Merge "veyron2/services/mgmt/application: Add optional packages"
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/application/impl/dispatcher.go b/services/mgmt/application/impl/dispatcher.go
index 92b03f8..8393beb 100644
--- a/services/mgmt/application/impl/dispatcher.go
+++ b/services/mgmt/application/impl/dispatcher.go
@@ -1,6 +1,8 @@
package impl
import (
+ "path/filepath"
+
"veyron.io/veyron/veyron/services/mgmt/repository"
"veyron.io/veyron/veyron/services/mgmt/lib/fs"
@@ -17,14 +19,14 @@
var _ ipc.Dispatcher = (*dispatcher)(nil)
-// NewDispatcher is the dispatcher factory.
-func NewDispatcher(name string, authorizer security.Authorizer) (*dispatcher, error) {
- // TODO(rjkroege@google.com): Use the config service.
- store, err := fs.NewMemstore("")
+// NewDispatcher is the dispatcher factory. storeDir is a path to a directory in which to
+// serialize the applicationd state.
+func NewDispatcher(storeDir string, authorizer security.Authorizer) (*dispatcher, error) {
+ store, err := fs.NewMemstore(filepath.Join(storeDir, "applicationdstate.db"))
if err != nil {
return nil, err
}
- return &dispatcher{store: store, storeRoot: name, auth: authorizer}, nil
+ return &dispatcher{store: store, storeRoot: storeDir, auth: authorizer}, nil
}
// DISPATCHER INTERFACE IMPLEMENTATION
diff --git a/services/mgmt/application/impl/impl_test.go b/services/mgmt/application/impl/impl_test.go
index 845c5ee..50e9ce2 100644
--- a/services/mgmt/application/impl/impl_test.go
+++ b/services/mgmt/application/impl/impl_test.go
@@ -2,6 +2,7 @@
import (
"io/ioutil"
+ "os"
"reflect"
"testing"
@@ -17,21 +18,15 @@
// TestInterface tests that the implementation correctly implements
// the Application interface.
func TestInterface(t *testing.T) {
- runtime := rt.Init()
- ctx := runtime.NewContext()
- defer runtime.Cleanup()
+ ctx := rt.R().NewContext()
// Setup and start the application repository server.
- server, err := runtime.NewServer()
+ server, err := rt.R().NewServer()
if err != nil {
t.Fatalf("NewServer() failed: %v", err)
}
defer server.Stop()
- server, err = runtime.NewServer()
- if err != nil {
- t.Fatalf("NewServer() failed: %v", err)
- }
dir, prefix := "", ""
store, err := ioutil.TempDir(dir, prefix)
if err != nil {
@@ -156,3 +151,88 @@
t.Fatalf("Stop() failed: %v", err)
}
}
+
+func init() {
+ rt.Init()
+}
+
+func TestPreserveAcrossRestarts(t *testing.T) {
+ server, err := rt.R().NewServer()
+ if err != nil {
+ t.Fatalf("NewServer() failed: %v", err)
+ }
+ defer server.Stop()
+ dir, prefix := "", ""
+ storedir, err := ioutil.TempDir(dir, prefix)
+ if err != nil {
+ t.Fatalf("TempDir(%q, %q) failed: %v", dir, prefix, err)
+ }
+ defer os.RemoveAll(storedir)
+
+ dispatcher, err := NewDispatcher(storedir, nil)
+ if err != nil {
+ t.Fatalf("NewDispatcher() failed: %v", err)
+ }
+
+ endpoint, err := server.Listen(profiles.LocalListenSpec)
+ if err != nil {
+ t.Fatalf("Listen(%s) failed: %v", profiles.LocalListenSpec, err)
+ }
+ if err := server.ServeDispatcher("", dispatcher); err != nil {
+ t.Fatalf("Serve(%v) failed: %v", dispatcher, err)
+ }
+
+ // Create client stubs for talking to the server.
+ stubV1 := repository.ApplicationClient(naming.JoinAddressName(endpoint.String(), "search/v1"))
+
+ // Create example envelopes.
+ envelopeV1 := application.Envelope{
+ Args: []string{"--help"},
+ Env: []string{"DEBUG=1"},
+ Binary: "/veyron/name/of/binary",
+ }
+
+ if err := stubV1.Put(rt.R().NewContext(), []string{"media"}, envelopeV1); err != nil {
+ t.Fatalf("Put() failed: %v", err)
+ }
+
+ // There is content here now.
+ output, err := stubV1.Match(rt.R().NewContext(), []string{"media"})
+ if err != nil {
+ t.Fatalf("Match(%v) failed: %v", "media", err)
+ }
+ if !reflect.DeepEqual(envelopeV1, output) {
+ t.Fatalf("Incorrect output: expected %v, got %v", envelopeV1, output)
+ }
+
+ server.Stop()
+
+ // Setup and start a second application server in its place.
+ server, err = rt.R().NewServer()
+ if err != nil {
+ t.Fatalf("NewServer() failed: %v", err)
+ }
+ defer server.Stop()
+
+ dispatcher, err = NewDispatcher(storedir, nil)
+ if err != nil {
+ t.Fatalf("NewDispatcher() failed: %v", err)
+ }
+ endpoint, err = server.Listen(profiles.LocalListenSpec)
+ if err != nil {
+ t.Fatalf("Listen(%s) failed: %v", profiles.LocalListenSpec, err)
+ }
+ if err := server.ServeDispatcher("", dispatcher); err != nil {
+ t.Fatalf("Serve(%v) failed: %v", dispatcher, err)
+ }
+
+ stubV1 = repository.ApplicationClient(naming.JoinAddressName(endpoint.String(), "search/v1"))
+
+ output, err = stubV1.Match(rt.R().NewContext(), []string{"media"})
+ if err != nil {
+ t.Fatalf("Match(%v) failed: %v", "media", err)
+ }
+ if !reflect.DeepEqual(envelopeV1, output) {
+ t.Fatalf("Incorrect output: expected %v, got %v", envelopeV1, output)
+ }
+}
diff --git a/services/mgmt/profile/impl/dispatcher.go b/services/mgmt/profile/impl/dispatcher.go
index b806796..023685a 100644
--- a/services/mgmt/profile/impl/dispatcher.go
+++ b/services/mgmt/profile/impl/dispatcher.go
@@ -1,6 +1,8 @@
package impl
import (
+ "path/filepath"
+
"veyron.io/veyron/veyron/services/mgmt/repository"
"veyron.io/veyron/veyron/services/mgmt/lib/fs"
@@ -17,14 +19,14 @@
var _ ipc.Dispatcher = (*dispatcher)(nil)
-// NewDispatcher is the dispatcher factory.
-func NewDispatcher(name string, authorizer security.Authorizer) (*dispatcher, error) {
- // TODO(rjkroege@google.com): Use the config service.
- store, err := fs.NewMemstore("")
+// NewDispatcher is the dispatcher factory. storeDir is a path to a
+// directory in which the profile state is persisted.
+func NewDispatcher(storeDir string, authorizer security.Authorizer) (*dispatcher, error) {
+ store, err := fs.NewMemstore(filepath.Join(storeDir, "profilestate.db"))
if err != nil {
return nil, err
}
- return &dispatcher{store: store, storeRoot: name, auth: authorizer}, nil
+ return &dispatcher{store: store, storeRoot: storeDir, auth: authorizer}, nil
}
// DISPATCHER INTERFACE IMPLEMENTATION
diff --git a/services/mgmt/profile/impl/impl_test.go b/services/mgmt/profile/impl/impl_test.go
index 8d0a9e7..d0a4521 100644
--- a/services/mgmt/profile/impl/impl_test.go
+++ b/services/mgmt/profile/impl/impl_test.go
@@ -2,6 +2,7 @@
import (
"io/ioutil"
+ "os"
"reflect"
"testing"
@@ -29,9 +30,7 @@
// TestInterface tests that the implementation correctly implements
// the Profile interface.
func TestInterface(t *testing.T) {
- runtime := rt.Init()
- defer runtime.Cleanup()
-
+ runtime := rt.R()
ctx := runtime.NewContext()
// Setup and start the profile repository server.
@@ -41,11 +40,6 @@
}
defer server.Stop()
- // Setup and start the profile server.
- server, err = runtime.NewServer()
- if err != nil {
- t.Fatalf("NewServer() failed: %v", err)
- }
dir, prefix := "", ""
store, err := ioutil.TempDir(dir, prefix)
if err != nil {
@@ -109,3 +103,88 @@
t.Fatalf("Stop() failed: %v", err)
}
}
+
+func init() {
+ rt.Init()
+}
+
+func TestPreserveAcrossRestarts(t *testing.T) {
+ runtime := rt.R()
+ ctx := runtime.NewContext()
+
+ // Setup and start the profile repository server.
+ server, err := runtime.NewServer()
+ if err != nil {
+ t.Fatalf("NewServer() failed: %v", err)
+ }
+ defer server.Stop()
+
+ dir, prefix := "", ""
+ storedir, err := ioutil.TempDir(dir, prefix)
+ if err != nil {
+ t.Fatalf("TempDir(%q, %q) failed: %v", dir, prefix, err)
+ }
+ defer os.RemoveAll(storedir)
+
+ dispatcher, err := NewDispatcher(storedir, nil)
+ if err != nil {
+ t.Fatalf("NewDispatcher() failed: %v", err)
+ }
+ endpoint, err := server.Listen(profiles.LocalListenSpec)
+ if err != nil {
+ t.Fatalf("Listen(%s) failed: %v", profiles.LocalListenSpec, err)
+ }
+ if err := server.ServeDispatcher("", dispatcher); err != nil {
+ t.Fatalf("Serve failed: %v", err)
+ }
+ t.Logf("Profile repository at %v", endpoint)
+
+ // Create client stubs for talking to the server.
+ stub := repository.ProfileClient(naming.JoinAddressName(endpoint.String(), "linux/base"))
+
+ if err := stub.Put(ctx, spec); err != nil {
+ t.Fatalf("Put() failed: %v", err)
+ }
+
+ label, err := stub.Label(ctx)
+ if err != nil {
+ t.Fatalf("Label() failed: %v", err)
+ }
+ if label != spec.Label {
+ t.Fatalf("Unexpected output: expected %v, got %v", spec.Label, label)
+ }
+
+ // Stop the first server.
+ server.Stop()
+
+ // Setup and start a second server.
+ server, err = runtime.NewServer()
+ if err != nil {
+ t.Fatalf("NewServer() failed: %v", err)
+ }
+ defer server.Stop()
+
+ dispatcher, err = NewDispatcher(storedir, nil)
+ if err != nil {
+ t.Fatalf("NewDispatcher() failed: %v", err)
+ }
+ endpoint, err = server.Listen(profiles.LocalListenSpec)
+ if err != nil {
+ t.Fatalf("Listen(%s) failed: %v", profiles.LocalListenSpec, err)
+ }
+ if err = server.ServeDispatcher("", dispatcher); err != nil {
+ t.Fatalf("Serve failed: %v", err)
+ }
+
+ // Create client stubs for talking to the server.
+ stub = repository.ProfileClient(naming.JoinAddressName(endpoint.String(), "linux/base"))
+
+ // Label
+ label, err = stub.Label(ctx)
+ if err != nil {
+ t.Fatalf("Label() failed: %v", err)
+ }
+ if label != spec.Label {
+ t.Fatalf("Unexpected output: expected %v, got %v", spec.Label, label)
+ }
+}