func (r *router) volumeDetachAll( ctx types.Context, w http.ResponseWriter, req *http.Request, store types.Store) error { var ( taskIDs []int tasks = map[string]*types.Task{} opts = &types.VolumesOpts{Opts: store} reply types.ServiceVolumeMap = map[string]types.VolumeMap{} replyRWL = &sync.Mutex{} ) for service := range services.StorageServices(ctx) { run := func( ctx types.Context, svc types.StorageService) (interface{}, error) { ctx = context.WithStorageService(ctx, svc) if _, ok := context.InstanceID(ctx); !ok { return nil, utils.NewMissingInstanceIDError(service.Name()) } var err error if ctx, err = context.WithStorageSession(ctx); err != nil { return nil, err } driver := svc.Driver() volumes, err := driver.Volumes(ctx, opts) if err != nil { return nil, err } // check here var volumeMap types.VolumeMap = map[string]*types.Volume{} defer func() { if len(volumeMap) > 0 { replyRWL.Lock() defer replyRWL.Unlock() reply[service.Name()] = volumeMap } }() for _, volume := range volumes { v, err := driver.VolumeDetach( ctx, volume.ID, &types.VolumeDetachOpts{ Force: store.GetBool("force"), Opts: store, }) if err != nil { return nil, err } if err != nil { return nil, err } if v == nil { continue } if OnVolume != nil { ok, err := OnVolume(ctx, req, store, v) if err != nil { return nil, err } if !ok { return nil, utils.NewNotFoundError(v.ID) } } if v.AttachmentState == 0 { v.AttachmentState = types.VolumeAvailable } volumeMap[v.ID] = v } return nil, nil } task := service.TaskExecute(ctx, run, nil) taskIDs = append(taskIDs, task.ID) tasks[service.Name()] = task } run := func(ctx types.Context) (interface{}, error) { services.TaskWaitAll(ctx, taskIDs...) for _, v := range tasks { if v.Error != nil { return nil, utils.NewBatchProcessErr(reply, v.Error) } } return reply, nil } return httputils.WriteTask( ctx, r.config, w, store, services.TaskExecute(ctx, run, schema.ServiceVolumeMapSchema), http.StatusResetContent) }
func (r *router) snapshots( ctx types.Context, w http.ResponseWriter, req *http.Request, store types.Store) error { var ( tasks = map[string]*types.Task{} taskIDs []int reply = types.ServiceSnapshotMap{} ) for service := range services.StorageServices(ctx) { run := func( ctx types.Context, svc types.StorageService) (interface{}, error) { ctx = context.WithStorageService(ctx, svc) var err error if ctx, err = context.WithStorageSession(ctx); err != nil { return nil, err } objs, err := svc.Driver().Snapshots(ctx, store) if err != nil { return nil, err } objMap := map[string]*types.Snapshot{} for _, obj := range objs { objMap[obj.ID] = obj } return objMap, nil } task := service.TaskExecute(ctx, run, schema.SnapshotMapSchema) taskIDs = append(taskIDs, task.ID) tasks[service.Name()] = task } run := func(ctx types.Context) (interface{}, error) { services.TaskWaitAll(ctx, taskIDs...) for k, v := range tasks { if v.Error != nil { return nil, utils.NewBatchProcessErr(reply, v.Error) } objMap, ok := v.Result.(map[string]*types.Snapshot) if !ok { return nil, utils.NewBatchProcessErr( reply, goof.New("error casting to []*types.Snapshot")) } reply[k] = objMap } return reply, nil } return httputils.WriteTask( ctx, r.config, w, store, services.TaskExecute(ctx, run, schema.ServiceSnapshotMapSchema), http.StatusOK) }
func (r *router) volumes( ctx types.Context, w http.ResponseWriter, req *http.Request, store types.Store) error { filter, err := parseFilter(store) if err != nil { return err } if filter != nil { store.Set("filter", filter) } var ( tasks = map[string]*types.Task{} taskIDs []int opts = &types.VolumesOpts{ Attachments: store.GetAttachments(), Opts: store, } reply = types.ServiceVolumeMap{} ) for service := range services.StorageServices(ctx) { run := func( ctx types.Context, svc types.StorageService) (interface{}, error) { ctx = context.WithStorageService(ctx, svc) var err error if ctx, err = context.WithStorageSession(ctx); err != nil { return nil, err } return getFilteredVolumes(ctx, req, store, svc, opts, filter) } task := service.TaskExecute(ctx, run, schema.VolumeMapSchema) taskIDs = append(taskIDs, task.ID) tasks[service.Name()] = task } run := func(ctx types.Context) (interface{}, error) { services.TaskWaitAll(ctx, taskIDs...) for k, v := range tasks { if v.Error != nil { return nil, utils.NewBatchProcessErr(reply, v.Error) } objMap, ok := v.Result.(types.VolumeMap) if !ok { return nil, utils.NewBatchProcessErr( reply, goof.New("error casting to types.VolumeMap")) } reply[k] = objMap } return reply, nil } return httputils.WriteTask( ctx, r.config, w, store, services.TaskExecute(ctx, run, schema.ServiceVolumeMapSchema), http.StatusOK) }