Commit 7816fc0b authored by Tristan Helmich's avatar Tristan Helmich

vagrantcloud post-processor selfhosted box feature

parent e39f555f
// 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
......
......@@ -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
......
......@@ -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
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment