Merge branch 'master' into scrape_doc_to_builder_struct_config
This commit is contained in:
commit
2db109d55b
|
@ -5,6 +5,7 @@
|
|||
/builder/alicloud/ @chhaj5236
|
||||
/builder/azure/ @paulmey
|
||||
/builder/hyperv/ @taliesins
|
||||
/builder/jdcloud/ @XiaohanLiang @remrain
|
||||
/builder/linode/ @displague @ctreatma @stvnjacobs
|
||||
/builder/lxc/ @ChrisLundquist
|
||||
/builder/lxd/ @ChrisLundquist
|
||||
|
|
|
@ -149,7 +149,7 @@ func TestStepInstanceInfo_errorTimeout(t *testing.T) {
|
|||
|
||||
errCh := make(chan error, 1)
|
||||
go func() {
|
||||
<-time.After(10 * time.Millisecond)
|
||||
<-time.After(50 * time.Millisecond)
|
||||
errCh <- nil
|
||||
}()
|
||||
|
||||
|
|
|
@ -45,9 +45,10 @@ func (s *stepCreateImage) Run(ctx context.Context, state multistep.StateBag) mul
|
|||
// Block Storage service volume or regular Compute service local volume.
|
||||
ui.Say(fmt.Sprintf("Creating the image: %s", config.ImageName))
|
||||
var imageId string
|
||||
var blockStorageClient *gophercloud.ServiceClient
|
||||
if s.UseBlockStorageVolume {
|
||||
// We need the v3 block storage client.
|
||||
blockStorageClient, err := config.blockStorageV3Client()
|
||||
blockStorageClient, err = config.blockStorageV3Client()
|
||||
if err != nil {
|
||||
err = fmt.Errorf("Error initializing block storage client: %s", err)
|
||||
state.Put("error", err)
|
||||
|
@ -64,15 +65,6 @@ func (s *stepCreateImage) Run(ctx context.Context, state multistep.StateBag) mul
|
|||
ui.Error(err.Error())
|
||||
return multistep.ActionHalt
|
||||
}
|
||||
err = volumeactions.SetImageMetadata(blockStorageClient, volume, volumeactions.ImageMetadataOpts{
|
||||
Metadata: config.ImageMetadata,
|
||||
}).ExtractErr()
|
||||
if err != nil {
|
||||
err := fmt.Errorf("Error setting image metadata: %s", err)
|
||||
state.Put("error", err)
|
||||
ui.Error(err.Error())
|
||||
return multistep.ActionHalt
|
||||
}
|
||||
imageId = image.ImageID
|
||||
} else {
|
||||
imageId, err = servers.CreateImage(computeClient, server.ID, servers.CreateImageOpts{
|
||||
|
@ -100,6 +92,19 @@ func (s *stepCreateImage) Run(ctx context.Context, state multistep.StateBag) mul
|
|||
return multistep.ActionHalt
|
||||
}
|
||||
|
||||
volume := state.Get("volume_id").(string)
|
||||
if len(config.ImageMetadata) > 0 && s.UseBlockStorageVolume {
|
||||
err = volumeactions.SetImageMetadata(blockStorageClient, volume, volumeactions.ImageMetadataOpts{
|
||||
Metadata: config.ImageMetadata,
|
||||
}).ExtractErr()
|
||||
if err != nil {
|
||||
err := fmt.Errorf("Error setting image metadata: %s", err)
|
||||
state.Put("error", err)
|
||||
ui.Error(err.Error())
|
||||
return multistep.ActionHalt
|
||||
}
|
||||
}
|
||||
|
||||
return multistep.ActionContinue
|
||||
}
|
||||
|
||||
|
|
|
@ -5,8 +5,14 @@
|
|||
package vagrantcloud
|
||||
|
||||
import (
|
||||
"archive/tar"
|
||||
"compress/gzip"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
|
@ -19,6 +25,7 @@ import (
|
|||
|
||||
var builtins = map[string]string{
|
||||
"mitchellh.post-processor.vagrant": "vagrant",
|
||||
"packer.post-processor.artifice": "artifice",
|
||||
"vagrant": "vagrant",
|
||||
}
|
||||
|
||||
|
@ -89,7 +96,7 @@ func (p *PostProcessor) Configure(raws ...interface{}) error {
|
|||
// Accumulate any errors
|
||||
errs := new(packer.MultiError)
|
||||
|
||||
// required configuration
|
||||
// Required configuration
|
||||
templates := map[string]*string{
|
||||
"box_tag": &p.config.Tag,
|
||||
"version": &p.config.Version,
|
||||
|
@ -103,7 +110,7 @@ func (p *PostProcessor) Configure(raws ...interface{}) error {
|
|||
}
|
||||
}
|
||||
|
||||
// create the HTTP client
|
||||
// Create the HTTP client
|
||||
p.client, err = VagrantCloudClient{}.New(p.config.VagrantCloudUrl, p.config.AccessToken, p.insecureSkipTLSVerify)
|
||||
if err != nil {
|
||||
errs = packer.MultiErrorAppend(
|
||||
|
@ -126,20 +133,21 @@ func (p *PostProcessor) PostProcess(ctx context.Context, ui packer.Ui, artifact
|
|||
// We assume that there is only one .box file to upload
|
||||
if !strings.HasSuffix(artifact.Files()[0], ".box") {
|
||||
return nil, false, false, fmt.Errorf(
|
||||
"Unknown files in artifact, vagrant box is required: %s", artifact.Files())
|
||||
"Unknown files in artifact, Vagrant box with .box suffix is required as first artifact file: %s", artifact.Files())
|
||||
}
|
||||
|
||||
if p.warnAtlasToken {
|
||||
ui.Message("Warning: Using Vagrant Cloud token found in ATLAS_TOKEN. Please make sure it is correct, or set VAGRANT_CLOUD_TOKEN")
|
||||
}
|
||||
|
||||
// The name of the provider for vagrant cloud, and vagrant
|
||||
providerName := providerFromBuilderName(artifact.Id())
|
||||
// Determine the name of the provider for Vagrant Cloud, and Vagrant
|
||||
providerName, err := getProvider(artifact.Id(), artifact.Files()[0], builtins[artifact.BuilderId()])
|
||||
|
||||
p.config.ctx.Data = &boxDownloadUrlTemplate{
|
||||
ArtifactId: artifact.Id(),
|
||||
Provider: providerName,
|
||||
}
|
||||
|
||||
boxDownloadUrl, err := interpolate.Render(p.config.BoxDownloadUrl, &p.config.ctx)
|
||||
if err != nil {
|
||||
return nil, false, false, fmt.Errorf("Error processing box_download_url: %s", err)
|
||||
|
@ -187,8 +195,21 @@ func (p *PostProcessor) PostProcess(ctx context.Context, ui packer.Ui, artifact
|
|||
return NewArtifact(providerName, p.config.Tag), true, false, nil
|
||||
}
|
||||
|
||||
// converts a packer builder name to the corresponding vagrant
|
||||
// provider
|
||||
func getProvider(builderName, boxfile, builderId string) (providerName string, err error) {
|
||||
if builderId == "artifice" {
|
||||
// The artifice post processor cannot embed any data in the
|
||||
// supplied artifact so the provider information must be extracted
|
||||
// from the box file directly
|
||||
providerName, err = providerFromVagrantBox(boxfile)
|
||||
} else {
|
||||
// For the Vagrant builder and Vagrant post processor the provider can
|
||||
// be determined from information embedded in the artifact
|
||||
providerName = providerFromBuilderName(builderName)
|
||||
}
|
||||
return providerName, err
|
||||
}
|
||||
|
||||
// Converts a packer builder name to the corresponding vagrant provider
|
||||
func providerFromBuilderName(name string) string {
|
||||
switch name {
|
||||
case "aws":
|
||||
|
@ -207,3 +228,59 @@ func providerFromBuilderName(name string) string {
|
|||
return name
|
||||
}
|
||||
}
|
||||
|
||||
// Returns the Vagrant provider the box is intended for use with by
|
||||
// reading the metadata file packaged inside the box
|
||||
func providerFromVagrantBox(boxfile string) (providerName string, err error) {
|
||||
log.Println("Attempting to determine provider from metadata in box file. This may take some time...")
|
||||
|
||||
f, err := os.Open(boxfile)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("Error attempting to open box file: %s", err)
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
// Vagrant boxes are gzipped tar archives
|
||||
ar, err := gzip.NewReader(f)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("Error unzipping box archive: %s", err)
|
||||
}
|
||||
tr := tar.NewReader(ar)
|
||||
|
||||
// The metadata.json file in the tar archive contains a 'provider' key
|
||||
type metadata struct {
|
||||
ProviderName string `json:"provider"`
|
||||
}
|
||||
md := metadata{}
|
||||
|
||||
// Loop through the files in the archive and read the provider
|
||||
// information from the boxes metadata.json file
|
||||
for {
|
||||
hdr, err := tr.Next()
|
||||
if err == io.EOF {
|
||||
if md.ProviderName == "" {
|
||||
return "", fmt.Errorf("Error: Provider info was not found in box: %s", boxfile)
|
||||
}
|
||||
break
|
||||
}
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("Error reading header info from box tar archive: %s", err)
|
||||
}
|
||||
|
||||
if hdr.Name == "metadata.json" {
|
||||
contents, err := ioutil.ReadAll(tr)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("Error reading contents of metadata.json file from box file: %s", err)
|
||||
}
|
||||
err = json.Unmarshal(contents, &md)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("Error parsing metadata.json file: %s", err)
|
||||
}
|
||||
if md.ProviderName == "" {
|
||||
return "", fmt.Errorf("Error: Could not determine Vagrant provider from box metadata.json file")
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
return md.ProviderName, nil
|
||||
}
|
||||
|
|
|
@ -1,16 +1,26 @@
|
|||
package vagrantcloud
|
||||
|
||||
import (
|
||||
"archive/tar"
|
||||
"bytes"
|
||||
"compress/gzip"
|
||||
"context"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"os"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/packer/packer"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
type tarFiles []struct {
|
||||
Name, Body string
|
||||
}
|
||||
|
||||
func testGoodConfig() map[string]interface{} {
|
||||
return map[string]interface{}{
|
||||
"access_token": "foo",
|
||||
|
@ -137,6 +147,44 @@ func TestPostProcessor_Configure_Bad(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestPostProcessor_PostProcess_checkArtifactType(t *testing.T) {
|
||||
artifact := &packer.MockArtifact{
|
||||
BuilderIdValue: "invalid.builder",
|
||||
}
|
||||
|
||||
config := testGoodConfig()
|
||||
server := newSecureServer("foo", nil)
|
||||
defer server.Close()
|
||||
config["vagrant_cloud_url"] = server.URL
|
||||
var p PostProcessor
|
||||
|
||||
p.Configure(config)
|
||||
_, _, _, err := p.PostProcess(context.Background(), testUi(), artifact)
|
||||
if !strings.Contains(err.Error(), "Unknown artifact type") {
|
||||
t.Fatalf("Should error with message 'Unknown artifact type...' with BuilderId: %s", artifact.BuilderIdValue)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPostProcessor_PostProcess_checkArtifactFileIsBox(t *testing.T) {
|
||||
artifact := &packer.MockArtifact{
|
||||
BuilderIdValue: "mitchellh.post-processor.vagrant", // good
|
||||
FilesValue: []string{"invalid.boxfile"}, // should have .box extension
|
||||
}
|
||||
|
||||
config := testGoodConfig()
|
||||
server := newSecureServer("foo", nil)
|
||||
defer server.Close()
|
||||
config["vagrant_cloud_url"] = server.URL
|
||||
var p PostProcessor
|
||||
|
||||
p.Configure(config)
|
||||
_, _, _, err := p.PostProcess(context.Background(), testUi(), artifact)
|
||||
if !strings.Contains(err.Error(), "Unknown files in artifact") {
|
||||
t.Fatalf("Should error with message 'Unknown files in artifact...' with artifact file: %s",
|
||||
artifact.FilesValue[0])
|
||||
}
|
||||
}
|
||||
|
||||
func testUi() *packer.BasicUi {
|
||||
return &packer.BasicUi{
|
||||
Reader: new(bytes.Buffer),
|
||||
|
@ -157,3 +205,258 @@ func TestProviderFromBuilderName(t *testing.T) {
|
|||
t.Fatal("should convert provider")
|
||||
}
|
||||
}
|
||||
|
||||
func TestProviderFromVagrantBox_missing_box(t *testing.T) {
|
||||
// Bad: Box does not exist
|
||||
boxfile := "i_dont_exist.box"
|
||||
_, err := providerFromVagrantBox(boxfile)
|
||||
if err == nil {
|
||||
t.Fatal("Should have error as box file does not exist")
|
||||
}
|
||||
t.Logf("%s", err)
|
||||
}
|
||||
|
||||
func TestProviderFromVagrantBox_empty_box(t *testing.T) {
|
||||
// Bad: Empty box file
|
||||
boxfile, err := newBoxFile()
|
||||
if err != nil {
|
||||
t.Fatalf("%s", err)
|
||||
}
|
||||
defer os.Remove(boxfile.Name())
|
||||
|
||||
_, err = providerFromVagrantBox(boxfile.Name())
|
||||
if err == nil {
|
||||
t.Fatal("Should have error as box file is empty")
|
||||
}
|
||||
t.Logf("%s", err)
|
||||
}
|
||||
|
||||
func TestProviderFromVagrantBox_gzip_only_box(t *testing.T) {
|
||||
boxfile, err := newBoxFile()
|
||||
if err != nil {
|
||||
t.Fatalf("%s", err)
|
||||
}
|
||||
defer os.Remove(boxfile.Name())
|
||||
|
||||
// Bad: Box is just a plain gzip file
|
||||
aw := gzip.NewWriter(boxfile)
|
||||
_, err = aw.Write([]byte("foo content"))
|
||||
if err != nil {
|
||||
t.Fatal("Error zipping test box file")
|
||||
}
|
||||
aw.Close() // Flush the gzipped contents to file
|
||||
|
||||
_, err = providerFromVagrantBox(boxfile.Name())
|
||||
if err == nil {
|
||||
t.Fatalf("Should have error as box file is a plain gzip file: %s", err)
|
||||
}
|
||||
t.Logf("%s", err)
|
||||
}
|
||||
|
||||
func TestProviderFromVagrantBox_no_files_in_archive(t *testing.T) {
|
||||
// Bad: Box contains no files
|
||||
boxfile, err := createBox(tarFiles{})
|
||||
if err != nil {
|
||||
t.Fatalf("Error creating test box: %s", err)
|
||||
}
|
||||
defer os.Remove(boxfile.Name())
|
||||
|
||||
_, err = providerFromVagrantBox(boxfile.Name())
|
||||
if err == nil {
|
||||
t.Fatalf("Should have error as box file has no contents")
|
||||
}
|
||||
t.Logf("%s", err)
|
||||
}
|
||||
|
||||
func TestProviderFromVagrantBox_no_metadata(t *testing.T) {
|
||||
// Bad: Box contains no metadata/metadata.json file
|
||||
files := tarFiles{
|
||||
{"foo.txt", "This is a foo file"},
|
||||
{"bar.txt", "This is a bar file"},
|
||||
}
|
||||
boxfile, err := createBox(files)
|
||||
if err != nil {
|
||||
t.Fatalf("Error creating test box: %s", err)
|
||||
}
|
||||
defer os.Remove(boxfile.Name())
|
||||
|
||||
_, err = providerFromVagrantBox(boxfile.Name())
|
||||
if err == nil {
|
||||
t.Fatalf("Should have error as box file does not include metadata.json file")
|
||||
}
|
||||
t.Logf("%s", err)
|
||||
}
|
||||
|
||||
func TestProviderFromVagrantBox_metadata_empty(t *testing.T) {
|
||||
// Bad: Create a box with an empty metadata.json file
|
||||
files := tarFiles{
|
||||
{"foo.txt", "This is a foo file"},
|
||||
{"bar.txt", "This is a bar file"},
|
||||
{"metadata.json", ""},
|
||||
}
|
||||
boxfile, err := createBox(files)
|
||||
if err != nil {
|
||||
t.Fatalf("Error creating test box: %s", err)
|
||||
}
|
||||
defer os.Remove(boxfile.Name())
|
||||
|
||||
_, err = providerFromVagrantBox(boxfile.Name())
|
||||
if err == nil {
|
||||
t.Fatalf("Should have error as box files metadata.json file is empty")
|
||||
}
|
||||
t.Logf("%s", err)
|
||||
}
|
||||
|
||||
func TestProviderFromVagrantBox_metadata_bad_json(t *testing.T) {
|
||||
// Bad: Create a box with bad JSON in the metadata.json file
|
||||
files := tarFiles{
|
||||
{"foo.txt", "This is a foo file"},
|
||||
{"bar.txt", "This is a bar file"},
|
||||
{"metadata.json", "{provider: badjson}"},
|
||||
}
|
||||
boxfile, err := createBox(files)
|
||||
if err != nil {
|
||||
t.Fatalf("Error creating test box: %s", err)
|
||||
}
|
||||
defer os.Remove(boxfile.Name())
|
||||
|
||||
_, err = providerFromVagrantBox(boxfile.Name())
|
||||
if err == nil {
|
||||
t.Fatalf("Should have error as box files metadata.json file contains badly formatted JSON")
|
||||
}
|
||||
t.Logf("%s", err)
|
||||
}
|
||||
|
||||
func TestProviderFromVagrantBox_metadata_no_provider_key(t *testing.T) {
|
||||
// Bad: Create a box with no 'provider' key in the metadata.json file
|
||||
files := tarFiles{
|
||||
{"foo.txt", "This is a foo file"},
|
||||
{"bar.txt", "This is a bar file"},
|
||||
{"metadata.json", `{"cows":"moo"}`},
|
||||
}
|
||||
boxfile, err := createBox(files)
|
||||
if err != nil {
|
||||
t.Fatalf("Error creating test box: %s", err)
|
||||
}
|
||||
defer os.Remove(boxfile.Name())
|
||||
|
||||
_, err = providerFromVagrantBox(boxfile.Name())
|
||||
if err == nil {
|
||||
t.Fatalf("Should have error as provider key/value pair is missing from boxes metadata.json file")
|
||||
}
|
||||
t.Logf("%s", err)
|
||||
}
|
||||
|
||||
func TestProviderFromVagrantBox_metadata_provider_value_empty(t *testing.T) {
|
||||
// Bad: The boxes metadata.json file 'provider' key has an empty value
|
||||
files := tarFiles{
|
||||
{"foo.txt", "This is a foo file"},
|
||||
{"bar.txt", "This is a bar file"},
|
||||
{"metadata.json", `{"provider":""}`},
|
||||
}
|
||||
boxfile, err := createBox(files)
|
||||
if err != nil {
|
||||
t.Fatalf("Error creating test box: %s", err)
|
||||
}
|
||||
defer os.Remove(boxfile.Name())
|
||||
|
||||
_, err = providerFromVagrantBox(boxfile.Name())
|
||||
if err == nil {
|
||||
t.Fatalf("Should have error as value associated with 'provider' key in boxes metadata.json file is empty")
|
||||
}
|
||||
t.Logf("%s", err)
|
||||
}
|
||||
|
||||
func TestProviderFromVagrantBox_metadata_ok(t *testing.T) {
|
||||
// Good: The boxes metadata.json file has the 'provider' key/value pair
|
||||
expectedProvider := "virtualbox"
|
||||
files := tarFiles{
|
||||
{"foo.txt", "This is a foo file"},
|
||||
{"bar.txt", "This is a bar file"},
|
||||
{"metadata.json", `{"provider":"` + expectedProvider + `"}`},
|
||||
}
|
||||
boxfile, err := createBox(files)
|
||||
if err != nil {
|
||||
t.Fatalf("Error creating test box: %s", err)
|
||||
}
|
||||
defer os.Remove(boxfile.Name())
|
||||
|
||||
provider, err := providerFromVagrantBox(boxfile.Name())
|
||||
assert.Equal(t, expectedProvider, provider, "Error: Expected provider: '%s'. Got '%s'", expectedProvider, provider)
|
||||
t.Logf("Expected provider '%s'. Got provider '%s'", expectedProvider, provider)
|
||||
}
|
||||
|
||||
func TestGetProvider_artifice(t *testing.T) {
|
||||
expectedProvider := "virtualbox"
|
||||
files := tarFiles{
|
||||
{"foo.txt", "This is a foo file"},
|
||||
{"bar.txt", "This is a bar file"},
|
||||
{"metadata.json", `{"provider":"` + expectedProvider + `"}`},
|
||||
}
|
||||
boxfile, err := createBox(files)
|
||||
if err != nil {
|
||||
t.Fatalf("Error creating test box: %s", err)
|
||||
}
|
||||
defer os.Remove(boxfile.Name())
|
||||
|
||||
provider, err := getProvider("", boxfile.Name(), "artifice")
|
||||
assert.Equal(t, expectedProvider, provider, "Error: Expected provider: '%s'. Got '%s'", expectedProvider, provider)
|
||||
t.Logf("Expected provider '%s'. Got provider '%s'", expectedProvider, provider)
|
||||
}
|
||||
|
||||
func TestGetProvider_other(t *testing.T) {
|
||||
expectedProvider := "virtualbox"
|
||||
|
||||
provider, _ := getProvider(expectedProvider, "foo.box", "other")
|
||||
assert.Equal(t, expectedProvider, provider, "Error: Expected provider: '%s'. Got '%s'", expectedProvider, provider)
|
||||
t.Logf("Expected provider '%s'. Got provider '%s'", expectedProvider, provider)
|
||||
}
|
||||
|
||||
func newBoxFile() (boxfile *os.File, err error) {
|
||||
boxfile, err = ioutil.TempFile(os.TempDir(), "test*.box")
|
||||
if err != nil {
|
||||
return boxfile, fmt.Errorf("Error creating test box file: %s", err)
|
||||
}
|
||||
return boxfile, nil
|
||||
}
|
||||
|
||||
func createBox(files tarFiles) (boxfile *os.File, err error) {
|
||||
boxfile, err = newBoxFile()
|
||||
if err != nil {
|
||||
return boxfile, err
|
||||
}
|
||||
|
||||
// Box files are gzipped tar archives
|
||||
aw := gzip.NewWriter(boxfile)
|
||||
tw := tar.NewWriter(aw)
|
||||
|
||||
// Add each file to the box
|
||||
for _, file := range files {
|
||||
// Create and write the tar file header
|
||||
hdr := &tar.Header{
|
||||
Name: file.Name,
|
||||
Mode: 0644,
|
||||
Size: int64(len(file.Body)),
|
||||
}
|
||||
err = tw.WriteHeader(hdr)
|
||||
if err != nil {
|
||||
return boxfile, fmt.Errorf("Error writing box tar file header: %s", err)
|
||||
}
|
||||
// Write the file contents
|
||||
_, err = tw.Write([]byte(file.Body))
|
||||
if err != nil {
|
||||
return boxfile, fmt.Errorf("Error writing box tar file contents: %s", err)
|
||||
}
|
||||
}
|
||||
// Flush and close each writer
|
||||
err = tw.Close()
|
||||
if err != nil {
|
||||
return boxfile, fmt.Errorf("Error flushing tar file contents: %s", err)
|
||||
}
|
||||
err = aw.Close()
|
||||
if err != nil {
|
||||
return boxfile, fmt.Errorf("Error flushing gzip file contents: %s", err)
|
||||
}
|
||||
|
||||
return boxfile, nil
|
||||
}
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
source "https://rubygems.org"
|
||||
|
||||
gem "middleman-hashicorp", "0.3.39"
|
||||
gem "middleman-hashicorp", "0.3.41"
|
||||
|
|
|
@ -6,7 +6,7 @@ GEM
|
|||
minitest (~> 5.1)
|
||||
thread_safe (~> 0.3, >= 0.3.4)
|
||||
tzinfo (~> 1.1)
|
||||
autoprefixer-rails (9.5.1)
|
||||
autoprefixer-rails (9.6.1)
|
||||
execjs
|
||||
bootstrap-sass (3.4.1)
|
||||
autoprefixer-rails (>= 5.2.1)
|
||||
|
@ -41,8 +41,8 @@ GEM
|
|||
erubis (2.7.0)
|
||||
eventmachine (1.2.7)
|
||||
execjs (2.7.0)
|
||||
ffi (1.10.0)
|
||||
haml (5.0.4)
|
||||
ffi (1.11.1)
|
||||
haml (5.1.2)
|
||||
temple (>= 0.8.0)
|
||||
tilt
|
||||
hike (1.2.3)
|
||||
|
@ -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.39)
|
||||
middleman-hashicorp (0.3.41)
|
||||
bootstrap-sass (~> 3.3)
|
||||
builder (~> 3.2)
|
||||
middleman (~> 3.4)
|
||||
|
@ -95,16 +95,16 @@ GEM
|
|||
sprockets (~> 2.12.1)
|
||||
sprockets-helpers (~> 1.1.0)
|
||||
sprockets-sass (~> 1.3.0)
|
||||
middleman-syntax (3.0.0)
|
||||
middleman-syntax (3.2.0)
|
||||
middleman-core (>= 3.2)
|
||||
rouge (~> 2.0)
|
||||
rouge (~> 3.2)
|
||||
mime-types (3.2.2)
|
||||
mime-types-data (~> 3.2015)
|
||||
mime-types-data (3.2019.0331)
|
||||
mini_portile2 (2.4.0)
|
||||
minitest (5.11.3)
|
||||
multi_json (1.13.1)
|
||||
nokogiri (1.10.2)
|
||||
nokogiri (1.10.4)
|
||||
mini_portile2 (~> 2.4.0)
|
||||
padrino-helpers (0.12.9)
|
||||
i18n (~> 0.6, >= 0.6.7)
|
||||
|
@ -117,16 +117,14 @@ GEM
|
|||
rack
|
||||
rack-test (1.1.0)
|
||||
rack (>= 1.0, < 3)
|
||||
rake (12.3.2)
|
||||
rb-fsevent (0.10.3)
|
||||
rb-inotify (0.10.0)
|
||||
ffi (~> 1.0)
|
||||
redcarpet (3.4.0)
|
||||
rouge (2.2.1)
|
||||
redcarpet (3.5.0)
|
||||
rouge (3.9.0)
|
||||
sass (3.4.25)
|
||||
sassc (2.0.1)
|
||||
sassc (2.1.0)
|
||||
ffi (~> 1.9)
|
||||
rake
|
||||
sprockets (2.12.5)
|
||||
hike (~> 1.2)
|
||||
multi_json (~> 1.0)
|
||||
|
@ -157,7 +155,7 @@ PLATFORMS
|
|||
ruby
|
||||
|
||||
DEPENDENCIES
|
||||
middleman-hashicorp (= 0.3.39)
|
||||
middleman-hashicorp (= 0.3.41)
|
||||
|
||||
BUNDLED WITH
|
||||
1.17.1
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
---
|
||||
description: |
|
||||
The Packer Vagrant Cloud post-processor receives a Vagrant box from the
|
||||
`vagrant` post-processor or vagrant builder and pushes it to Vagrant Cloud.
|
||||
Vagrant Cloud hosts and serves boxes to Vagrant, allowing you to version and
|
||||
distribute boxes to an organization in a simple way.
|
||||
The Vagrant Cloud post-processor enables the upload of Vagrant boxes to
|
||||
Vagrant Cloud.
|
||||
layout: docs
|
||||
page_title: 'Vagrant Cloud - Post-Processors'
|
||||
sidebar_current: 'docs-post-processors-vagrant-cloud'
|
||||
|
@ -13,12 +11,16 @@ sidebar_current: 'docs-post-processors-vagrant-cloud'
|
|||
|
||||
Type: `vagrant-cloud`
|
||||
|
||||
The Packer Vagrant Cloud post-processor receives a Vagrant box from the
|
||||
`vagrant` post-processor or vagrant builder and pushes it to Vagrant Cloud.
|
||||
[Vagrant Cloud](https://app.vagrantup.com/boxes/search) hosts and serves boxes
|
||||
to Vagrant, allowing you to version and distribute boxes to an organization in a
|
||||
simple way.
|
||||
|
||||
The Vagrant Cloud post-processor enables the upload of Vagrant boxes to Vagrant
|
||||
Cloud. Currently, the Vagrant Cloud post-processor will accept and upload boxes
|
||||
supplied to it from the [Vagrant](/docs/post-processors/vagrant.html) or
|
||||
[Artifice](/docs/post-processors/artifice.html) post-processors and the
|
||||
[Vagrant](/docs/builders/vagrant.html) builder.
|
||||
|
||||
You'll need to be familiar with Vagrant Cloud, have an upgraded account to
|
||||
enable box hosting, and be distributing your box via the [shorthand
|
||||
name](https://docs.vagrantup.com/v2/cli/box.html) configuration.
|
||||
|
@ -94,12 +96,18 @@ on Vagrant Cloud, as well as authentication and version information.
|
|||
- `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
|
||||
## Use with the Vagrant Post-Processor
|
||||
|
||||
You'll need to use the Vagrant post-processor before using this post-processor.
|
||||
An example configuration is below. Note the use of a doubly-nested array, which
|
||||
ensures that the Vagrant Cloud post-processor is run after the Vagrant
|
||||
post-processor.
|
||||
An example configuration is shown below. Note the use of the nested array that
|
||||
wraps both the Vagrant and Vagrant Cloud post-processors within the
|
||||
post-processor section. Chaining the post-processors together in this way tells
|
||||
Packer that the artifact produced by the Vagrant post-processor should be passed
|
||||
directly to the Vagrant Cloud Post-Processor. It also sets the order in which
|
||||
the post-processors should run.
|
||||
|
||||
Failure to chain the post-processors together in this way will result in the
|
||||
wrong artifact being supplied to the Vagrant Cloud post-processor. This will
|
||||
likely cause the Vagrant Cloud post-processor to error and fail.
|
||||
|
||||
``` json
|
||||
{
|
||||
|
@ -108,6 +116,10 @@ post-processor.
|
|||
"version": "1.0.{{timestamp}}"
|
||||
},
|
||||
"post-processors": [
|
||||
{
|
||||
"type": "shell-local",
|
||||
"inline": ["echo Doing stuff..."]
|
||||
},
|
||||
[
|
||||
{
|
||||
"type": "vagrant",
|
||||
|
@ -125,3 +137,56 @@ post-processor.
|
|||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Use with the Artifice Post-Processor
|
||||
|
||||
An example configuration is shown below. Note the use of the nested array that
|
||||
wraps both the Artifice and Vagrant Cloud post-processors within the
|
||||
post-processor section. Chaining the post-processors together in this way tells
|
||||
Packer that the artifact produced by the Artifice post-processor should be
|
||||
passed directly to the Vagrant Cloud Post-Processor. It also sets the order in
|
||||
which the post-processors should run.
|
||||
|
||||
Failure to chain the post-processors together in this way will result in the
|
||||
wrong artifact being supplied to the Vagrant Cloud post-processor. This will
|
||||
likely cause the Vagrant Cloud post-processor to error and fail.
|
||||
|
||||
Note that the Vagrant box specified in the Artifice post-processor `files` array
|
||||
must end in the `.box` extension. It must also be the first file in the array.
|
||||
Additional files bundled by the Artifice post-processor will be ignored.
|
||||
|
||||
```json
|
||||
{
|
||||
"variables": {
|
||||
"cloud_token": "{{ env `VAGRANT_CLOUD_TOKEN` }}",
|
||||
},
|
||||
|
||||
"builders": [
|
||||
{
|
||||
"type": "null",
|
||||
"communicator": "none"
|
||||
}
|
||||
],
|
||||
|
||||
"post-processors": [
|
||||
{
|
||||
"type": "shell-local",
|
||||
"inline": ["echo Doing stuff..."]
|
||||
},
|
||||
[
|
||||
{
|
||||
"type": "artifice",
|
||||
"files": [
|
||||
"./path/to/my.box"
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "vagrant-cloud",
|
||||
"box_tag": "myorganisation/mybox",
|
||||
"access_token": "{{user `cloud_token`}}",
|
||||
"version": "0.1.0",
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
```
|
||||
|
|
|
@ -104,8 +104,9 @@ Optional Parameters:
|
|||
- `galaxy_command` (string) - The command to invoke ansible-galaxy. By
|
||||
default, this is `ansible-galaxy`.
|
||||
|
||||
- `galaxy_force_install` (string) - Force overwriting an existing role.
|
||||
Adds `--force` option to `ansible-galaxy` command. By default, this is empty.
|
||||
- `galaxy_force_install` (bool) - Force overwriting an existing role.
|
||||
Adds `--force` option to `ansible-galaxy` command. By default, this is
|
||||
`false`.
|
||||
|
||||
- `groups` (array of strings) - The groups into which the Ansible host should
|
||||
be placed. When unspecified, the host is not associated with any groups.
|
||||
|
|
Loading…
Reference in New Issue