[updates] install via needs directories
pkgfs no longer depends on Amber, instead Amber performs all of the
installation operations off of it's own back.
Change-Id: I8de8f98e2fc4094484d295db45b30d7e1d747667
diff --git a/garnet/go/src/amber/amberd/amberd.go b/garnet/go/src/amber/amberd/amberd.go
index 58891ea..f7cdc4b 100644
--- a/garnet/go/src/amber/amberd/amberd.go
+++ b/garnet/go/src/amber/amberd/amberd.go
@@ -67,7 +67,7 @@
var ctlSvc amber.ControlService
var evtSvc amber.EventsService
- d, err := daemon.NewDaemon(*store, "", "", &evtSvc)
+ d, err := daemon.NewDaemon(*store, "", "", "", &evtSvc)
if err != nil {
log.Fatalf("failed to start daemon: %s", err)
}
diff --git a/garnet/go/src/amber/control_server/control_server.go b/garnet/go/src/amber/control_server/control_server.go
index 5a45b7f..5174c66 100644
--- a/garnet/go/src/amber/control_server/control_server.go
+++ b/garnet/go/src/amber/control_server/control_server.go
@@ -75,13 +75,17 @@
func (c *ControlServer) GetUpdateComplete(name string, ver, mer *string) (zx.Channel, error) {
r, ch, e := zx.NewChannel(0)
if e != nil {
- log.Printf("Could not create channel")
+ log.Printf("getupdatecomplete: could not create channel")
// TODO(raggi): the client is just going to get peer closed, and no indication of why
- return zx.Channel(zx.HandleInvalid), e
+ return zx.Channel(zx.HandleInvalid), nil
}
if len(name) == 0 {
- return zx.Channel(zx.HandleInvalid), fmt.Errorf("No package name provided")
+ log.Printf("getupdatecomplete: invalid arguments: empty name")
+ ch.Handle().SignalPeer(0, zx.SignalUser0)
+ ch.Write([]byte(zx.ErrInvalidArgs.String()), []zx.Handle{}, 0)
+ ch.Close()
+ return r, nil
}
var (
@@ -97,6 +101,7 @@
}
go func() {
+ defer ch.Close()
c.daemon.UpdateIfStale()
root, length, err := c.daemon.MerkleFor(name, version, merkle)
@@ -104,56 +109,38 @@
log.Printf("control_server: could not get update for %s: %s", filepath.Join(name, version, merkle), err)
ch.Handle().SignalPeer(0, zx.SignalUser0)
ch.Write([]byte(err.Error()), []zx.Handle{}, 0)
- ch.Close()
return
}
if _, err := os.Stat(filepath.Join("/pkgfs/versions", root)); err == nil {
ch.Write([]byte(root), []zx.Handle{}, 0)
- ch.Close()
return
}
log.Printf("control_server: get update: %s", filepath.Join(name, version, merkle))
- c.daemon.AddWatch(root, func(root string, err error) {
- if os.IsExist(err) {
- log.Printf("control_server: %s already installed", filepath.Join(name, version, root))
- // signal success to the client
- err = nil
- }
- if err != nil {
- log.Printf("control_server: error downloading package: %s", err)
- ch.Handle().SignalPeer(0, zx.SignalUser0)
- ch.Write([]byte(err.Error()), []zx.Handle{}, 0)
- ch.Close()
- return
- }
+ err = c.daemon.GetPkg(root, length)
+ if os.IsExist(err) {
+ log.Printf("control_server: %s already installed", filepath.Join(name, version, root))
+ // signal success to the client
+ err = nil
+ }
+ if err != nil {
+ log.Printf("control_server: error downloading package: %s", err)
+ ch.Handle().SignalPeer(0, zx.SignalUser0)
+ ch.Write([]byte(err.Error()), []zx.Handle{}, 0)
+ } else {
ch.Write([]byte(root), []zx.Handle{}, 0)
- ch.Close()
- return
- })
-
- // errors are handled by the watcher callback
- c.daemon.GetPkg(root, length)
+ }
}()
-
return r, nil
}
func (c *ControlServer) PackagesActivated(merkle []string) error {
- log.Printf("control_server: packages activated %s", merkle)
- for _, m := range merkle {
- c.daemon.Activated(m)
- }
return nil
}
func (c *ControlServer) PackagesFailed(merkle []string, status int32, blobMerkle string) error {
- log.Printf("control_server: packages failed %s due to blob %s, status: %d", merkle, blobMerkle, status)
- for _, m := range merkle {
- c.daemon.Failed(m, zx.Status(status))
- }
return nil
}
@@ -174,13 +161,6 @@
}
func (c *ControlServer) GetBlob(merkle string) error {
- log.Printf("control_server: blob requested: %q", merkle)
- if !merklePat.MatchString(merkle) {
- return fmt.Errorf("%q is not a valid merkle root", merkle)
- }
-
- go c.daemon.GetBlob(merkle)
-
return nil
}
diff --git a/garnet/go/src/amber/daemon/activation_watcher.go b/garnet/go/src/amber/daemon/activation_watcher.go
deleted file mode 100644
index d821f97..0000000
--- a/garnet/go/src/amber/daemon/activation_watcher.go
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package daemon
-
-import (
- "sync"
-)
-
-type activationWatcher struct {
- mu sync.Mutex
- observers map[string][]func(string, error)
-}
-
-func (a *activationWatcher) addWatch(root string, f func(string, error)) {
- a.mu.Lock()
- defer a.mu.Unlock()
-
- if a.observers == nil {
- a.observers = make(map[string][]func(string, error))
- }
-
- a.observers[root] = append(a.observers[root], f)
-}
-
-func (a *activationWatcher) update(root string, err error) {
- a.mu.Lock()
- fs := a.observers[root]
- delete(a.observers, root)
- a.mu.Unlock()
-
- for _, f := range fs {
- f(root, err)
- }
-}
diff --git a/garnet/go/src/amber/daemon/daemon.go b/garnet/go/src/amber/daemon/daemon.go
index 2308e0b..f4d3fb1 100644
--- a/garnet/go/src/amber/daemon/daemon.go
+++ b/garnet/go/src/amber/daemon/daemon.go
@@ -25,6 +25,7 @@
const (
DefaultPkgInstallDir = "/pkgfs/install/pkg"
DefaultBlobInstallDir = "/pkgfs/install/blob"
+ DefaultPkgNeedsDir = "/pkgfs/needs/packages"
PackageGarbageDir = "/pkgfs/garbage"
)
@@ -32,27 +33,31 @@
store string
pkgInstallDir string
blobInstallDir string
+ pkgNeedsDir string
muSrcs sync.Mutex
srcs map[string]*source.Source
events *amber.EventsService
- aw activationWatcher
}
// NewDaemon creates a Daemon
-func NewDaemon(store, pkgInstallDir, blobInstallDir string, events *amber.EventsService) (*Daemon, error) {
+func NewDaemon(store, pkgInstallDir, blobInstallDir, pkgNeedsDir string, events *amber.EventsService) (*Daemon, error) {
if pkgInstallDir == "" {
pkgInstallDir = DefaultPkgInstallDir
}
if blobInstallDir == "" {
blobInstallDir = DefaultBlobInstallDir
}
+ if pkgNeedsDir == "" {
+ pkgNeedsDir = DefaultPkgNeedsDir
+ }
d := &Daemon{
store: store,
pkgInstallDir: pkgInstallDir,
blobInstallDir: blobInstallDir,
+ pkgNeedsDir: pkgNeedsDir,
srcs: make(map[string]*source.Source),
events: events,
}
@@ -394,28 +399,38 @@
err := d.fetchInto(merkle, length, d.pkgInstallDir)
if os.IsExist(err) {
- // Packages that already exist are simply "successful"
- d.aw.update(merkle, nil)
return nil
}
if err != nil {
- // errors fetching the package meta.far are terminal
- d.aw.update(merkle, err)
log.Printf("error fetching pkg %q: %s", merkle, err)
+ return err
}
- // In the non-error case, waiters are updated by activation.
- // XXX(raggi): note this is a potentially unbounded wait.
- return err
-}
+ needsDir, err := os.Open(filepath.Join(d.pkgNeedsDir, merkle))
+ if os.IsNotExist(err) {
+ // Package is fully installed already
+ return nil
+ }
+ defer needsDir.Close()
-// GetBlob is a blocking call which downloads the requested blob
-func (d *Daemon) GetBlob(merkle string) error {
- err := d.fetchInto(merkle, -1, d.blobInstallDir)
- d.aw.update(merkle, err)
- if err != nil && !os.IsExist(err) {
- log.Printf("error fetching blob %q: %s", merkle, err)
+ neededBlobs, err := needsDir.Readdirnames(-1)
+ if err != nil {
+ return err
+ }
+ for len(neededBlobs) > 0 {
+ for _, blob := range neededBlobs {
+ // TODO(raggi): switch to using the needs paths for install
+ err := d.fetchInto(blob, -1, d.blobInstallDir)
+ if err != nil {
+ return err
+ }
+ }
+
+ neededBlobs, err = needsDir.Readdirnames(-1)
+ if err != nil {
+ return err
+ }
}
return err
}
@@ -444,18 +459,6 @@
})
}
-func (d *Daemon) AddWatch(merkle string, f func(string, error)) {
- d.aw.addWatch(merkle, f)
-}
-
-func (d *Daemon) Activated(merkle string) {
- d.aw.update(merkle, nil)
-}
-
-func (d *Daemon) Failed(merkle string, status zx.Status) {
- d.aw.update(merkle, &zx.Error{Status: status})
-}
-
func (d *Daemon) GC() error {
// Garbage collection is done by trying to unlink a particular control
// file exposed by pkgfs.
diff --git a/garnet/go/src/amber/daemon/daemon_test.go b/garnet/go/src/amber/daemon/daemon_test.go
index 0f7d067..f46a6b4 100644
--- a/garnet/go/src/amber/daemon/daemon_test.go
+++ b/garnet/go/src/amber/daemon/daemon_test.go
@@ -29,7 +29,7 @@
}
defer os.RemoveAll(store)
- d, err := NewDaemon(store, "", "", nil)
+ d, err := NewDaemon(store, "", "", "", nil)
if err != nil {
panic(err)
}
@@ -209,8 +209,11 @@
blobsDir, err := ioutil.TempDir("", "amber-test-blobs")
panicerr(err)
defer os.RemoveAll(blobsDir)
+ pkgNeedsDir, err := ioutil.TempDir("", "amber-test-pkgneeds")
+ panicerr(err)
+ defer os.RemoveAll(pkgNeedsDir)
- d, err := NewDaemon(store, pkgsDir, blobsDir, nil)
+ d, err := NewDaemon(store, pkgsDir, blobsDir, pkgNeedsDir, nil)
panicerr(err)
err = d.AddSource(&amber.SourceConfig{
@@ -242,30 +245,17 @@
t.Errorf("merkleFor length: got %d, want %d", length, pkgBlobLength)
}
- // TODO(raggi): add coverage for error propagatation cases
- var rootSeen string
- var errSeen error
- d.AddWatch(pkgBlob, func(root string, err error) {
- rootSeen = root
- errSeen = err
- })
+ os.MkdirAll(filepath.Join(pkgNeedsDir, pkgBlob), 0755)
+ panicerr(ioutil.WriteFile(filepath.Join(pkgNeedsDir, pkgBlob, root1), []byte{}, 0644))
+
panicerr(d.GetPkg(pkgBlob, pkgBlobLength))
- d.Activated(pkgBlob)
-
- if rootSeen != pkgBlob {
- t.Errorf("activation: got %q, want %q", rootSeen, pkgBlob)
- }
- panicerr(errSeen)
-
c, err := ioutil.ReadFile(pkgsDir + "/" + pkgBlob)
panicerr(err)
if got := string(c); got != pkgContent {
t.Errorf("getpkg: got %q, want %q", got, pkgContent)
}
- panicerr(d.GetBlob(root1))
-
c, err = ioutil.ReadFile(blobsDir + "/" + root1)
panicerr(err)
if got, want := string(c), "first blob"; got != want {
@@ -341,8 +331,11 @@
blobsDir, err := ioutil.TempDir("", "amber-test-blobs")
panicerr(err)
defer os.RemoveAll(blobsDir)
+ pkgNeedsDir, err := ioutil.TempDir("", "amber-test-pkgneeds")
+ panicerr(err)
+ defer os.RemoveAll(pkgNeedsDir)
- d, err := NewDaemon(store, pkgsDir, blobsDir, nil)
+ d, err := NewDaemon(store, pkgsDir, blobsDir, pkgNeedsDir, nil)
panicerr(err)
err = d.AddSource(&amber.SourceConfig{
@@ -377,252 +370,20 @@
t.Errorf("merkleFor length: got %d, want %d", length, pkgBlobLength)
}
- // TODO(raggi): add coverage for error propagatation cases
- var rootSeen string
- var errSeen error
- d.AddWatch(pkgBlob, func(root string, err error) {
- rootSeen = root
- errSeen = err
- })
+ os.MkdirAll(filepath.Join(pkgNeedsDir, pkgBlob), 0755)
+ panicerr(ioutil.WriteFile(filepath.Join(pkgNeedsDir, pkgBlob, root1), []byte{}, 0644))
+
panicerr(d.GetPkg(pkgBlob, pkgBlobLength))
- d.Activated(pkgBlob)
-
- if rootSeen != pkgBlob {
- t.Errorf("activation: got %q, want %q", rootSeen, pkgBlob)
- }
- panicerr(errSeen)
-
c, err := ioutil.ReadFile(pkgsDir + "/" + pkgBlob)
panicerr(err)
if got := string(c); got != pkgContent {
t.Errorf("getpkg: got %q, want %q", got, pkgContent)
}
- panicerr(d.GetBlob(root1))
-
c, err = ioutil.ReadFile(blobsDir + "/" + root1)
panicerr(err)
if got, want := string(c), "first blob"; got != want {
t.Errorf("getblob: got %q, want %q", got, want)
}
}
-
-/***
-In the time between PKG-414 and when the tests in this file were re-enabled,
-the following case rotted because it is no longer possible to Mount
-filesystems in this way.
-
-// Mock blobfs that always returns "no space".
-
-type blobfsFile struct {
- pkgfs.UnsupportedFile
-}
-
-func (f blobfsFile) Truncate(size uint64) error {
- return fs.ErrNoSpace
-}
-
-var _ = fs.File(blobfsFile{})
-
-type blobfsDirectory struct {
- pkgfs.UnsupportedDirectory
-}
-
-func (d blobfsDirectory) Open(name string, flags fs.OpenFlags) (fs.File, fs.Directory, *fs.Remote, error) {
- return blobfsFile{}, nil, nil, nil
-}
-
-var _ = fs.Directory(blobfsDirectory{})
-
-type blobfsFilesystem struct {
- serveChannel zx.Channel
-}
-
-func (fs *blobfsFilesystem) Mount(path string) error {
- var err error
- err = os.MkdirAll(path, os.ModePerm)
- panicerr(err)
- parentFd, err := syscall.Open(path, syscall.O_ADMIN|syscall.O_DIRECTORY, 0777)
- panicerr(err)
- var rpcChan, mountChan zx.Channel
- rpcChan, mountChan, err = zx.NewChannel(0)
- panicerr(err)
- remote := zxio.DirectoryInterface(fidl.InterfaceRequest{Channel: mountChan})
- dirChan := zx.Channel(syscall.FDIOForFD(parentFd).Handles()[0])
- dir := zxio.DirectoryAdminInterface(fidl.InterfaceRequest{Channel: dirChan})
- panicerr(err)
- status, err := dir.Mount(remote)
- if zx.Status(status) != zx.ErrOk {
- panic(fmt.Sprintf("Mount error: %s", zx.Status(status)))
- }
- panicerr(err)
- fs.Serve(rpcChan)
- return nil
-}
-
-func (fs *blobfsFilesystem) Unmount() {
- // Just a test, let this be a no-op.
-}
-
-// Starts a Directory protocol RPC server on the given channel. Does not block.
-func (fs *blobfsFilesystem) Serve(c zx.Channel) error {
- // rpc.NewServer takes ownership of the Handle and will close it on error.
- vfs, err := rpc.NewServer(fs, zx.Handle(c))
- if err != nil {
- return fmt.Errorf("vfs server creation: %s", err)
- }
- fs.serveChannel = c
-
- // TODO(raggi): serve has no quit/shutdown path.
- for i := runtime.NumCPU(); i > 0; i-- {
- go vfs.Serve()
- }
- return nil
-}
-
-func (fs *blobfsFilesystem) Blockcount() int64 {
- return 0
-}
-
-func (fs *blobfsFilesystem) Blocksize() int64 {
- return 0
-}
-
-func (fs *blobfsFilesystem) Size() int64 {
- return 0
-}
-
-func (fs *blobfsFilesystem) Close() error {
- fs.Unmount()
- return nil
-}
-
-func (fs *blobfsFilesystem) RootDirectory() fs.Directory {
- return blobfsDirectory{}
-}
-
-func (fs *blobfsFilesystem) Type() string {
- return "blobfs"
-}
-
-func (fs *blobfsFilesystem) FreeSize() int64 {
- return 0
-}
-
-func (fs *blobfsFilesystem) DevicePath() string {
- return ""
-}
-
-var _ = fs.FileSystem(&blobfsFilesystem{})
-
-type eventsImpl struct{}
-
-var _ = amber.Events(eventsImpl{})
-
-func TestOutOfSpace(t *testing.T) {
- var err error
-
- // Fake blobfs that always returns fs.ErrNoSpace.
- blobfsRootPath, err := ioutil.TempDir("", "pkgfs-test-blobfs")
- defer os.RemoveAll(blobfsRootPath)
- panicerr(err)
-
- blobfsPath := filepath.Join(blobfsRootPath, "blobfs")
- var fs blobfsFilesystem
- fs.Mount(blobfsPath)
- defer fs.Unmount()
-
- // Set up pkgfs.
-
- indexPath, err := ioutil.TempDir("", "pkgfs-test-index")
- if err != nil {
- panic(err)
- }
- panicerr(err)
- defer os.RemoveAll(indexPath)
-
- pkgfs, err := pkgfs.New(indexPath, blobfsPath, amberer.NewAmberClient())
- panicerr(err)
-
- pkgfsDir, err := ioutil.TempDir("", "pkgfs-test-mount")
- panicerr(err)
- defer os.RemoveAll(pkgfsDir)
-
- go func() {
- if err := pkgfs.Mount(pkgfsDir); err != nil {
- panic(err)
- }
- }()
- defer pkgfs.Unmount()
-
- // Set up daemon.
-
- store, err := ioutil.TempDir("", "amber-test")
- panicerr(err)
- defer os.RemoveAll(store)
-
- installPkgDir := filepath.Join(pkgfsDir, "install/pkg")
- installBlobDir := filepath.Join(pkgfsDir, "install/blob")
- var evtSvc amber.EventsService
- d, err := NewDaemon(store, installPkgDir, installBlobDir, &evtSvc)
- panicerr(err)
-
- // Create a fake package and blob.
-
- // TODO(raggi): make this a real package instead, but that's a lot more setup
- pkgContent := "very fake package"
- pkgBlob, err := makeBlob(store, pkgContent)
- panicerr(err)
- root1Content := "first blob"
- root1Length := int64(len(root1Content))
- root1, err := makeBlob(store, root1Content)
- panicerr(err)
-
- // Add a source.
-
- repoDir, err := ioutil.TempDir("", "amber-test-repo")
- panicerr(err)
- defer os.RemoveAll(repoDir)
- repo := initRepo(repoDir, store, []string{pkgBlob, root1})
- keys, err := repo.RootKeys()
- panicerr(err)
-
- rootKey := keys[0]
- server := httptest.NewServer(http.FileServer(http.Dir(repoDir + "/repository")))
-
- // XXX(raggi): cleanup disabled because networking bug!
- // defer server.Close()
- // // so that the httptest server can close:
- // defer http.DefaultTransport.(*http.Transport).CloseIdleConnections()
-
- err = d.AddSource(&amber.SourceConfig{
- Id: "testing",
- RepoUrl: server.URL,
- BlobRepoUrl: server.URL + "/blobs",
- // TODO(raggi): fix keyconfig
- RootKeys: []amber.KeyConfig{
- {
- Type: rootKey.Type,
- Value: rootKey.Value.Public.String(),
- },
- },
- StatusConfig: &amber.StatusConfig{Enabled: true},
- })
- panicerr(err)
-
- // Fetch into daemon and check that the event was signaled.
- req, evtIfc, err := amber.NewEventsInterfaceRequest()
- panicerr(err)
- _, err = evtSvc.Add(eventsImpl{}, req.ToChannel(), nil)
- panicerr(err)
- err = d.fetchInto(root1, root1Length, installBlobDir)
- if e, ok := err.(zx.Error); ok && e.Status == zx.ErrNoSpace {
- // Expected.
- } else {
- panic(fmt.Sprintf("fetchInto returned unexpected error %s", err))
- }
- err = evtIfc.ExpectOnOutOfSpace()
- panicerr(err)
-}
-*/
diff --git a/garnet/go/src/amber/sys_update/sys_update.go b/garnet/go/src/amber/sys_update/sys_update.go
index c36b30b..755dc55 100644
--- a/garnet/go/src/amber/sys_update/sys_update.go
+++ b/garnet/go/src/amber/sys_update/sys_update.go
@@ -16,7 +16,6 @@
"path/filepath"
"regexp"
"strings"
- "sync"
"time"
"amber/atonce"
@@ -114,14 +113,7 @@
return err
}
- var w sync.WaitGroup
- w.Add(1)
- upMon.d.AddWatch(root, func(root string, e error) {
- err = e
- w.Done()
- })
- upMon.d.GetPkg(root, length)
- w.Wait()
+ err = upMon.d.GetPkg(root, length)
if err != nil {
log.Printf("sys_upd_mon: unable to fetch package update: %s", err)
return err
diff --git a/garnet/go/src/pmd/amberer/amberer.go b/garnet/go/src/pmd/amberer/amberer.go
deleted file mode 100644
index ed4597a..0000000
--- a/garnet/go/src/pmd/amberer/amberer.go
+++ /dev/null
@@ -1,108 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Amberer is a fire-and-forget auto-reconnecting proxy to the Amber Control Interface
-package amberer
-
-import (
- "app/context"
- "fidl/fuchsia/amber"
- "log"
- "sync"
- "syscall/zx"
-)
-
-type AmberClient interface {
- PackagesActivated(merkles []string)
- PackagesFailed(merkles []string, status zx.Status, blob_merkle string)
- GetBlob(merkle string)
-}
-
-type realAmberClient struct {
- mu sync.RWMutex
- proxy *amber.ControlInterface
-}
-
-func (am *realAmberClient) PackagesActivated(merkles []string) {
- go func() {
- amber, err := am.get()
- if err != nil {
- log.Printf("pkgfs: amber.PackagesActivated(%v) failed: %s", merkles, err)
- return
- }
-
- err = amber.PackagesActivated(merkles)
- if am.checkErr(err) {
- log.Printf("pkgfs: amber.PackagesActivated(%v) failed: %s", merkles, err)
- }
- }()
-}
-
-func (am *realAmberClient) PackagesFailed(merkles []string, status zx.Status, blobMerkle string) {
- go func() {
- amber, err := am.get()
- if err != nil {
- log.Printf("pkgfs: amber.PackagesFailed(%v, %s) failed: %s", merkles, blobMerkle, err)
- return
- }
-
- err = amber.PackagesFailed(merkles, int32(status), blobMerkle)
- if am.checkErr(err) {
- log.Printf("pkgfs: amber.PackagesFailed(%v, %s) failed: %s", merkles, blobMerkle, err)
- }
- }()
-}
-
-func (am *realAmberClient) GetBlob(merkle string) {
- amber, err := am.get()
- if err != nil {
- log.Printf("pkgfs: amber.GetBlob(%q) failed: %s", merkle, err)
- return
- }
-
- err = amber.GetBlob(merkle)
- if am.checkErr(err) {
- log.Printf("pkgfs: amber.GetBlob(%q) failed: %s", merkle, err)
- }
-}
-
-var _ AmberClient = &realAmberClient{}
-
-func NewAmberClient() AmberClient {
- return &realAmberClient{}
-}
-
-func (am *realAmberClient) get() (*amber.ControlInterface, error) {
- am.mu.RLock()
- var a = am.proxy
- am.mu.RUnlock()
-
- if a != nil {
- return a, nil
- }
-
- am.mu.Lock()
- defer am.mu.Unlock()
-
- req, pxy, err := amber.NewControlInterfaceRequest()
- if err != nil {
- return nil, err
- }
- context.CreateFromStartupInfo().ConnectToEnvService(req)
- am.proxy = pxy
- return pxy, nil
-}
-
-func (am *realAmberClient) checkErr(err error) bool {
- if err != nil {
- am.mu.Lock()
- if am.proxy != nil {
- am.proxy.Close()
- }
- am.proxy = nil
- am.mu.Unlock()
- return true
- }
- return false
-}
diff --git a/garnet/go/src/pmd/index/dynamic_index.go b/garnet/go/src/pmd/index/dynamic_index.go
index 4b977be..4fbde1c 100644
--- a/garnet/go/src/pmd/index/dynamic_index.go
+++ b/garnet/go/src/pmd/index/dynamic_index.go
@@ -16,7 +16,6 @@
"syscall/zx"
"fuchsia.googlesource.com/pm/pkg"
- "fuchsia.googlesource.com/pmd/amberer"
)
// DynamicIndex provides concurrency safe access to a dynamic index of packages and package metadata
@@ -25,9 +24,6 @@
static *StaticIndex
- // client to connect to amber
- amberClient amberer.AmberClient
-
// mu protects all following fields
mu sync.Mutex
@@ -45,17 +41,16 @@
}
// NewDynamic initializes an DynamicIndex with the given root path.
-func NewDynamic(root string, static *StaticIndex, am amberer.AmberClient) *DynamicIndex {
+func NewDynamic(root string, static *StaticIndex) *DynamicIndex {
// TODO(PKG-14): error is deliberately ignored. This should not be fatal to boot.
_ = os.MkdirAll(root, os.ModePerm)
return &DynamicIndex{
- root: root,
- static: static,
- roots: make(map[string]pkg.Package),
- installing: make(map[string]pkg.Package),
- needs: make(map[string]map[string]struct{}),
- waiting: make(map[string]map[string]struct{}),
- amberClient: am,
+ root: root,
+ static: static,
+ roots: make(map[string]pkg.Package),
+ installing: make(map[string]pkg.Package),
+ needs: make(map[string]map[string]struct{}),
+ waiting: make(map[string]map[string]struct{}),
}
}
@@ -160,8 +155,6 @@
for p := range ps {
pkgRoots = append(pkgRoots, p)
}
-
- idx.amberClient.PackagesFailed(pkgRoots, status, blobRoot)
}
// InstallingFailedForPackage removes an entry from the package installation index,
@@ -198,19 +191,6 @@
// We wait on all of the "needs", that is, all blobs that were not found on the
// system at the time of import.
idx.waiting[root] = needs
-
- // create a copy of the needs so we're concurrency safe
- cn := make([]string, 0, len(needs))
- for root := range needs {
- cn = append(cn, root)
- }
-
- log.Printf("asking amber to fetch %d needed blobs", len(cn))
- go func() {
- for _, root := range cn {
- idx.amberClient.GetBlob(root)
- }
- }()
return nil
}
@@ -317,11 +297,6 @@
}
func (idx *DynamicIndex) Notify(roots ...string) {
- if len(roots) == 0 {
- return
- }
-
- idx.amberClient.PackagesActivated(roots)
}
// GetRoot looks for a package by merkleroot, returning the matching package and
diff --git a/garnet/go/src/pmd/index/dynamic_index_test.go b/garnet/go/src/pmd/index/dynamic_index_test.go
index 099aeda..445cec6 100644
--- a/garnet/go/src/pmd/index/dynamic_index_test.go
+++ b/garnet/go/src/pmd/index/dynamic_index_test.go
@@ -15,41 +15,8 @@
"testing"
"fuchsia.googlesource.com/pm/pkg"
- "fuchsia.googlesource.com/pmd/amberer"
)
-type packageFailure struct {
- merkles []string
- status zx.Status
- blobMerkle string
-}
-
-type fakeAmberClient struct {
- activated []string
- failed []packageFailure
-}
-
-func (am *fakeAmberClient) PackagesActivated(merkles []string) {
- for _, m := range merkles {
- am.activated = append(am.activated, m)
- }
-}
-
-func (am *fakeAmberClient) PackagesFailed(merkles []string, status zx.Status, blobMerkle string) {
- am.failed = append(am.failed, packageFailure{merkles, status, blobMerkle})
-}
-
-func (am *fakeAmberClient) GetBlob(merkle string) {}
-
-func newFakeAmberClient() *fakeAmberClient {
- return &fakeAmberClient{
- activated: make([]string, 0),
- failed: make([]packageFailure, 0),
- }
-}
-
-var _ amberer.AmberClient = &fakeAmberClient{}
-
func TestList(t *testing.T) {
d, err := ioutil.TempDir("", t.Name())
if err != nil {
@@ -66,7 +33,7 @@
t.Fatal(err)
}
- idx := NewDynamic(d, NewStatic(), newFakeAmberClient())
+ idx := NewDynamic(d, NewStatic())
pkgs, err := idx.List()
if err != nil {
t.Fatal(err)
@@ -122,7 +89,7 @@
t.Fatal(err)
}
- idx := NewDynamic(d, NewStatic(), newFakeAmberClient())
+ idx := NewDynamic(d, NewStatic())
err = idx.Add(pkg.Package{Name: "foo", Version: "0"}, "abc")
if err != nil {
@@ -165,8 +132,7 @@
t.Fatal(err)
}
- am := newFakeAmberClient()
- idx := NewDynamic(d, NewStatic(), am)
+ idx := NewDynamic(d, NewStatic())
// New package, no blobs pre-installed.
{
@@ -214,11 +180,6 @@
t.Errorf("got %q, want %q", idx.needs, wantNeeds)
}
- wantActivated := []string{}
- if !reflect.DeepEqual(am.activated, wantActivated) {
- t.Errorf("got %q, want %q", am.activated, wantActivated)
- }
-
// Fulfill other blob. Package is done and appears in index.
idx.Fulfill("blob2")
if _, ok := idx.waiting["root1"]; ok {
@@ -232,10 +193,6 @@
t.Errorf("root1 was not deleted from installing")
}
- wantActivated = []string{"root1"}
- if !reflect.DeepEqual(am.activated, wantActivated) {
- t.Errorf("got %q, want %q", am.activated, wantActivated)
- }
paths, err := filepath.Glob(filepath.Join(d, "packages/*/*"))
if err != nil {
t.Fatal(err)
@@ -280,17 +237,6 @@
// Fail blob with error. Causes package failure to be signaled.
idx.InstallingFailedForBlob("blob4", zx.ErrNoSpace)
- wantFailed := []packageFailure{
- {
- merkles: []string{"root2"},
- status: zx.ErrNoSpace,
- blobMerkle: "blob4",
- },
- }
- if !reflect.DeepEqual(am.failed, wantFailed) {
- t.Errorf("got %v, want %v", am.failed, wantFailed)
- }
-
// Fulfill blob. Now the package should be marked finished.
idx.Fulfill("blob4")
@@ -305,10 +251,6 @@
t.Errorf("root2 was not deleted from installing")
}
- wantActivated := []string{"root1", "root2"}
- if !reflect.DeepEqual(am.activated, wantActivated) {
- t.Errorf("got %q, want %q", am.activated, wantActivated)
- }
paths, err := filepath.Glob(filepath.Join(d, "packages/*/*"))
if err != nil {
t.Fatal(err)
diff --git a/garnet/go/src/pmd/pkgfs/needs_directory.go b/garnet/go/src/pmd/pkgfs/needs_directory.go
index 6ca8fc98..f47e3c7 100644
--- a/garnet/go/src/pmd/pkgfs/needs_directory.go
+++ b/garnet/go/src/pmd/pkgfs/needs_directory.go
@@ -60,7 +60,7 @@
}
func (d *needsRoot) Read() ([]fs.Dirent, error) {
- return []fs.Dirent{dirDirEnt("blobs")}, nil
+ return []fs.Dirent{dirDirEnt("blobs"), dirDirEnt("packages")}, nil
}
func (d *needsRoot) Stat() (int64, time.Time, time.Time, error) {
diff --git a/garnet/go/src/pmd/pkgfs/pkgfs.go b/garnet/go/src/pmd/pkgfs/pkgfs.go
index 68c1ecd2..eb7b983 100644
--- a/garnet/go/src/pmd/pkgfs/pkgfs.go
+++ b/garnet/go/src/pmd/pkgfs/pkgfs.go
@@ -27,7 +27,6 @@
"thinfs/zircon/rpc"
"fuchsia.googlesource.com/pm/pkg"
- "fuchsia.googlesource.com/pmd/amberer"
"fuchsia.googlesource.com/pmd/blobfs"
"fuchsia.googlesource.com/pmd/index"
)
@@ -43,7 +42,7 @@
}
// New initializes a new pkgfs filesystem server
-func New(indexDir string, blobDir string, am amberer.AmberClient) (*Filesystem, error) {
+func New(indexDir string, blobDir string) (*Filesystem, error) {
bm, err := blobfs.New(blobDir)
if err != nil {
return nil, fmt.Errorf("pkgfs: open blobfs: %s", err)
@@ -52,7 +51,7 @@
static := index.NewStatic()
f := &Filesystem{
static: static,
- index: index.NewDynamic(indexDir, static, am),
+ index: index.NewDynamic(indexDir, static),
blobfs: bm,
mountInfo: mountInfo{
parentFd: -1,
diff --git a/garnet/go/src/pmd/pkgfs/pkgfs_test.go b/garnet/go/src/pmd/pkgfs/pkgfs_test.go
index 3637e13..a730c00 100644
--- a/garnet/go/src/pmd/pkgfs/pkgfs_test.go
+++ b/garnet/go/src/pmd/pkgfs/pkgfs_test.go
@@ -25,7 +25,6 @@
"fuchsia.googlesource.com/merkle"
"fuchsia.googlesource.com/pm/build"
- "fuchsia.googlesource.com/pmd/amberer"
)
// Adding a file to /in writes the file to blobfs
@@ -123,7 +122,7 @@
}
defer os.RemoveAll(d)
- pkgfs, err := New(indexPath, blobfsPath, amberer.NewAmberClient())
+ pkgfs, err := New(indexPath, blobfsPath)
if err != nil {
panic(err)
}
diff --git a/garnet/go/src/pmd/pkgsvr/pkgsvr.go b/garnet/go/src/pmd/pkgsvr/pkgsvr.go
index d95bb77..281b03e 100644
--- a/garnet/go/src/pmd/pkgsvr/pkgsvr.go
+++ b/garnet/go/src/pmd/pkgsvr/pkgsvr.go
@@ -11,7 +11,6 @@
"app/context"
- "fuchsia.googlesource.com/pmd/amberer"
"fuchsia.googlesource.com/pmd/pkgfs"
)
@@ -29,7 +28,7 @@
sysPkg := flag.Arg(0)
// TODO(raggi): Reading from the index should be delayed until after verified boot completion
- fs, err := pkgfs.New(*index, *blob, amberer.NewAmberClient())
+ fs, err := pkgfs.New(*index, *blob)
if err != nil {
log.Fatalf("pkgfs: initialization failed: %s", err)
}