Merge "veyron/lib/modules: replace StdoutPipe with a custom in-memory queue-based ReadWriteCloser in order to decouple the consumers of stdout from using the stdout file handle directly."
diff --git a/services/identity/googleoauth/template.go b/services/identity/googleoauth/template.go
index a3dc4ee..7a06956 100644
--- a/services/identity/googleoauth/template.go
+++ b/services/identity/googleoauth/template.go
@@ -185,17 +185,18 @@
   <label class="col-sm-2" for="required-caveat">Expiration</label>
   <div class="col-sm-10" class="input-group" name="required-caveat">
     <div class="radio">
-      <label>
-      <input type="radio" name="requiredCaveat" id="requiredCaveat" value="Revocation" checked>
-      When explicitly revoked
-      </label>
-    </div>
-    <div class="radio">
       <div class="input-group">
-        <input type="radio" name="requiredCaveat" id="requiredCaveat" value="Expiry">
+        <input type="radio" name="requiredCaveat" id="requiredCaveat" value="Expiry" checked>
         <input type="datetime-local" id="expiry" name="expiry">
       </div>
     </div>
+    <div class="radio">
+      <label>
+      <!-- TODO(suharshs): Enable this after ThirdPartyCaveats are fixed. -->
+      <input type="radio" name="requiredCaveat" id="requiredCaveat" value="Revocation" disabled>
+      When explicitly revoked
+      </label>
+    </div>
   </div>
 </div>
 <h4 class="form-signin-heading">Additional caveats</h4>
diff --git a/services/mgmt/binary/impl/http_test.go b/services/mgmt/binary/impl/http_test.go
index 123540e..1ca59e8 100644
--- a/services/mgmt/binary/impl/http_test.go
+++ b/services/mgmt/binary/impl/http_test.go
@@ -27,7 +27,7 @@
 			size := testutil.Rand.Intn(1000*bufferLength) + 1
 			data[i] = testutil.RandomBytes(size)
 		}
-		if err := binary.Create(rt.R().NewContext(), int32(length)); err != nil {
+		if err := binary.Create(rt.R().NewContext(), int32(length), "application/octet-stream"); err != nil {
 			t.Fatalf("Create() failed: %v", err)
 		}
 		for i := 0; i < length; i++ {
@@ -35,7 +35,7 @@
 				t.FailNow()
 			}
 		}
-		parts, err := binary.Stat(rt.R().NewContext())
+		parts, _, err := binary.Stat(rt.R().NewContext())
 		if err != nil {
 			t.Fatalf("Stat() failed: %v", err)
 		}
diff --git a/services/mgmt/binary/impl/impl_test.go b/services/mgmt/binary/impl/impl_test.go
index 75bb0e0..ec0e151 100644
--- a/services/mgmt/binary/impl/impl_test.go
+++ b/services/mgmt/binary/impl/impl_test.go
@@ -162,13 +162,13 @@
 		size := testutil.Rand.Intn(1000 * bufferLength)
 		data := testutil.RandomBytes(size)
 		// Test the binary repository interface.
-		if err := binary.Create(rt.R().NewContext(), 1); err != nil {
+		if err := binary.Create(rt.R().NewContext(), 1, "applicaton/octet-stream"); err != nil {
 			t.Fatalf("Create() failed: %v", err)
 		}
 		if streamErr, err := invokeUpload(t, binary, data, 0); streamErr != nil || err != nil {
 			t.FailNow()
 		}
-		parts, err := binary.Stat(rt.R().NewContext())
+		parts, _, err := binary.Stat(rt.R().NewContext())
 		if err != nil {
 			t.Fatalf("Stat() failed: %v", err)
 		}
@@ -215,7 +215,7 @@
 			data[i] = testutil.RandomBytes(size)
 		}
 		// Test the binary repository interface.
-		if err := binary.Create(rt.R().NewContext(), int32(length)); err != nil {
+		if err := binary.Create(rt.R().NewContext(), int32(length), "applicaton/octet-stream"); err != nil {
 			t.Fatalf("Create() failed: %v", err)
 		}
 		for i := 0; i < length; i++ {
@@ -223,7 +223,7 @@
 				t.FailNow()
 			}
 		}
-		parts, err := binary.Stat(rt.R().NewContext())
+		parts, _, err := binary.Stat(rt.R().NewContext())
 		if err != nil {
 			t.Fatalf("Stat() failed: %v", err)
 		}
@@ -264,13 +264,13 @@
 			size := testutil.Rand.Intn(1000 * bufferLength)
 			data[i] = testutil.RandomBytes(size)
 		}
-		if err := binary.Create(rt.R().NewContext(), int32(length)); err != nil {
+		if err := binary.Create(rt.R().NewContext(), int32(length), "applicaton/octet-stream"); err != nil {
 			t.Fatalf("Create() failed: %v", err)
 		}
 		// Simulate a flaky upload client that keeps uploading parts until
 		// finished.
 		for {
-			parts, err := binary.Stat(rt.R().NewContext())
+			parts, _, err := binary.Stat(rt.R().NewContext())
 			if err != nil {
 				t.Fatalf("Stat() failed: %v", err)
 			}
@@ -309,10 +309,10 @@
 			data[i][j] = byte(testutil.Rand.Int())
 		}
 	}
-	if err := binary.Create(rt.R().NewContext(), int32(length)); err != nil {
+	if err := binary.Create(rt.R().NewContext(), int32(length), "applicaton/octet-stream"); err != nil {
 		t.Fatalf("Create() failed: %v", err)
 	}
-	if err := binary.Create(rt.R().NewContext(), int32(length)); err == nil {
+	if err := binary.Create(rt.R().NewContext(), int32(length), "applicaton/octet-stream"); err == nil {
 		t.Fatalf("Create() did not fail when it should have")
 	} else if want := verror.Exists; !verror.Is(err, want) {
 		t.Fatalf("Unexpected error: %v, expected error id %v", err, want)
@@ -372,7 +372,7 @@
 		name := naming.JoinAddressName(ep, obj)
 		binary := repository.BinaryClient(name)
 
-		if err := binary.Create(rt.R().NewContext(), 1); err != nil {
+		if err := binary.Create(rt.R().NewContext(), 1, "applicaton/octet-stream"); err != nil {
 			t.Fatalf("Create() failed: %v", err)
 		}
 		if streamErr, err := invokeUpload(t, binary, data, 0); streamErr != nil || err != nil {
diff --git a/services/mgmt/binary/impl/service.go b/services/mgmt/binary/impl/service.go
index 8a01122..44894a1 100644
--- a/services/mgmt/binary/impl/service.go
+++ b/services/mgmt/binary/impl/service.go
@@ -75,8 +75,8 @@
 
 const bufferLength = 4096
 
-func (i *binaryService) Create(_ ipc.ServerContext, nparts int32) error {
-	vlog.Infof("%v.Create(%v)", i.suffix, nparts)
+func (i *binaryService) Create(_ ipc.ServerContext, nparts int32, mediaType string) error {
+	vlog.Infof("%v.Create(%v, %v)", i.suffix, nparts, mediaType)
 	if nparts < 1 {
 		return errInvalidParts
 	}
@@ -199,12 +199,12 @@
 	return "", 0, nil
 }
 
-func (i *binaryService) Stat(ipc.ServerContext) ([]binary.PartInfo, error) {
+func (i *binaryService) Stat(ipc.ServerContext) ([]binary.PartInfo, string, error) {
 	vlog.Infof("%v.Stat()", i.suffix)
 	result := make([]binary.PartInfo, 0)
 	parts, err := getParts(i.path)
 	if err != nil {
-		return []binary.PartInfo{}, err
+		return []binary.PartInfo{}, "", err
 	}
 	for _, part := range parts {
 		checksumFile := filepath.Join(part, checksum)
@@ -215,7 +215,7 @@
 				continue
 			}
 			vlog.Errorf("ReadFile(%v) failed: %v", checksumFile, err)
-			return []binary.PartInfo{}, errOperationFailed
+			return []binary.PartInfo{}, "", errOperationFailed
 		}
 		dataFile := filepath.Join(part, data)
 		fi, err := os.Stat(dataFile)
@@ -225,11 +225,12 @@
 				continue
 			}
 			vlog.Errorf("Stat(%v) failed: %v", dataFile, err)
-			return []binary.PartInfo{}, errOperationFailed
+			return []binary.PartInfo{}, "", errOperationFailed
 		}
 		result = append(result, binary.PartInfo{Checksum: string(bytes), Size: fi.Size()})
 	}
-	return result, nil
+	// TODO(rthellend): Store the actual media type.
+	return result, "application/octet-stream", nil
 }
 
 func (i *binaryService) Upload(context repository.BinaryUploadContext, part int32) error {
diff --git a/services/mgmt/lib/binary/impl.go b/services/mgmt/lib/binary/impl.go
index 41af160..747ede1 100644
--- a/services/mgmt/lib/binary/impl.go
+++ b/services/mgmt/lib/binary/impl.go
@@ -44,7 +44,8 @@
 
 func download(ctx context.T, w io.WriteSeeker, von string) error {
 	client := repository.BinaryClient(von)
-	parts, err := client.Stat(ctx)
+	// TODO(rthellend): Use the media type.
+	parts, _, err := client.Stat(ctx)
 	if err != nil {
 		vlog.Errorf("Stat() failed: %v", err)
 		return err
@@ -174,7 +175,9 @@
 		return errOperationFailed
 	}
 	nparts := (size-1)/partSize + 1
-	if err := client.Create(ctx, int32(nparts)); err != nil {
+	// TODO(rthellend): Determine the actual media type.
+	mediaType := "application/octet-stream"
+	if err := client.Create(ctx, int32(nparts), mediaType); err != nil {
 		vlog.Errorf("Create() failed: %v", err)
 		return err
 	}
@@ -220,7 +223,7 @@
 			}
 			if err := sender.Close(); err != nil {
 				vlog.Errorf("Close() failed: %v", err)
-				parts, statErr := client.Stat(ctx)
+				parts, _, statErr := client.Stat(ctx)
 				if statErr != nil {
 					vlog.Errorf("Stat() failed: %v", statErr)
 					if deleteErr := client.Delete(ctx); err != nil {
@@ -235,7 +238,7 @@
 			}
 			if err := stream.Finish(); err != nil {
 				vlog.Errorf("Finish() failed: %v", err)
-				parts, statErr := client.Stat(ctx)
+				parts, _, statErr := client.Stat(ctx)
 				if statErr != nil {
 					vlog.Errorf("Stat() failed: %v", statErr)
 					if deleteErr := client.Delete(ctx); err != nil {
diff --git a/services/mgmt/node/impl/mock_repo_test.go b/services/mgmt/node/impl/mock_repo_test.go
index 3901275..e669595 100644
--- a/services/mgmt/node/impl/mock_repo_test.go
+++ b/services/mgmt/node/impl/mock_repo_test.go
@@ -80,7 +80,7 @@
 
 // BINARY REPOSITORY INTERFACE IMPLEMENTATION
 
-func (*brInvoker) Create(ipc.ServerContext, int32) error {
+func (*brInvoker) Create(ipc.ServerContext, int32, string) error {
 	vlog.VI(1).Infof("Create()")
 	return nil
 }
@@ -125,16 +125,16 @@
 	return "", 0, nil
 }
 
-func (*brInvoker) Stat(ipc.ServerContext) ([]binary.PartInfo, error) {
+func (*brInvoker) Stat(ipc.ServerContext) ([]binary.PartInfo, string, error) {
 	vlog.VI(1).Infof("Stat()")
 	h := md5.New()
 	bytes, err := ioutil.ReadFile(os.Args[0])
 	if err != nil {
-		return []binary.PartInfo{}, errOperationFailed
+		return []binary.PartInfo{}, "", errOperationFailed
 	}
 	h.Write(bytes)
 	part := binary.PartInfo{Checksum: hex.EncodeToString(h.Sum(nil)), Size: int64(len(bytes))}
-	return []binary.PartInfo{part}, nil
+	return []binary.PartInfo{part}, "application/octet-stream", nil
 }
 
 func (i *brInvoker) Upload(repository.BinaryUploadContext, int32) error {
diff --git a/services/mgmt/repository/repository.vdl.go b/services/mgmt/repository/repository.vdl.go
index 0b017b3..028e6f6 100644
--- a/services/mgmt/repository/repository.vdl.go
+++ b/services/mgmt/repository/repository.vdl.go
@@ -254,10 +254,10 @@
 	result.Methods["Put"] = __ipc.MethodSignature{
 		InArgs: []__ipc.MethodArgument{
 			{Name: "Profiles", Type: 61},
-			{Name: "Envelope", Type: 65},
+			{Name: "Envelope", Type: 66},
 		},
 		OutArgs: []__ipc.MethodArgument{
-			{Name: "", Type: 66},
+			{Name: "", Type: 67},
 		},
 	}
 	result.Methods["Remove"] = __ipc.MethodSignature{
@@ -265,17 +265,18 @@
 			{Name: "Profile", Type: 3},
 		},
 		OutArgs: []__ipc.MethodArgument{
-			{Name: "", Type: 66},
+			{Name: "", Type: 67},
 		},
 	}
 
 	result.TypeDefs = []__vdlutil.Any{
-		__wiretype.StructType{
+		__wiretype.MapType{Key: 0x3, Elem: 0x3, Name: "", Tags: []string(nil)}, __wiretype.StructType{
 			[]__wiretype.FieldType{
 				__wiretype.FieldType{Type: 0x3, Name: "Title"},
 				__wiretype.FieldType{Type: 0x3d, Name: "Args"},
 				__wiretype.FieldType{Type: 0x3, Name: "Binary"},
 				__wiretype.FieldType{Type: 0x3d, Name: "Env"},
+				__wiretype.FieldType{Type: 0x41, Name: "Packages"},
 			},
 			"veyron.io/veyron/veyron2/services/mgmt/application.Envelope", []string(nil)},
 		__wiretype.NamedPrimitiveType{Type: 0x1, Name: "error", Tags: []string(nil)}}
diff --git a/tools/application/impl_test.go b/tools/application/impl_test.go
index 010ace1..526f4f5 100644
--- a/tools/application/impl_test.go
+++ b/tools/application/impl_test.go
@@ -25,6 +25,9 @@
 		Args:   []string{"arg1", "arg2", "arg3"},
 		Binary: "/path/to/binary",
 		Env:    []string{"env1", "env2", "env3"},
+		Packages: map[string]string{
+			"pkg1": "/path/to/package1",
+		},
 	}
 	jsonEnv = `{
   "Title": "fifa world cup",
@@ -38,7 +41,10 @@
     "env1",
     "env2",
     "env3"
-  ]
+  ],
+  "Packages": {
+    "pkg1": "/path/to/package1"
+  }
 }`
 )
 
diff --git a/tools/binary/impl_test.go b/tools/binary/impl_test.go
index 0f32f85..d438459 100644
--- a/tools/binary/impl_test.go
+++ b/tools/binary/impl_test.go
@@ -27,7 +27,7 @@
 	suffix string
 }
 
-func (s *server) Create(ipc.ServerContext, int32) error {
+func (s *server) Create(ipc.ServerContext, int32, string) error {
 	vlog.Infof("Create() was called. suffix=%v", s.suffix)
 	return nil
 }
@@ -53,13 +53,13 @@
 	return "", 0, nil
 }
 
-func (s *server) Stat(ipc.ServerContext) ([]binary.PartInfo, error) {
+func (s *server) Stat(ipc.ServerContext) ([]binary.PartInfo, string, error) {
 	vlog.Infof("Stat() was called. suffix=%v", s.suffix)
 	h := md5.New()
 	text := "HelloWorld"
 	h.Write([]byte(text))
 	part := binary.PartInfo{Checksum: hex.EncodeToString(h.Sum(nil)), Size: int64(len(text))}
-	return []binary.PartInfo{part}, nil
+	return []binary.PartInfo{part}, "text/plain", nil
 }
 
 func (s *server) Upload(ctx repository.BinaryUploadContext, _ int32) error {