Merge "veyron/services/wsprd: Broke up the monolithic lib package into many smaller packages."
diff --git a/services/mgmt/build/constants.go b/services/mgmt/build/constants.go
deleted file mode 100644
index d150780..0000000
--- a/services/mgmt/build/constants.go
+++ /dev/null
@@ -1,64 +0,0 @@
-package build
-
-type OperatingSystem uint8
-
-const (
-	LINUX OperatingSystem = iota
-	DARWIN
-	WINDOWS
-)
-
-func (os OperatingSystem) String() string {
-	switch os {
-	case LINUX:
-		return "linux"
-	case DARWIN:
-		return "darwin"
-	case WINDOWS:
-		return "windows"
-	default:
-		return "unknown"
-	}
-}
-
-type Format uint8
-
-const (
-	ELF Format = iota
-	MACH
-	PE
-)
-
-func (format Format) String() string {
-	switch format {
-	case ELF:
-		return "elf"
-	case MACH:
-		return "mach-o"
-	case PE:
-		return "pe"
-	default:
-		return "unknown"
-	}
-}
-
-type Architecture uint8
-
-const (
-	AMD64 Architecture = iota
-	ARM
-	X86
-)
-
-func (arch Architecture) String() string {
-	switch arch {
-	case AMD64:
-		return "amd64"
-	case ARM:
-		return "arm"
-	case X86:
-		return "x86"
-	default:
-		return "unknown"
-	}
-}
diff --git a/services/mgmt/build/impl/impl_test.go b/services/mgmt/build/impl/impl_test.go
index 31b2d71..0404e7b 100644
--- a/services/mgmt/build/impl/impl_test.go
+++ b/services/mgmt/build/impl/impl_test.go
@@ -1,6 +1,7 @@
 package impl
 
 import (
+	"io"
 	"os"
 	"path/filepath"
 	"strings"
@@ -49,31 +50,43 @@
 	}
 }
 
-func invokeBuild(t *testing.T, client build.Build, files []build.File) ([]byte, error) {
+func invokeBuild(t *testing.T, client build.Build, files []build.File) ([]byte, []build.File, error) {
 	stream, err := client.Build(rt.R().NewContext())
 	if err != nil {
 		t.Errorf("Build() failed: %v", err)
-		return nil, err
+		return nil, nil, err
 	}
 	for _, file := range files {
 		if err := stream.Send(file); err != nil {
 			t.Logf("Send() failed: %v", err)
 			stream.Cancel()
-			return nil, err
+			return nil, nil, err
 		}
 	}
 	if err := stream.CloseSend(); err != nil {
 		t.Logf("CloseSend() failed: %v", err)
 		stream.Cancel()
-		return nil, err
+		return nil, nil, err
+	}
+	bins := make([]build.File, 0)
+	for {
+		bin, err := stream.Recv()
+		if err != nil && err != io.EOF {
+			t.Logf("Recv() failed: %v", err)
+			return nil, nil, err
+		}
+		if err == io.EOF {
+			break
+		}
+		bins = append(bins, bin)
 	}
 	output, err := stream.Finish()
 	if err != nil {
 		t.Logf("Finish() failed: %v", err)
 		stream.Cancel()
-		return nil, err
+		return nil, nil, err
 	}
-	return output, nil
+	return output, bins, nil
 }
 
 const mainSrc = `package main
@@ -97,13 +110,16 @@
 			Contents: []byte(mainSrc),
 		},
 	}
-	output, err := invokeBuild(t, client, files)
+	output, bins, err := invokeBuild(t, client, files)
 	if err != nil {
 		t.FailNow()
 	}
 	if got, expected := strings.TrimSpace(string(output)), "test"; got != expected {
 		t.Fatalf("Unexpected output: got %v, expected %v", got, expected)
 	}
+	if got, expected := len(bins), 1; got != expected {
+		t.Fatalf("Unexpected number of binaries: got %v, expected %v", got, expected)
+	}
 }
 
 // TestFailure checks that the build server fails to build a package
@@ -118,7 +134,7 @@
 			Contents: []byte(""),
 		},
 	}
-	if _, err := invokeBuild(t, client, files); err == nil {
+	if _, _, err := invokeBuild(t, client, files); err == nil {
 		t.FailNow()
 	}
 }
diff --git a/services/mgmt/build/impl/invoker.go b/services/mgmt/build/impl/invoker.go
index b2b9c52..2ef2585 100644
--- a/services/mgmt/build/impl/invoker.go
+++ b/services/mgmt/build/impl/invoker.go
@@ -1,6 +1,7 @@
 package impl
 
 import (
+	"bytes"
 	"errors"
 	"io"
 	"io/ioutil"
@@ -15,7 +16,8 @@
 )
 
 var (
-	errOperationFailed = errors.New("operation failed")
+	errBuildFailed   = errors.New("build failed")
+	errInternalError = errors.New("internal error")
 )
 
 // invoker holds the state of a build server invocation.
@@ -33,25 +35,28 @@
 
 // BUILD INTERFACE IMPLEMENTATION
 
+// TODO(jsimsa): Add support for building for a specific profile
+// specified as a suffix the Build().
 func (i *invoker) Build(_ ipc.ServerContext, stream build.BuildServiceBuildStream) ([]byte, error) {
+	vlog.VI(1).Infof("Build() called.")
 	dir, prefix := "", ""
 	dirPerm, filePerm := os.FileMode(0700), os.FileMode(0600)
 	root, err := ioutil.TempDir(dir, prefix)
 	if err != nil {
 		vlog.Errorf("TempDir(%v, %v) failed: %v", dir, prefix, err)
-		return nil, errOperationFailed
+		return nil, errInternalError
 	}
 	defer os.RemoveAll(root)
 	srcDir := filepath.Join(root, "go", "src")
 	if err := os.MkdirAll(srcDir, dirPerm); err != nil {
 		vlog.Errorf("MkdirAll(%v, %v) failed: %v", srcDir, dirPerm, err)
-		return nil, errOperationFailed
+		return nil, errInternalError
 	}
 	for {
 		srcFile, err := stream.Recv()
 		if err != nil && err != io.EOF {
 			vlog.Errorf("Recv() failed: %v", err)
-			return nil, errOperationFailed
+			return nil, errInternalError
 		}
 		if err == io.EOF {
 			break
@@ -60,21 +65,50 @@
 		dir := filepath.Dir(filePath)
 		if err := os.MkdirAll(dir, dirPerm); err != nil {
 			vlog.Errorf("MkdirAll(%v, %v) failed: %v", dir, dirPerm, err)
-			return nil, errOperationFailed
+			return nil, errInternalError
 		}
 		if err := ioutil.WriteFile(filePath, srcFile.Contents, filePerm); err != nil {
 			vlog.Errorf("WriteFile(%v, %v) failed: %v", filePath, filePerm, err)
-			return nil, errOperationFailed
+			return nil, errInternalError
 		}
 	}
-	cmd := exec.Command(i.gobin, "build", "-v", "...")
+	cmd := exec.Command(i.gobin, "install", "-v", "...")
 	cmd.Env = append(cmd.Env, "GOPATH="+filepath.Dir(srcDir))
-	bytes, err := cmd.CombinedOutput()
-	if err != nil {
-		vlog.Errorf("CombinedOutput() failed: %v", err)
-		return nil, errOperationFailed
+	var output bytes.Buffer
+	cmd.Stdout = &output
+	cmd.Stderr = &output
+	if err := cmd.Run(); err != nil {
+		vlog.Errorf("Run() failed: %v", err)
+		if output.Len() != 0 {
+			vlog.Errorf("%v", output.String())
+		}
+		return output.Bytes(), errBuildFailed
 	}
-	return bytes, nil
+	binDir := filepath.Join(root, "go", "bin")
+	files, err := ioutil.ReadDir(binDir)
+	if err != nil {
+		vlog.Errorf("ReadDir(%v) failed: %v", binDir, err)
+		return nil, errInternalError
+	}
+	// TODO(jsimsa): Analyze the binary files for non-standard shared
+	// library dependencies.
+	for _, file := range files {
+		binPath := filepath.Join(root, "go", "bin", file.Name())
+		bytes, err := ioutil.ReadFile(binPath)
+		if err != nil {
+			vlog.Errorf("ReadFile(%v) failed: %v", binPath, err)
+			return nil, errInternalError
+		}
+		result := build.File{
+			Name:     "bin/" + file.Name(),
+			Contents: bytes,
+		}
+		if err := stream.Send(result); err != nil {
+			vlog.Errorf("Send() failed: %v", err)
+			return nil, errInternalError
+		}
+	}
+	return output.Bytes(), nil
 }
 
 func (i *invoker) Describe(_ ipc.ServerContext, name string) (binary.Description, error) {
diff --git a/services/mgmt/build/impl/util.go b/services/mgmt/build/impl/util.go
new file mode 100644
index 0000000..2710ae9
--- /dev/null
+++ b/services/mgmt/build/impl/util.go
@@ -0,0 +1,59 @@
+package impl
+
+import (
+	"runtime"
+
+	"veyron2/services/mgmt/build"
+)
+
+func getArch() build.Architecture {
+	switch runtime.GOARCH {
+	case "386":
+		return build.X86
+	case "amd64":
+		return build.AMD64
+	case "arm":
+		return build.ARM
+	default:
+		return build.UnsupportedArchitecture
+	}
+}
+
+func getOS() build.OperatingSystem {
+	switch runtime.GOOS {
+	case "darwin":
+		return build.Darwin
+	case "linux":
+		return build.Linux
+	case "windows":
+		return build.Windows
+	default:
+		return build.UnsupportedOperatingSystem
+	}
+}
+
+func archString(arch build.Architecture) string {
+	switch arch {
+	case build.X86:
+		return "x86"
+	case build.AMD64:
+		return "amd64"
+	case build.ARM:
+		return "arm"
+	default:
+		return "unsupported"
+	}
+}
+
+func osString(os build.OperatingSystem) string {
+	switch os {
+	case build.Darwin:
+		return "darwin"
+	case build.Linux:
+		return "linux"
+	case build.Windows:
+		return "windows"
+	default:
+		return "unsupported"
+	}
+}
diff --git a/services/mgmt/node/impl/invoker.go b/services/mgmt/node/impl/invoker.go
index 565d6d8..ed450c6 100644
--- a/services/mgmt/node/impl/invoker.go
+++ b/services/mgmt/node/impl/invoker.go
@@ -41,8 +41,7 @@
 	"time"
 
 	"veyron/lib/config"
-	"veyron/services/mgmt/build"
-	cbinary "veyron/services/mgmt/lib/binary"
+	blib "veyron/services/mgmt/lib/binary"
 	vexec "veyron/services/mgmt/lib/exec"
 	"veyron/services/mgmt/profile"
 
@@ -52,6 +51,7 @@
 	"veyron2/rt"
 	"veyron2/services/mgmt/application"
 	"veyron2/services/mgmt/binary"
+	"veyron2/services/mgmt/build"
 	"veyron2/services/mgmt/node"
 	"veyron2/services/mgmt/repository"
 	"veyron2/verror"
@@ -119,30 +119,30 @@
 // TODO(jsimsa): Avoid computing the host node description from
 // scratch if a recent cached copy exists.
 func (i *invoker) computeNodeProfile() (*profile.Specification, error) {
-	result := profile.Specification{Format: profile.Format{Attributes: make(map[string]string)}}
+	result := profile.Specification{}
 
 	// Find out what the supported file format, operating system, and
 	// architecture is.
 	switch runtime.GOOS {
-	case "linux":
-		result.Format.Name = build.ELF.String()
-		result.Format.Attributes["os"] = build.LINUX.String()
 	case "darwin":
-		result.Format.Name = build.MACH.String()
-		result.Format.Attributes["os"] = build.DARWIN.String()
+		result.Format = build.MACH
+		result.OS = build.Darwin
+	case "linux":
+		result.Format = build.ELF
+		result.OS = build.Linux
 	case "windows":
-		result.Format.Name = build.PE.String()
-		result.Format.Attributes["os"] = build.WINDOWS.String()
+		result.Format = build.PE
+		result.OS = build.Windows
 	default:
 		return nil, errors.New("Unsupported operating system: " + runtime.GOOS)
 	}
 	switch runtime.GOARCH {
 	case "amd64":
-		result.Format.Attributes["arch"] = build.AMD64.String()
+		result.Arch = build.AMD64
 	case "arm":
-		result.Format.Attributes["arch"] = build.AMD64.String()
+		result.Arch = build.ARM
 	case "x86":
-		result.Format.Attributes["arch"] = build.AMD64.String()
+		result.Arch = build.X86
 	default:
 		return nil, errors.New("Unsupported hardware architecture: " + runtime.GOARCH)
 	}
@@ -269,13 +269,13 @@
 	result := node.Description{Profiles: make(map[string]struct{})}
 loop:
 	for _, profile := range known {
-		if profile.Format.Name != p.Format.Name {
+		if profile.Format != p.Format {
 			continue
 		}
-		if profile.Format.Attributes["os"] != p.Format.Attributes["os"] {
+		if profile.OS != p.OS {
 			continue
 		}
-		if profile.Format.Attributes["arch"] != p.Format.Attributes["arch"] {
+		if profile.Arch != p.Arch {
 			continue
 		}
 		for library := range profile.Libraries {
@@ -331,7 +331,7 @@
 // APPLICATION INTERFACE IMPLEMENTATION
 
 func downloadBinary(workspace, name string) error {
-	data, err := cbinary.Download(name)
+	data, err := blib.Download(name)
 	if err != nil {
 		vlog.Errorf("Download(%v) failed: %v", name, err)
 		return errOperationFailed
diff --git a/services/mgmt/profile/impl/impl_test.go b/services/mgmt/profile/impl/impl_test.go
index bb52ef9..ca9ff10 100644
--- a/services/mgmt/profile/impl/impl_test.go
+++ b/services/mgmt/profile/impl/impl_test.go
@@ -10,15 +10,18 @@
 
 	"veyron2/naming"
 	"veyron2/rt"
+	"veyron2/services/mgmt/build"
 )
 
 var (
 	// spec is an example profile specification used throughout the test.
 	spec = profile.Specification{
-		Format:      profile.Format{Name: "elf", Attributes: map[string]string{"os": "linux", "arch": "amd64"}},
+		Arch:        build.AMD64,
+		Description: "Example profile to test the profile repository implementation.",
+		Format:      build.ELF,
 		Libraries:   map[profile.Library]struct{}{profile.Library{Name: "foo", MajorVersion: "1", MinorVersion: "0"}: struct{}{}},
 		Label:       "example",
-		Description: "Example profile to test the profile repository implementation.",
+		OS:          build.Linux,
 	}
 )
 
diff --git a/services/mgmt/profile/profile.vdl b/services/mgmt/profile/profile.vdl
index d37c59b..0f6338b 100644
--- a/services/mgmt/profile/profile.vdl
+++ b/services/mgmt/profile/profile.vdl
@@ -2,16 +2,7 @@
 // types used by the implementation of Veyron profiles.
 package profile
 
-// Format includes a type (e.g. ELF) and each instance of the format
-// has some specific attributes. The key attributes are the target
-// operating system (e.g. for ELF this could be one of System V,
-// HP-UX, NetBSD, Linux, Solaris, AIX, IRIX, FreeBSD, and OpenBSD) and
-// the target instruction set architecture (e.g. for ELF this could be
-// one of SPARC, x86, PowerPC, ARM, IA-64, x86-64, and AArch64).
-type Format struct {
-	Name       string
-	Attributes map[string]string
-}
+import "veyron2/services/mgmt/build"
 
 // Library describes a shared library that applications may use.
 type Library struct {
@@ -26,12 +17,17 @@
 // Specification is how we represent a profile internally. It should
 // provide enough information to allow matching of binaries to nodes.
 type Specification struct {
-	// Format is the file format of the application binary.
-	Format      Format
-	// Libraries is a set of libraries the application binary depends on.
-	Libraries   set[Library]
-	// A human-friendly concise label for the profile, e.g. "linux-media"
-	Label       string
-	// A human-friendly description of the profile.
+	// Arch is the target hardware architecture of the profile.
+	Arch        build.Architecture
+	// Description is a human-friendly description of the profile.
 	Description string
+	// Format is the file format supported by the profile.
+	Format      build.Format
+	// Libraries is a set of libraries the profile requires.
+	Libraries   set[Library]
+	// Label is a human-friendly concise label for the profile,
+	// e.g. "linux-media".
+	Label       string
+	// OS is the target operating system of the profile.
+	OS          build.OperatingSystem
 }
diff --git a/services/mgmt/profile/profile.vdl.go b/services/mgmt/profile/profile.vdl.go
index c219f26..8ece520 100644
--- a/services/mgmt/profile/profile.vdl.go
+++ b/services/mgmt/profile/profile.vdl.go
@@ -5,16 +5,9 @@
 // types used by the implementation of Veyron profiles.
 package profile
 
-// Format includes a type (e.g. ELF) and each instance of the format
-// has some specific attributes. The key attributes are the target
-// operating system (e.g. for ELF this could be one of System V,
-// HP-UX, NetBSD, Linux, Solaris, AIX, IRIX, FreeBSD, and OpenBSD) and
-// the target instruction set architecture (e.g. for ELF this could be
-// one of SPARC, x86, PowerPC, ARM, IA-64, x86-64, and AArch64).
-type Format struct {
-	Name       string
-	Attributes map[string]string
-}
+import (
+	"veyron2/services/mgmt/build"
+)
 
 // Library describes a shared library that applications may use.
 type Library struct {
@@ -29,12 +22,17 @@
 // Specification is how we represent a profile internally. It should
 // provide enough information to allow matching of binaries to nodes.
 type Specification struct {
-	// Format is the file format of the application binary.
-	Format Format
-	// Libraries is a set of libraries the application binary depends on.
-	Libraries map[Library]struct{}
-	// A human-friendly concise label for the profile, e.g. "linux-media"
-	Label string
-	// A human-friendly description of the profile.
+	// Arch is the target hardware architecture of the profile.
+	Arch build.Architecture
+	// Description is a human-friendly description of the profile.
 	Description string
+	// Format is the file format supported by the profile.
+	Format build.Format
+	// Libraries is a set of libraries the profile requires.
+	Libraries map[Library]struct{}
+	// Label is a human-friendly concise label for the profile,
+	// e.g. "linux-media".
+	Label string
+	// OS is the target operating system of the profile.
+	OS build.OperatingSystem
 }
diff --git a/services/mgmt/repository/repository.vdl.go b/services/mgmt/repository/repository.vdl.go
index f6bcc37..83bc841 100644
--- a/services/mgmt/repository/repository.vdl.go
+++ b/services/mgmt/repository/repository.vdl.go
@@ -523,46 +523,42 @@
 	result := _gen_ipc.ServiceSignature{Methods: make(map[string]_gen_ipc.MethodSignature)}
 	result.Methods["Put"] = _gen_ipc.MethodSignature{
 		InArgs: []_gen_ipc.MethodArgument{
-			{Name: "Specification", Type: 69},
+			{Name: "Specification", Type: 70},
 		},
 		OutArgs: []_gen_ipc.MethodArgument{
-			{Name: "", Type: 70},
+			{Name: "", Type: 71},
 		},
 	}
 	result.Methods["Remove"] = _gen_ipc.MethodSignature{
 		InArgs: []_gen_ipc.MethodArgument{},
 		OutArgs: []_gen_ipc.MethodArgument{
-			{Name: "", Type: 70},
+			{Name: "", Type: 71},
 		},
 	}
 	result.Methods["Specification"] = _gen_ipc.MethodSignature{
 		InArgs: []_gen_ipc.MethodArgument{},
 		OutArgs: []_gen_ipc.MethodArgument{
-			{Name: "", Type: 69},
 			{Name: "", Type: 70},
+			{Name: "", Type: 71},
 		},
 	}
 
 	result.TypeDefs = []_gen_vdlutil.Any{
-		_gen_wiretype.MapType{Key: 0x3, Elem: 0x3, Name: "", Tags: []string(nil)}, _gen_wiretype.StructType{
-			[]_gen_wiretype.FieldType{
-				_gen_wiretype.FieldType{Type: 0x3, Name: "Name"},
-				_gen_wiretype.FieldType{Type: 0x41, Name: "Attributes"},
-			},
-			"veyron/services/mgmt/profile.Format", []string(nil)},
-		_gen_wiretype.StructType{
+		_gen_wiretype.NamedPrimitiveType{Type: 0x32, Name: "veyron2/services/mgmt/build.Architecture", Tags: []string(nil)}, _gen_wiretype.NamedPrimitiveType{Type: 0x32, Name: "veyron2/services/mgmt/build.Format", Tags: []string(nil)}, _gen_wiretype.StructType{
 			[]_gen_wiretype.FieldType{
 				_gen_wiretype.FieldType{Type: 0x3, Name: "Name"},
 				_gen_wiretype.FieldType{Type: 0x3, Name: "MajorVersion"},
 				_gen_wiretype.FieldType{Type: 0x3, Name: "MinorVersion"},
 			},
 			"veyron/services/mgmt/profile.Library", []string(nil)},
-		_gen_wiretype.MapType{Key: 0x43, Elem: 0x2, Name: "", Tags: []string(nil)}, _gen_wiretype.StructType{
+		_gen_wiretype.MapType{Key: 0x43, Elem: 0x2, Name: "", Tags: []string(nil)}, _gen_wiretype.NamedPrimitiveType{Type: 0x32, Name: "veyron2/services/mgmt/build.OperatingSystem", Tags: []string(nil)}, _gen_wiretype.StructType{
 			[]_gen_wiretype.FieldType{
+				_gen_wiretype.FieldType{Type: 0x41, Name: "Arch"},
+				_gen_wiretype.FieldType{Type: 0x3, Name: "Description"},
 				_gen_wiretype.FieldType{Type: 0x42, Name: "Format"},
 				_gen_wiretype.FieldType{Type: 0x44, Name: "Libraries"},
 				_gen_wiretype.FieldType{Type: 0x3, Name: "Label"},
-				_gen_wiretype.FieldType{Type: 0x3, Name: "Description"},
+				_gen_wiretype.FieldType{Type: 0x45, Name: "OS"},
 			},
 			"veyron/services/mgmt/profile.Specification", []string(nil)},
 		_gen_wiretype.NamedPrimitiveType{Type: 0x1, Name: "error", Tags: []string(nil)}}
diff --git a/services/store/typeregistryhack/init.go b/services/store/typeregistryhack/init.go
index 84a8f00..72b5216 100644
--- a/services/store/typeregistryhack/init.go
+++ b/services/store/typeregistryhack/init.go
@@ -5,10 +5,7 @@
 package typeregistryhack
 
 import (
-	"veyron/services/mgmt/profile"
-	"veyron2/services/mgmt/application"
-
-	// Register boxes types
+	// Register boxes types.
 	"veyron/examples/boxes"
 	// Register mdb types.
 	_ "veyron/examples/storage/mdb/schema"
@@ -18,6 +15,12 @@
 	_ "veyron/examples/bank/schema"
 	// Register stfortune types.
 	_ "veyron/examples/stfortune/schema"
+	// Register profile types.
+	"veyron/services/mgmt/profile"
+	// Register application types.
+	"veyron2/services/mgmt/application"
+	// Register build types.
+	_ "veyron2/services/mgmt/build"
 
 	"veyron2/vom"
 )
diff --git a/tools/profile/impl/impl.go b/tools/profile/impl/impl.go
index cef78c8..b90e8a6 100644
--- a/tools/profile/impl/impl.go
+++ b/tools/profile/impl/impl.go
@@ -8,6 +8,7 @@
 	"veyron/services/mgmt/repository"
 
 	"veyron2/rt"
+	"veyron2/services/mgmt/build"
 )
 
 var cmdLabel = &cmdline.Command{
@@ -105,10 +106,12 @@
 
 	// TODO(rthellend): Read an actual specification from a file.
 	spec := profile.Specification{
-		Format:      profile.Format{Name: "elf", Attributes: map[string]string{"os": "linux", "arch": "amd64"}},
+		Arch:        build.AMD64,
+		Description: "Example profile to test the profile manager implementation.",
+		Format:      build.ELF,
 		Libraries:   map[profile.Library]struct{}{profile.Library{Name: "foo", MajorVersion: "1", MinorVersion: "0"}: struct{}{}},
 		Label:       "example",
-		Description: "Example profile to test the profile manager implementation.",
+		OS:          build.Linux,
 	}
 	if err := p.Put(rt.R().NewContext(), spec); err != nil {
 		return err
diff --git a/tools/profile/impl/impl_test.go b/tools/profile/impl/impl_test.go
index 8500787..45ccf14 100644
--- a/tools/profile/impl/impl_test.go
+++ b/tools/profile/impl/impl_test.go
@@ -15,16 +15,19 @@
 	"veyron2/naming"
 	"veyron2/rt"
 	"veyron2/security"
+	"veyron2/services/mgmt/build"
 	"veyron2/vlog"
 )
 
 var (
 	// spec is an example profile specification used throughout the test.
 	spec = profile.Specification{
-		Format:      profile.Format{Name: "elf", Attributes: map[string]string{"os": "linux"}},
+		Arch:        build.AMD64,
+		Description: "Example profile to test the profile repository implementation.",
+		Format:      build.ELF,
 		Libraries:   map[profile.Library]struct{}{profile.Library{Name: "foo", MajorVersion: "1", MinorVersion: "0"}: struct{}{}},
 		Label:       "example",
-		Description: "Example profile to test the profile repository implementation.",
+		OS:          build.Linux,
 	}
 )