func startLockServer(ctx *context.T, configDir string) (func(), error) { blessings, _ := v23.GetPrincipal(ctx).BlessingStore().Default() lockNhSuffix := fmt.Sprint(blessings) // Start a local mounttable where the lock server would be // mounted, and make this mounttable visible in the local // neighborhood. mtName, stopMT, err := locklib.StartMounttable(ctx, configDir, locklib.LockNhPrefix+lockNhSuffix) if err != nil { return nil, err } ctx, _, err = v23.WithNewNamespace(ctx, mtName) if err != nil { stopMT() return nil, err } ctx, cancel := context.WithCancel(ctx) _, server, err := v23.WithNewServer(ctx, lockObjectName(ctx), newLock(), security.DefaultAuthorizer()) if err != nil { stopMT() return nil, err } stopLock := func() { cancel() vlog.Infof("Stopping lock server...") <-server.Closed() vlog.Infof("Stopped lock server...") stopMT() } vlog.Infof("Started lock server\n") vlog.Infof("ENDPOINT: %v\n", server.Status().Endpoints[0].Name()) return stopLock, nil }
func startUnclaimedLockServer(ctx *context.T, configDir string) (<-chan struct{}, func(), error) { // Start a local mounttable where the unclaimed lock server would // be mounted, and make this mounttable visible in the local // neighborhood. mtName, stopMT, err := locklib.StartMounttable(ctx, configDir, locklib.LockNhPrefix+unclaimedLockNhSuffix) if err != nil { return nil, nil, err } ctx, _, err = v23.WithNewNamespace(ctx, mtName) if err != nil { stopMT() return nil, nil, err } claimed := make(chan struct{}) ctx, cancel := context.WithCancel(ctx) _, server, err := v23.WithNewServer(ctx, lockObjectName(ctx), newUnclaimedLock(claimed, configDir), security.AllowEveryone()) if err != nil { stopMT() return nil, nil, err } stopUnclaimedLock := func() { cancel() vlog.Infof("Stopping unclaimed lock server...") <-server.Closed() vlog.Infof("Stopped unclaimed lock server...") stopMT() } vlog.Infof("Started unclaimed lock server\n") vlog.Infof("ENDPOINT: %v\n", server.Status().Endpoints[0].Name()) return claimed, stopUnclaimedLock, nil }
func (ul *unclaimedLock) Claim(ctx *context.T, call rpc.ServerCall, name string) (security.Blessings, error) { vlog.Infof("Claim called by %q", call.Security().RemoteBlessings()) if strings.ContainsAny(name, security.ChainSeparator) { // TODO(ataly, ashankar): We have to error out in this case because of the current // neighborhood setup wherein the neighborhood-name of a claimed lock's mounttable is // the same as the locks's name. Since neighborhood-names aren't allowed to contain // slashes, we have to disallow slashes in the lock name as well. return security.Blessings{}, NewErrInvalidLockName(ctx, name, security.ChainSeparator) } var ( principal = v23.GetPrincipal(ctx) origDefault, _ = principal.BlessingStore().Default() restore = func() error { // TODO(ataly): Remove roots of current default blessing if needed // (i.e., if current default != origDefault). if err := principal.BlessingStore().SetDefault(origDefault); err != nil { return verror.Convert(verror.ErrInternal, ctx, err) } return nil } ) defer ul.mu.Unlock() ul.mu.Lock() if ul.claimed == nil { return security.Blessings{}, NewErrLockAlreadyClaimed(ctx) } keyBlessing, err := ul.makeKey(principal, name, call.Security().RemoteBlessings().PublicKey()) if err != nil { restore() return security.Blessings{}, verror.Convert(verror.ErrInternal, ctx, err) } // Create a file in the config directory to indicate that lock has been claimed. f, err := os.Create(filepath.Join(ul.configDir, claimFileName)) if err != nil { restore() return security.Blessings{}, verror.Convert(verror.ErrInternal, ctx, err) } f.Close() close(ul.claimed) ul.claimed = nil vlog.Infof("Lock successfullly claimed with name %q", name) return keyBlessing, nil }
func (omxHandler) Display(ctx *context.T, mimetype string, r io.ReadCloser) (func(), error) { defer r.Close() tmp, err := ioutil.TempFile("", "") if err != nil { return nil, err } if _, err := io.Copy(tmp, r); err != nil { os.Remove(tmp.Name()) return nil, err } tmp.Close() args := []string{ "-b", tmp.Name(), } vlog.Infof("Running: omxplayer %s", strings.Join(args, " ")) cmd := exec.Command("omxplayer", args...) cmd.Stdin = r cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr if err := cmd.Start(); err != nil { return nil, err } return func() { if err := cmd.Process.Kill(); err != nil { vlog.Errorf("Could not kill omx: %v", err) } cmd.Wait() os.Remove(tmp.Name()) }, nil }
// StartMounttable starts a local mounttable server with an authorization // policy that allows all principals to "Resolve" names, but restricts all // other operations to the principal specified by the provided context. // // The mounttable makes itself visible in the local neighborhood under the // name LockNeighborhoodPrefix + <nhName>. // // Returns the endpoint of the mounttable server and a callback to // be invoked to shutdown the mounttable server on success, or an error // on failure. func StartMounttable(ctx *context.T, configDir string, nhName string) (string, func(), error) { if len(configDir) == 0 { return "", nil, errors.New("could not start mounttable, config directory not provided") } permFilePath := filepath.Join(configDir, permsFile) if err := initPermissions(permFilePath); err != nil { return "", nil, fmt.Errorf("could not initialize permissions file (%v) for mounttable: %v", permFilePath, err) } mtName, stopMT, err := mounttablelib.StartServers(ctx, v23.GetListenSpec(ctx), "", nhName, permFilePath, "", "mounttable") if err != nil { vlog.Errorf("mounttablelib.StartServers failed: %v", err) return "", nil, err } vlog.Infof("Started local mounttable at: %v", mtName) return mtName, func() { vlog.Infof("Stopping mounttable...") stopMT() vlog.Infof("Stopped mounttable.") }, nil }
func (vlcHandler) Display(ctx *context.T, mimetype string, r io.ReadCloser) (func(), error) { defer r.Close() tmp, err := ioutil.TempFile("", "") if err != nil { return nil, err } if _, err := io.Copy(tmp, r); err != nil { os.Remove(tmp.Name()) return nil, err } tmp.Close() args := []string{ "--no-video-title-show", "--fullscreen", "--x11-display", ":0", tmp.Name(), "vlc://quit", } if strings.HasPrefix(mimetype, "audio/") { args = append([]string{"--audio-visual=visual"}, args...) } vlog.Infof("Running: vlc %s", strings.Join(args, " ")) cmd := exec.Command("vlc", args...) cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr if err := cmd.Start(); err != nil { return nil, err } return func() { if err := cmd.Process.Kill(); err != nil { vlog.Errorf("Could not kill vlc: %v", err) } cmd.Wait() os.Remove(tmp.Name()) }, nil }
// Init initializes the JNI code with the given Java environment. This method // must be called from the main Java thread. func Init(env jutil.Env) error { if err := jbt.Init(env); err != nil { return err } if err := jble.Init(env); err != nil { // The BLE protocol isn't always compiled in, so don't fail if it // isn't available. vlog.Infof("Unable to initialize BLE protocol: %v", err) } // Cache global references to all Java classes used by the package. This is // necessary because JNI gets access to the class loader only in the system // thread, so we aren't able to invoke FindClass in other threads. var err error jAddressChooserImplClass, err = jutil.JFindClass(env, "io/v/impl/google/rpc/AddressChooserImpl") if err != nil { return err } jServerImplClass, err = jutil.JFindClass(env, "io/v/impl/google/rpc/ServerImpl") if err != nil { return err } jClientImplClass, err = jutil.JFindClass(env, "io/v/impl/google/rpc/ClientImpl") if err != nil { return err } jClientCallImplClass, err = jutil.JFindClass(env, "io/v/impl/google/rpc/ClientCallImpl") if err != nil { return err } jStreamServerCallImplClass, err = jutil.JFindClass(env, "io/v/impl/google/rpc/StreamServerCallImpl") if err != nil { return err } jServerCallImplClass, err = jutil.JFindClass(env, "io/v/impl/google/rpc/ServerCallImpl") if err != nil { return err } jStreamImplClass, err = jutil.JFindClass(env, "io/v/impl/google/rpc/StreamImpl") if err != nil { return err } jServerRPCHelperClass, err = jutil.JFindClass(env, "io/v/impl/google/rpc/ServerRPCHelper") if err != nil { return err } jInvokerClass, err = jutil.JFindClass(env, "io/v/v23/rpc/Invoker") if err != nil { return err } jListenSpecClass, err = jutil.JFindClass(env, "io/v/v23/rpc/ListenSpec") if err != nil { return err } jListenSpecAddressClass, err = jutil.JFindClass(env, "io/v/v23/rpc/ListenSpec$Address") if err != nil { return err } jPublisherEntryClass, err = jutil.JFindClass(env, "io/v/v23/rpc/PublisherEntry") if err != nil { return err } jNetworkAddressClass, err = jutil.JFindClass(env, "io/v/v23/rpc/NetworkAddress") if err != nil { return err } jProxyStatusClass, err = jutil.JFindClass(env, "io/v/v23/rpc/ProxyStatus") if err != nil { return err } jReflectInvokerClass, err = jutil.JFindClass(env, "io/v/v23/rpc/ReflectInvoker") if err != nil { return err } jServerStatusClass, err = jutil.JFindClass(env, "io/v/v23/rpc/ServerStatus") if err != nil { return err } jServerStateClass, err = jutil.JFindClass(env, "io/v/v23/rpc/ServerState") if err != nil { return err } jOptionDefsClass, err = jutil.JFindClass(env, "io/v/v23/OptionDefs") if err != nil { return err } jEndpointClass, err = jutil.JFindClass(env, "io/v/v23/naming/Endpoint") if err != nil { return err } jInterfaceClass, err = jutil.JFindClass(env, "io/v/v23/vdlroot/signature/Interface") if err != nil { return err } jMethodClass, err = jutil.JFindClass(env, "io/v/v23/vdlroot/signature/Method") if err != nil { return err } jGlobReplyClass, err = jutil.JFindClass(env, "io/v/v23/naming/GlobReply") if err != nil { return err } jObjectClass, err = jutil.JFindClass(env, "java/lang/Object") if err != nil { return err } return nil }
func (l *lockImpl) Status(ctx *context.T, call rpc.ServerCall) (lock.LockStatus, error) { remoteBlessingNames, _ := security.RemoteBlessingNames(ctx, call.Security()) vlog.Infof("Status called by %q", remoteBlessingNames) return l.hw.Status(), nil }
func (l *lockImpl) Unlock(ctx *context.T, call rpc.ServerCall) error { remoteBlessingNames, _ := security.RemoteBlessingNames(ctx, call.Security()) vlog.Infof("Unlock called by %q", remoteBlessingNames) return l.hw.SetStatus(lock.Unlocked) }