packer: Build can return multiple artifacts
This commit is contained in:
parent
dab3eb5ece
commit
1015df8fa8
|
@ -163,7 +163,7 @@ func (c Command) Run(env packer.Environment, args []string) int {
|
||||||
// Run all the builds in parallel and wait for them to complete
|
// Run all the builds in parallel and wait for them to complete
|
||||||
var interruptWg, wg sync.WaitGroup
|
var interruptWg, wg sync.WaitGroup
|
||||||
interrupted := false
|
interrupted := false
|
||||||
artifacts := make(map[string]packer.Artifact)
|
artifacts := make(map[string][]packer.Artifact)
|
||||||
errors := make(map[string]error)
|
errors := make(map[string]error)
|
||||||
for _, b := range builds {
|
for _, b := range builds {
|
||||||
// Increment the waitgroup so we wait for this item to finish properly
|
// Increment the waitgroup so we wait for this item to finish properly
|
||||||
|
@ -191,14 +191,14 @@ func (c Command) Run(env packer.Environment, args []string) int {
|
||||||
name := b.Name()
|
name := b.Name()
|
||||||
log.Printf("Starting build run: %s", name)
|
log.Printf("Starting build run: %s", name)
|
||||||
ui := buildUis[name]
|
ui := buildUis[name]
|
||||||
artifact, err := b.Run(ui, env.Cache())
|
runArtifacts, err := b.Run(ui, env.Cache())
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ui.Error(fmt.Sprintf("Build errored: %s", err))
|
ui.Error(fmt.Sprintf("Build errored: %s", err))
|
||||||
errors[name] = err
|
errors[name] = err
|
||||||
} else {
|
} else {
|
||||||
ui.Say("Build finished.")
|
ui.Say("Build finished.")
|
||||||
artifacts[name] = artifact
|
artifacts[name] = runArtifacts
|
||||||
}
|
}
|
||||||
}(b)
|
}(b)
|
||||||
|
|
||||||
|
@ -235,17 +235,19 @@ func (c Command) Run(env packer.Environment, args []string) int {
|
||||||
|
|
||||||
if len(artifacts) > 0 {
|
if len(artifacts) > 0 {
|
||||||
env.Ui().Say("\n==> Builds finished. The artifacts of successful builds are:")
|
env.Ui().Say("\n==> Builds finished. The artifacts of successful builds are:")
|
||||||
for name, artifact := range artifacts {
|
for name, buildArtifacts := range artifacts {
|
||||||
var message bytes.Buffer
|
for _, artifact := range buildArtifacts {
|
||||||
fmt.Fprintf(&message, "--> %s: ", name)
|
var message bytes.Buffer
|
||||||
|
fmt.Fprintf(&message, "--> %s: ", name)
|
||||||
|
|
||||||
if artifact != nil {
|
if artifact != nil {
|
||||||
fmt.Fprintf(&message, artifact.String())
|
fmt.Fprintf(&message, artifact.String())
|
||||||
} else {
|
} else {
|
||||||
fmt.Print("<nothing>")
|
fmt.Print("<nothing>")
|
||||||
|
}
|
||||||
|
|
||||||
|
env.Ui().Say(message.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
env.Ui().Say(message.String())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,7 @@ type Build interface {
|
||||||
|
|
||||||
// Run runs the actual builder, returning an artifact implementation
|
// Run runs the actual builder, returning an artifact implementation
|
||||||
// of what is built. If anything goes wrong, an error is returned.
|
// of what is built. If anything goes wrong, an error is returned.
|
||||||
Run(Ui, Cache) (Artifact, error)
|
Run(Ui, Cache) ([]Artifact, error)
|
||||||
|
|
||||||
// Cancel will cancel a running build. This will block until the build
|
// Cancel will cancel a running build. This will block until the build
|
||||||
// is actually completely cancelled.
|
// is actually completely cancelled.
|
||||||
|
@ -113,7 +113,7 @@ func (b *coreBuild) Prepare() (err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Runs the actual build. Prepare must be called prior to running this.
|
// Runs the actual build. Prepare must be called prior to running this.
|
||||||
func (b *coreBuild) Run(ui Ui, cache Cache) (Artifact, error) {
|
func (b *coreBuild) Run(ui Ui, cache Cache) ([]Artifact, error) {
|
||||||
if !b.prepareCalled {
|
if !b.prepareCalled {
|
||||||
panic("Prepare must be called first")
|
panic("Prepare must be called first")
|
||||||
}
|
}
|
||||||
|
@ -140,7 +140,14 @@ func (b *coreBuild) Run(ui Ui, cache Cache) (Artifact, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
hook := &DispatchHook{hooks}
|
hook := &DispatchHook{hooks}
|
||||||
return b.builder.Run(ui, hook, cache)
|
artifacts := make([]Artifact, 0, 1)
|
||||||
|
|
||||||
|
artifact, err := b.builder.Run(ui, hook, cache)
|
||||||
|
if artifact != nil {
|
||||||
|
artifacts = append(artifacts, artifact)
|
||||||
|
}
|
||||||
|
|
||||||
|
return artifacts, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *coreBuild) SetDebug(val bool) {
|
func (b *coreBuild) SetDebug(val bool) {
|
||||||
|
|
|
@ -38,24 +38,29 @@ func (b *build) Prepare() (err error) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *build) Run(ui packer.Ui, cache packer.Cache) (packer.Artifact, error) {
|
func (b *build) Run(ui packer.Ui, cache packer.Cache) ([]packer.Artifact, error) {
|
||||||
// Create and start the server for the UI
|
// Create and start the server for the UI
|
||||||
server := rpc.NewServer()
|
server := rpc.NewServer()
|
||||||
RegisterCache(server, cache)
|
RegisterCache(server, cache)
|
||||||
RegisterUi(server, ui)
|
RegisterUi(server, ui)
|
||||||
args := &BuildRunArgs{serveSingleConn(server)}
|
args := &BuildRunArgs{serveSingleConn(server)}
|
||||||
|
|
||||||
var reply string
|
var result []string
|
||||||
if err := b.client.Call("Build.Run", args, &reply); err != nil {
|
if err := b.client.Call("Build.Run", args, &result); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
client, err := rpc.Dial("tcp", reply)
|
artifacts := make([]packer.Artifact, len(result))
|
||||||
if err != nil {
|
for i, addr := range result {
|
||||||
return nil, err
|
client, err := rpc.Dial("tcp", addr)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
artifacts[i] = Artifact(client)
|
||||||
}
|
}
|
||||||
|
|
||||||
return Artifact(client), nil
|
return artifacts, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *build) SetDebug(val bool) {
|
func (b *build) SetDebug(val bool) {
|
||||||
|
@ -80,22 +85,24 @@ func (b *BuildServer) Prepare(args interface{}, reply *error) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *BuildServer) Run(args *BuildRunArgs, reply *string) error {
|
func (b *BuildServer) Run(args *BuildRunArgs, reply *[]string) error {
|
||||||
client, err := rpc.Dial("tcp", args.UiRPCAddress)
|
client, err := rpc.Dial("tcp", args.UiRPCAddress)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
artifact, err := b.build.Run(&Ui{client}, Cache(client))
|
artifacts, err := b.build.Run(&Ui{client}, Cache(client))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return NewBasicError(err)
|
return NewBasicError(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wrap the artifact
|
*reply = make([]string, len(artifacts))
|
||||||
server := rpc.NewServer()
|
for i, artifact := range artifacts {
|
||||||
RegisterArtifact(server, artifact)
|
server := rpc.NewServer()
|
||||||
|
RegisterArtifact(server, artifact)
|
||||||
|
(*reply)[i] = serveSingleConn(server)
|
||||||
|
}
|
||||||
|
|
||||||
*reply = serveSingleConn(server)
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,7 @@ func (b *testBuild) Prepare() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *testBuild) Run(ui packer.Ui, cache packer.Cache) (packer.Artifact, error) {
|
func (b *testBuild) Run(ui packer.Ui, cache packer.Cache) ([]packer.Artifact, error) {
|
||||||
b.runCalled = true
|
b.runCalled = true
|
||||||
b.runCache = cache
|
b.runCache = cache
|
||||||
b.runUi = ui
|
b.runUi = ui
|
||||||
|
@ -40,7 +40,7 @@ func (b *testBuild) Run(ui packer.Ui, cache packer.Cache) (packer.Artifact, erro
|
||||||
if b.errRunResult {
|
if b.errRunResult {
|
||||||
return nil, errors.New("foo")
|
return nil, errors.New("foo")
|
||||||
} else {
|
} else {
|
||||||
return testBuildArtifact, nil
|
return []packer.Artifact{testBuildArtifact}, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,9 +79,11 @@ func TestBuildRPC(t *testing.T) {
|
||||||
// Test Run
|
// Test Run
|
||||||
cache := new(testCache)
|
cache := new(testCache)
|
||||||
ui := new(testUi)
|
ui := new(testUi)
|
||||||
_, err = bClient.Run(ui, cache)
|
artifacts, err := bClient.Run(ui, cache)
|
||||||
assert.True(b.runCalled, "run should be called")
|
assert.True(b.runCalled, "run should be called")
|
||||||
assert.Nil(err, "should not error")
|
assert.Nil(err, "should not error")
|
||||||
|
assert.Equal(len(artifacts), 1, "should have one artifact")
|
||||||
|
assert.Equal(artifacts[0].BuilderId(), "bid", "should have proper builder id")
|
||||||
|
|
||||||
// Test the UI given to run, which should be fully functional
|
// Test the UI given to run, which should be fully functional
|
||||||
if b.runCalled {
|
if b.runCalled {
|
||||||
|
|
Loading…
Reference in New Issue