Merge "services/identity/server: fix shutdown race"
diff --git a/cmd/mgmt/device/impl/impl.go b/cmd/mgmt/device/impl/impl.go
index 30f332d..da5b736 100644
--- a/cmd/mgmt/device/impl/impl.go
+++ b/cmd/mgmt/device/impl/impl.go
@@ -165,7 +165,14 @@
 		}
 	}
 	if err := call.Finish(); err != nil {
-		return fmt.Errorf("Start failed: %v", err)
+		if len(appInstanceIDs) == 0 {
+			return fmt.Errorf("Start failed: %v", err)
+		} else {
+			return fmt.Errorf(
+				"Start failed: %v,\nView log with:\n debug logs read `debug glob %s/logs/STDERR-*`",
+				err, naming.Join(appInstallation, appInstanceIDs[0]))
+		}
+
 	}
 	for _, id := range appInstanceIDs {
 		fmt.Fprintf(cmd.Stdout(), "Successfully started: %q\n", naming.Join(appInstallation, id))
diff --git a/lib/vdl/codegen/javascript/gen_type_def.go b/lib/vdl/codegen/javascript/gen_type_def.go
index d1a399d..76acc2a 100644
--- a/lib/vdl/codegen/javascript/gen_type_def.go
+++ b/lib/vdl/codegen/javascript/gen_type_def.go
@@ -4,6 +4,7 @@
 	"fmt"
 
 	"v.io/v23/vdl"
+	"v.io/x/ref/lib/vdl/vdlutil"
 )
 
 // makeTypeDefinitionsString generates a string that defines the specified types.
@@ -30,7 +31,11 @@
 
 	for _, def := range sortedDefs {
 		if def.Type.Name() != "" {
-			str += makeConstructorDefinitionString(def.Type, jsnames)
+			if def.Type.Kind() == vdl.Enum {
+				str += makeEnumLabelString(def.Type, jsnames)
+			} else {
+				str += makeConstructorDefinitionString(def.Type, jsnames)
+			}
 		}
 	}
 
@@ -112,6 +117,24 @@
 	return fmt.Sprintf("module.exports.%s = %s;\n", name, ctorName)
 }
 
+// makeEnumLabelString creates a string that defines the labels in an enum.
+// e.g. `module.Exports.MyEnum = {
+//   ALabel: (Registry.lookupOrCreateConstructor(_typeMyEnum))("ALabel"),
+//   BLabel: (Registry.lookupOrCreateConstructor(_typeMyEnum))("BLabel"),
+// }`
+
+func makeEnumLabelString(t *vdl.Type, jsnames typeNames) string {
+	_, name := vdl.SplitIdent(t.Name())
+	str := fmt.Sprintf("module.exports.%s = {\n", name)
+	for i := 0; i < t.NumEnumLabel(); i++ {
+		enumVal := vdl.ZeroValue(t)
+		enumVal.AssignEnumIndex(i)
+		str += fmt.Sprintf("  %s: %s,\n", vdlutil.ToConstCase(t.EnumLabel(i)), typedConst(jsnames, enumVal))
+	}
+	str += "};\n"
+	return str
+}
+
 func jsKind(k vdl.Kind) string {
 	switch k {
 	case vdl.Any:
diff --git a/lib/vdl/codegen/javascript/pkg_types.go b/lib/vdl/codegen/javascript/pkg_types.go
index f7445d9..7f986da 100644
--- a/lib/vdl/codegen/javascript/pkg_types.go
+++ b/lib/vdl/codegen/javascript/pkg_types.go
@@ -6,6 +6,7 @@
 	"strings"
 
 	"v.io/x/ref/lib/vdl/compile"
+	"v.io/x/ref/lib/vdl/vdlutil"
 
 	"v.io/v23/vdl"
 )
@@ -52,6 +53,10 @@
 		return name
 	}
 
+	if t.Kind() == vdl.Enum {
+		return fmt.Sprintf("%s.%s._type", tn.LookupConstructor(t), vdlutil.ToConstCase(t.EnumLabel(0)))
+	}
+
 	return "new " + tn.LookupConstructor(t) + "()._type"
 }
 
diff --git a/lib/vdl/codegen/javascript/type_test.go b/lib/vdl/codegen/javascript/type_test.go
index bc3df73..7e932f2 100644
--- a/lib/vdl/codegen/javascript/type_test.go
+++ b/lib/vdl/codegen/javascript/type_test.go
@@ -57,6 +57,9 @@
 					{
 						Type: vdl.ListType(vdl.ByteType),
 					},
+					{
+						Type: vdl.NamedType("ColorsBeginningWithAOrB", vdl.EnumType("Aqua", "Beige")),
+					},
 				},
 			},
 		},
@@ -75,6 +78,7 @@
 
 	expectedResult := `var _type1 = new vdl.Type();
 var _type2 = new vdl.Type();
+var _typeColorsBeginningWithAOrB = new vdl.Type();
 var _typeNamedList = new vdl.Type();
 var _typeNamedStruct = new vdl.Type();
 _type1.kind = vdl.Kind.LIST;
@@ -83,6 +87,9 @@
 _type2.kind = vdl.Kind.LIST;
 _type2.name = "";
 _type2.elem = vdl.Types.BYTE;
+_typeColorsBeginningWithAOrB.kind = vdl.Kind.ENUM;
+_typeColorsBeginningWithAOrB.name = "ColorsBeginningWithAOrB";
+_typeColorsBeginningWithAOrB.labels = ["Aqua", "Beige"];
 _typeNamedList.kind = vdl.Kind.LIST;
 _typeNamedList.name = "NamedList";
 _typeNamedList.elem = _typeNamedStruct;
@@ -91,8 +98,13 @@
 _typeNamedStruct.fields = [{name: "List", type: _typeNamedList}, {name: "Bool", type: new otherPkg.NamedBool()._type}, {name: "UnnamedTypeField", type: _type1}];
 _type1.freeze();
 _type2.freeze();
+_typeColorsBeginningWithAOrB.freeze();
 _typeNamedList.freeze();
 _typeNamedStruct.freeze();
+module.exports.ColorsBeginningWithAOrB = {
+  AQUA: canonicalize.reduce(new (vdl.Registry.lookupOrCreateConstructor(_typeColorsBeginningWithAOrB))('Aqua', true), _typeColorsBeginningWithAOrB),
+  BEIGE: canonicalize.reduce(new (vdl.Registry.lookupOrCreateConstructor(_typeColorsBeginningWithAOrB))('Beige', true), _typeColorsBeginningWithAOrB),
+};
 module.exports.NamedList = (vdl.Registry.lookupOrCreateConstructor(_typeNamedList));
 module.exports.NamedStruct = (vdl.Registry.lookupOrCreateConstructor(_typeNamedStruct));
 `
diff --git a/services/wsprd/ipc/server/server.go b/services/wsprd/ipc/server/server.go
index 25fbdf2..4543182 100644
--- a/services/wsprd/ipc/server/server.go
+++ b/services/wsprd/ipc/server/server.go
@@ -333,11 +333,12 @@
 // It resolves each []security.Caveat in cavs to an error (or nil) and collects them in a slice.
 // TODO(ataly, ashankar, bprosnitz): Update this method so tha it also conveys the CallSide to
 // JavaScript.
-func (s *Server) validateCavsInJavascript(call security.Call, _ security.CallSide, cavs [][]security.Caveat) []error {
+func (s *Server) validateCavsInJavascript(call security.Call, callSide security.CallSide, cavs [][]security.Caveat) []error {
 	flow := s.helper.CreateNewFlow(s, nil)
 	req := CaveatValidationRequest{
-		Call: s.convertSecurityCall(call, false),
-		Cavs: cavs,
+		Call:     s.convertSecurityCall(call, false),
+		CallSide: callSide,
+		Cavs:     cavs,
 	}
 
 	replyChan := make(chan []error, 1)
diff --git a/services/wsprd/ipc/server/server.vdl b/services/wsprd/ipc/server/server.vdl
index 3872b16..507dfdf 100644
--- a/services/wsprd/ipc/server/server.vdl
+++ b/services/wsprd/ipc/server/server.vdl
@@ -19,6 +19,7 @@
 
 type CaveatValidationRequest struct {
     Call SecurityCall
+    CallSide security.CallSide
     Cavs [][]security.Caveat
 }
 
diff --git a/services/wsprd/ipc/server/server.vdl.go b/services/wsprd/ipc/server/server.vdl.go
index adb4dad..27b9a46 100644
--- a/services/wsprd/ipc/server/server.vdl.go
+++ b/services/wsprd/ipc/server/server.vdl.go
@@ -33,8 +33,9 @@
 }
 
 type CaveatValidationRequest struct {
-	Call SecurityCall
-	Cavs [][]security.Caveat
+	Call     SecurityCall
+	CallSide security.CallSide
+	Cavs     [][]security.Caveat
 }
 
 func (CaveatValidationRequest) __VDLReflect(struct {