func (dc *DaemonConfig) getMounted() (map[string]*storage.Mount, map[string]int, error) { mounts := map[string]*storage.Mount{} counts := map[string]int{} now := time.Now() // XXX this loop will indefinitely run if the docker service is down. // This is intentional to ensure we don't take any action when docker is down. for { dockerClient, err := client.NewEnvClient() if err != nil { return nil, nil, errored.Errorf("Could not initiate docker client").Combine(err) } containers, err := dockerClient.ContainerList(context.Background(), types.ContainerListOptions{}) if err != nil { if now.Sub(time.Now()) > dc.Global.Timeout { panic("Cannot contact docker") } logrus.Error(errored.Errorf("Could not query docker; retrying").Combine(err)) time.Sleep(time.Second) continue } for _, container := range containers { if container.State == "running" { for _, mount := range container.Mounts { if mount.Driver == dc.PluginName { mounts[mount.Name] = nil counts[mount.Name]++ } } } } break } for driverName := range backend.MountDrivers { cd, err := backend.NewMountDriver(driverName, dc.Global.MountPath) if err != nil { return nil, nil, err } mounted, err := cd.Mounted(dc.Global.Timeout) if err != nil { return nil, nil, err } for _, mount := range mounted { logrus.Debugf("Refreshing existing mount for %q: %v", mount.Volume.Name, *mount) mounts[mount.Volume.Name] = mount } } return mounts, counts, nil }
// GetStorageParameters accepts a Volume API request and turns it into several internal structs. func (a *API) GetStorageParameters(uc *Volume) (storage.MountDriver, *config.Volume, storage.DriverOptions, error) { driverOpts := storage.DriverOptions{} volConfig, err := a.Client.GetVolume(uc.Policy, uc.Name) if err != nil { return nil, nil, driverOpts, err } driver, err := backend.NewMountDriver(volConfig.Backends.Mount, (*a.Global).MountPath) if err != nil { return nil, nil, driverOpts, errors.GetDriver.Combine(err) } driverOpts, err = volConfig.ToDriverOptions((*a.Global).Timeout) if err != nil { return nil, nil, driverOpts, errors.UnmarshalRequest.Combine(err) } return driver, volConfig, driverOpts, nil }
func (cfg *Volume) validateBackends() error { // We use a few dummy variables to ensure that global configuration is // not needed in the storage drivers, that the validation does not fail // because of it. do, err := cfg.ToDriverOptions(time.Second) if err != nil { return err } if cfg.Backends.CRUD != "" { crud, err := backend.NewCRUDDriver(cfg.Backends.CRUD) if err != nil { return err } if err := crud.Validate(&do); err != nil { return err } } mnt, err := backend.NewMountDriver(cfg.Backends.Mount, backend.MountPath) if err != nil { return err } if err := mnt.Validate(&do); err != nil { return err } if cfg.Backends.Snapshot != "" { snapshot, err := backend.NewSnapshotDriver(cfg.Backends.Snapshot) if err != nil { return err } if err := snapshot.Validate(&do); err != nil { return err } } return nil }