From 7816fc0bf92f66f1797c9952c71630ad5c877b73 Mon Sep 17 00:00:00 2001 From: Tristan Helmich Date: Fri, 1 Aug 2014 19:31:10 +0200 Subject: [PATCH 1/2] vagrantcloud post-processor selfhosted box feature --- .../vagrant-cloud/post-processor.go | 45 +++++++++++++++---- .../vagrant-cloud/step_create_provider.go | 6 +++ .../vagrant-cloud/step_release_version.go | 5 +++ 3 files changed, 47 insertions(+), 9 deletions(-) diff --git a/post-processor/vagrant-cloud/post-processor.go b/post-processor/vagrant-cloud/post-processor.go index 8a7f53ebc..f6a5b2dfe 100644 --- a/post-processor/vagrant-cloud/post-processor.go +++ b/post-processor/vagrant-cloud/post-processor.go @@ -1,6 +1,7 @@ // vagrant_cloud implements the packer.PostProcessor interface and adds a // post-processor that uploads artifacts from the vagrant post-processor -// to Vagrant Cloud (vagrantcloud.com) +// to Vagrant Cloud (vagrantcloud.com) or manages self hosted boxes on the +// Vagrant Cloud package vagrantcloud import ( @@ -25,9 +26,16 @@ type Config struct { AccessToken string `mapstructure:"access_token"` VagrantCloudUrl string `mapstructure:"vagrant_cloud_url"` + BoxDownloadUrl string `mapstructure:"box_download_url"` + tpl *packer.ConfigTemplate } +type boxDownloadUrlTemplate struct { + ArtifactId string + Provider string +} + type PostProcessor struct { config Config client *VagrantCloudClient @@ -103,6 +111,14 @@ func (p *PostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact) (pac // The name of the provider for vagrant cloud, and vagrant providerName := providerFromBuilderName(artifact.Id()) + boxDownloadUrl, err := p.config.tpl.Process(p.config.BoxDownloadUrl, &boxDownloadUrlTemplate { + ArtifactId: artifact.Id(), + Provider: providerName, + }) + if err != nil { + return nil, false, fmt.Errorf("Error processing box_download_url: %s", err) + } + // Set up the state state := new(multistep.BasicStateBag) state.Put("config", p.config) @@ -111,16 +127,27 @@ func (p *PostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact) (pac state.Put("artifactFilePath", artifact.Files()[0]) state.Put("ui", ui) state.Put("providerName", providerName) + state.Put("boxDownloadUrl", boxDownloadUrl) // Build the steps - steps := []multistep.Step{ - new(stepVerifyBox), - new(stepCreateVersion), - new(stepCreateProvider), - new(stepPrepareUpload), - new(stepUpload), - new(stepVerifyUpload), - new(stepReleaseVersion), + steps := []multistep.Step{} + if p.config.BoxDownloadUrl == "" { + steps = []multistep.Step{ + new(stepVerifyBox), + new(stepCreateVersion), + new(stepCreateProvider), + new(stepPrepareUpload), + new(stepUpload), + new(stepVerifyUpload), + new(stepReleaseVersion), + } + } else { + steps = []multistep.Step{ + new(stepVerifyBox), + new(stepCreateVersion), + new(stepCreateProvider), + new(stepReleaseVersion), + } } // Run the steps diff --git a/post-processor/vagrant-cloud/step_create_provider.go b/post-processor/vagrant-cloud/step_create_provider.go index 887932c4f..c2d6772bd 100644 --- a/post-processor/vagrant-cloud/step_create_provider.go +++ b/post-processor/vagrant-cloud/step_create_provider.go @@ -8,6 +8,7 @@ import ( type Provider struct { Name string `json:"name"` + Url string `json:"url,omitempty"` HostedToken string `json:"hosted_token,omitempty"` UploadUrl string `json:"upload_url,omitempty"` } @@ -22,11 +23,16 @@ func (s *stepCreateProvider) Run(state multistep.StateBag) multistep.StepAction box := state.Get("box").(*Box) version := state.Get("version").(*Version) providerName := state.Get("providerName").(string) + downloadUrl := state.Get("boxDownloadUrl").(string) path := fmt.Sprintf("box/%s/version/%v/providers", box.Tag, version.Number) provider := &Provider{Name: providerName} + if downloadUrl != "" { + provider.Url = downloadUrl + } + // Wrap the provider in a provider object for the API wrapper := make(map[string]interface{}) wrapper["provider"] = provider diff --git a/post-processor/vagrant-cloud/step_release_version.go b/post-processor/vagrant-cloud/step_release_version.go index 43512bdca..d8809f9ca 100644 --- a/post-processor/vagrant-cloud/step_release_version.go +++ b/post-processor/vagrant-cloud/step_release_version.go @@ -2,6 +2,7 @@ package vagrantcloud import ( "fmt" + "strings" "github.com/mitchellh/multistep" "github.com/mitchellh/packer/packer" ) @@ -30,6 +31,10 @@ func (s *stepReleaseVersion) Run(state multistep.StateBag) multistep.StepAction if err != nil || (resp.StatusCode != 200) { cloudErrors := &VagrantCloudErrors{} err = decodeBody(resp, cloudErrors) + if strings.Contains(cloudErrors.FormatErrors(), "already been released") { + ui.Message("Not releasing version, already released") + return multistep.ActionContinue + } state.Put("error", fmt.Errorf("Error releasing version: %s", cloudErrors.FormatErrors())) return multistep.ActionHalt } From 849458f29dc4700cc5b943e8e83689cbb0296eab Mon Sep 17 00:00:00 2001 From: Tristan Helmich Date: Sat, 2 Aug 2014 15:14:29 +0200 Subject: [PATCH 2/2] Update documentation: New box_download_url setting --- .../source/docs/post-processors/vagrant-cloud.html.markdown | 3 +++ 1 file changed, 3 insertions(+) diff --git a/website/source/docs/post-processors/vagrant-cloud.html.markdown b/website/source/docs/post-processors/vagrant-cloud.html.markdown index 273b0cf32..cc1bccaf9 100644 --- a/website/source/docs/post-processors/vagrant-cloud.html.markdown +++ b/website/source/docs/post-processors/vagrant-cloud.html.markdown @@ -70,6 +70,9 @@ to `https://vagrantcloud.com/api/v1` * `version_description` (string) - Optionally markdown text used as a full-length and in-depth description of the version, typically for denoting changes introduced +* `box_download_url` (string) - Optional URL for a self-hosted box. If this is set +the box will not be uploaded to the Vagrant Cloud. + ## Use with Vagrant Post-Processor You'll need to use the Vagrant post-processor before using this post-processor.