Merge pull request #1385 from Mayflower/vagrantcloud_selfhosted

Vagrantcloud selfhosted
This commit is contained in:
Mitchell Hashimoto 2014-10-27 17:12:21 -07:00
commit 6a1744a1d2
4 changed files with 50 additions and 9 deletions

View File

@ -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

View File

@ -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

View File

@ -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
}

View File

@ -72,6 +72,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.