Commit 41a7fd45 authored by Mitchell Hashimoto's avatar Mitchell Hashimoto

packer: Return artifact from build

parent cf6d2218
......@@ -7,7 +7,7 @@ import "log"
type Build interface {
Name() string
Prepare() error
Run(Ui)
Run(Ui) Artifact
}
// A build struct represents a single build job, the result of which should
......@@ -41,11 +41,11 @@ func (b *coreBuild) Prepare() (err error) {
}
// Runs the actual build. Prepare must be called prior to running this.
func (b *coreBuild) Run(ui Ui) {
func (b *coreBuild) Run(ui Ui) Artifact {
if !b.prepareCalled {
panic("Prepare must be called first")
}
hook := &DispatchHook{b.hooks}
b.builder.Run(ui, hook)
return b.builder.Run(ui, hook)
}
......@@ -7,7 +7,7 @@ import (
// An implementation of packer.Build where the build is actually executed
// over an RPC connection.
type Build struct {
type build struct {
client *rpc.Client
}
......@@ -23,23 +23,38 @@ type BuildRunArgs struct {
UiRPCAddress string
}
func (b *Build) Name() (result string) {
func Build(client *rpc.Client) *build {
return &build{client}
}
func (b *build) Name() (result string) {
b.client.Call("Build.Name", new(interface{}), &result)
return
}
func (b *Build) Prepare() (err error) {
func (b *build) Prepare() (err error) {
b.client.Call("Build.Prepare", new(interface{}), &err)
return
}
func (b *Build) Run(ui packer.Ui) {
func (b *build) Run(ui packer.Ui) packer.Artifact {
// Create and start the server for the UI
// TODO: Error handling
server := rpc.NewServer()
RegisterUi(server, ui)
args := &BuildRunArgs{serveSingleConn(server)}
b.client.Call("Build.Run", args, new(interface{}))
var reply string
if err := b.client.Call("Build.Run", args, &reply); err != nil {
panic(err)
}
client, err := rpc.Dial("tcp", reply)
if err != nil {
panic(err)
}
return Artifact(client)
}
func (b *BuildServer) Name(args *interface{}, reply *string) error {
......@@ -52,14 +67,18 @@ func (b *BuildServer) Prepare(args *BuildPrepareArgs, reply *error) error {
return nil
}
func (b *BuildServer) Run(args *BuildRunArgs, reply *interface{}) error {
func (b *BuildServer) Run(args *BuildRunArgs, reply *string) error {
client, err := rpc.Dial("tcp", args.UiRPCAddress)
if err != nil {
return err
}
b.build.Run(&Ui{client})
artifact := b.build.Run(&Ui{client})
// Wrap the artifact
server := rpc.NewServer()
RegisterArtifact(server, artifact)
*reply = nil
*reply = serveSingleConn(server)
return nil
}
......@@ -7,6 +7,8 @@ import (
"testing"
)
var testBuildArtifact = &testArtifact{}
type testBuild struct {
nameCalled bool
prepareCalled bool
......@@ -24,32 +26,27 @@ func (b *testBuild) Prepare() error {
return nil
}
func (b *testBuild) Run(ui packer.Ui) {
func (b *testBuild) Run(ui packer.Ui) packer.Artifact {
b.runCalled = true
b.runUi = ui
return testBuildArtifact
}
func TestBuildRPC(t *testing.T) {
assert := asserts.NewTestingAsserts(t, true)
// Create the UI to test
// Create the interface to test
b := new(testBuild)
bServer := &BuildServer{b}
// Start the RPC server
readyChan := make(chan int)
stopChan := make(chan int)
defer func() { stopChan <- 1 }()
go testRPCServer(":1234", "Build", bServer, readyChan, stopChan)
<-readyChan
// Start the server
server := rpc.NewServer()
RegisterBuild(server, b)
address := serveSingleConn(server)
// Create the client over RPC and run some methods to verify it works
client, err := rpc.Dial("tcp", ":1234")
if err != nil {
panic(err)
}
bClient := &Build{client}
client, err := rpc.Dial("tcp", address)
assert.Nil(err, "should be able to connect")
bClient := Build(client)
// Test Name
bClient.Name()
......@@ -76,7 +73,7 @@ func TestBuild_ImplementsBuild(t *testing.T) {
assert := asserts.NewTestingAsserts(t, true)
var realBuild packer.Build
b := &Build{nil}
b := Build(nil)
assert.Implementor(b, &realBuild, "should be a Build")
}
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