func (d *driver) unmount(w http.ResponseWriter, r *http.Request) { method := "unmount" request, err := d.decode(method, w, r) if err != nil { return } volInfo, err := d.volFromName(request.Name) if err != nil { e := d.volNotFound(method, request.Name, err, w) json.NewEncoder(w).Encode(&volumeResponse{Err: e.Error()}) return } v, err := volume.Get(d.name) if err != nil { json.NewEncoder(w).Encode(&volumeResponse{Err: err.Error()}) return } err = v.Detach(volInfo.vol.ID) if err != nil { d.logReq(request.Name, method).Warnf("%s", err.Error()) json.NewEncoder(w).Encode(&volumeResponse{Err: err.Error()}) return } d.emptyResponse(w) }
func Init(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (graphdriver.Driver, error) { var volumeDriver string for _, option := range options { key, val, err := parsers.ParseKeyValueOpt(option) if err != nil { return nil, err } switch key { case Layer0VolumeDriver: volumeDriver = val default: return nil, fmt.Errorf("Unknown option %s\n", key) } } log.Infof("Layer0 volume driver: %v", volumeDriver) volDriver, err := volume.Get(volumeDriver) if err != nil { return nil, err } ov, err := overlay.Init(home, options, uidMaps, gidMaps) if err != nil { volDriver.Shutdown() return nil, err } d := &Layer0{ Driver: ov, home: home, volumes: make(map[string]*Layer0Vol), volDriver: volDriver, } return d, nil }
func TestAll(t *testing.T) { /* cmd := exec.Command("dd", "if=/dev/zero", "of=/tmp/x", "bs=1M", "count=100") err := cmd.Run() if err != nil { t.Fatalf("Failed to create file: %v", err) } cmd = exec.Command("/sbin/mkfs.btrfs", "/tmp/x") err = cmd.Run() if err != nil { t.Fatalf("Failed to create btrfs:%v", err) } err = os.MkdirAll("/tmp/btrfs_test", 0755) if err != nil { t.Fatalf("Failed to create mkdir: %v", err) } err = syscall.Mount("/tmp/x", "/tmp/btrfs_test", "btrfs", syscall.MS_NODEV, "") if err != nil { t.Fatalf("Failed to mount btrfs: %v", err) } */ _, err := volume.New(Name, volume.DriverParams{RootParam: "/tmp/btrfs_test"}) if err != nil { t.Fatalf("Failed to initialize Driver: %v", err) } d, err := volume.Get(Name) if err != nil { t.Fatalf("Failed to initialize Volume Driver: %v", err) } ctx := test.NewContext(d) ctx.Filesystem = api.FsBtrfs test.Run(t, ctx) }
func (d *driver) mount(w http.ResponseWriter, r *http.Request) { var response volumePathResponse method := "mount" request, err := d.decode(method, w, r) if err != nil { return } volInfo, err := d.volFromName(request.Name) if err != nil { e := d.volNotFound(method, request.Name, err, w) json.NewEncoder(w).Encode(&volumePathResponse{Err: e.Error()}) return } response.Mountpoint = fmt.Sprintf("/mnt/%s", request.Name) os.MkdirAll(response.Mountpoint, 0755) v, err := volume.Get(d.name) if err != nil { json.NewEncoder(w).Encode(&volumePathResponse{Err: err.Error()}) return } path, err := v.Attach(volInfo.vol.ID) if err != nil { json.NewEncoder(w).Encode(&volumePathResponse{Err: err.Error()}) return } response.Mountpoint = path d.logReq(method, request.Name).Debugf("response %v", path) json.NewEncoder(w).Encode(&response) }
func (vd *volApi) inspect(w http.ResponseWriter, r *http.Request) { var err error var volumeID string method := "inspect" d, err := volume.Get(vd.name) if err != nil { notFound(w, r) return } if volumeID, err = vd.parseVolumeID(r); err != nil { e := fmt.Errorf("Failed to parse parse volumeID: %s", err.Error()) vd.sendError(vd.name, method, w, e.Error(), http.StatusBadRequest) return } vd.logRequest(method, string(volumeID)).Infoln("") dk, err := d.Inspect([]string{volumeID}) if err != nil { vd.sendError(vd.name, method, w, err.Error(), http.StatusNotFound) return } json.NewEncoder(w).Encode(dk) }
func (vd *volApi) alerts(w http.ResponseWriter, r *http.Request) { var volumeID api.VolumeID var err error method := "stats" if volumeID, err = vd.parseVolumeID(r); err != nil { e := fmt.Errorf("Failed to parse parse volumeID: %s", err.Error()) vd.sendError(vd.name, method, w, e.Error(), http.StatusBadRequest) return } d, err := volume.Get(vd.name) if err != nil { notFound(w, r) return } alerts, err := d.Alerts(volumeID) if err != nil { e := fmt.Errorf("Failed to get alerts: %s", err.Error()) vd.sendError(vd.name, method, w, e.Error(), http.StatusBadRequest) return } json.NewEncoder(w).Encode(alerts) }
func (vd *volApi) snap(w http.ResponseWriter, r *http.Request) { var snapReq api.SnapCreateRequest var snapRes api.SnapCreateResponse method := "snap" if err := json.NewDecoder(r.Body).Decode(&snapReq); err != nil { vd.sendError(vd.name, method, w, err.Error(), http.StatusBadRequest) return } d, err := volume.Get(vd.name) if err != nil { notFound(w, r) return } vd.logRequest(method, string(snapReq.Id)).Infoln("") id, err := d.Snapshot(snapReq.Id, snapReq.Readonly, snapReq.Locator) snapRes.VolumeCreateResponse = &api.VolumeCreateResponse{ Id: id, VolumeResponse: &api.VolumeResponse{ Error: responseStatus(err), }, } json.NewEncoder(w).Encode(&snapRes) }
func (d *driver) list(w http.ResponseWriter, r *http.Request) { method := "list" v, err := volume.Get(d.name) if err != nil { d.logRequest(method, "").Warnf("Cannot locate volume driver: %v", err.Error()) d.errorResponse(w, err) return } vols, err := v.Enumerate(nil, nil) if err != nil { d.errorResponse(w, err) return } volInfo := make([]volumeInfo, len(vols)) for i, v := range vols { volInfo[i].Name = v.Locator.Name if v.AttachPath != "" { volInfo[i].Mountpoint = path.Join(v.AttachPath, config.DataDir) } } json.NewEncoder(w).Encode(map[string][]volumeInfo{"Volumes": volInfo}) }
func (d *driver) create(w http.ResponseWriter, r *http.Request) { var err error method := "create" request, err := d.decode(method, w, r) if err != nil { return } d.logReq(method, request.Name).Info("") _, err = d.volFromName(request.Name) if err != nil { v, err := volume.Get(d.name) if err != nil { json.NewEncoder(w).Encode(&volumeResponse{Err: err}) return } spec := d.specFromOpts(request.Opts) _, err = v.Create(api.VolumeLocator{Name: request.Name}, nil, spec) if err != nil { json.NewEncoder(w).Encode(&volumeResponse{Err: err}) return } } json.NewEncoder(w).Encode(&volumeResponse{}) }
func (vd *volApi) delete(w http.ResponseWriter, r *http.Request) { var volumeID string var err error method := "delete" if volumeID, err = vd.parseVolumeID(r); err != nil { e := fmt.Errorf("Failed to parse parse volumeID: %s", err.Error()) vd.sendError(vd.name, method, w, e.Error(), http.StatusBadRequest) return } vd.logRequest(method, volumeID).Infoln("") d, err := volume.Get(vd.name) if err != nil { notFound(w, r) return } volumeResponse := &api.VolumeResponse{} if err := d.Delete(volumeID); err != nil { volumeResponse.Error = err.Error() } json.NewEncoder(w).Encode(volumeResponse) }
func (vd *volApi) stats(w http.ResponseWriter, r *http.Request) { var volumeID string var err error method := "stats" if volumeID, err = vd.parseVolumeID(r); err != nil { e := fmt.Errorf("Failed to parse parse volumeID: %s", err.Error()) vd.sendError(vd.name, method, w, e.Error(), http.StatusBadRequest) return } vd.logRequest(method, string(volumeID)).Infoln("") d, err := volume.Get(vd.name) if err != nil { notFound(w, r) return } stats, err := d.Stats(volumeID) if err != nil { e := fmt.Errorf("Failed to get stats: %s", err.Error()) vd.sendError(vd.name, method, w, e.Error(), http.StatusBadRequest) return } json.NewEncoder(w).Encode(stats) }
func Init(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (graphdriver.Driver, error) { logrus.Infof("Initializing Fuse Graph driver at home:%s and storage: %v...", home, virtPath) var volumeDriver string for _, option := range options { key, val, err := parsers.ParseKeyValueOpt(option) if err != nil { return nil, err } switch key { case UnionFSVolumeDriver: volumeDriver = val default: return nil, fmt.Errorf("Unknown option %s\n", key) } } if volumeDriver == "" { logrus.Warnf("Error - no volume driver specified for UnionFS") return nil, fmt.Errorf("No volume driver specified for UnionFS") } logrus.Infof("UnionFS volume driver: %v", volumeDriver) volDriver, err := volume.Get(volumeDriver) if err != nil { logrus.Warnf("Error while loading volume driver: %s", volumeDriver) return nil, err } // In case it is mounted. syscall.Unmount(virtPath, 0) err = os.MkdirAll(virtPath, 0744) if err != nil { volDriver.Shutdown() logrus.Warnf("Error while creating FUSE mount path: %v", err) return nil, err } err = os.MkdirAll(physPath, 0744) if err != nil { volDriver.Shutdown() logrus.Warnf("Error while creating FUSE mount path: %v", err) return nil, err } cVirtPath := C.CString(virtPath) cPhysPath := C.CString(physPath) go C.start_unionfs(cPhysPath, cVirtPath) d := &Driver{ volDriver: volDriver, } return d, nil }
func (d *driver) volFromName(name string) (*volumeInfo, error) { v, err := volume.Get(d.name) if err != nil { return nil, fmt.Errorf("Cannot locate volume driver for %s: %s", d.name, err.Error()) } volumes, err := v.Inspect([]types.VolumeID{types.VolumeID(name)}) if err != nil || len(volumes) == 0 { return nil, fmt.Errorf("Cannot locate volume %s", name) } return &volumeInfo{vol: &volumes[0]}, nil }
func (d *driver) mount(w http.ResponseWriter, r *http.Request) { var response volumePathResponse method := "mount" v, err := volume.Get(d.name) if err != nil { d.logReq(method, "").Warn("Cannot locate volume driver") json.NewEncoder(w).Encode(&volumePathResponse{Err: err}) return } request, err := d.decode(method, w, r) if err != nil { json.NewEncoder(w).Encode(&volumePathResponse{Err: err}) return } d.logReq(method, request.Name).Debug("") volInfo, err := d.volFromName(request.Name) if err != nil { json.NewEncoder(w).Encode(&volumePathResponse{Err: err}) return } // If this is a block driver, first attach the volume. if v.Type()&volume.Block != 0 { attachPath, err := v.Attach(volInfo.vol.ID) if err != nil { d.logReq(method, request.Name).Warnf("Cannot attach volume: %v", err.Error()) json.NewEncoder(w).Encode(&volumePathResponse{Err: err}) return } d.logReq(method, request.Name).Debugf("response %v", attachPath) } // Now mount it. response.Mountpoint = path.Join(config.MountBase, request.Name) os.MkdirAll(response.Mountpoint, 0755) err = v.Mount(volInfo.vol.ID, response.Mountpoint) if err != nil { d.logReq(method, request.Name).Warnf("Cannot mount volume %v, %v", response.Mountpoint, err) json.NewEncoder(w).Encode(&volumePathResponse{Err: err}) return } response.Mountpoint = path.Join(response.Mountpoint, config.DataDir) os.MkdirAll(response.Mountpoint, 0755) d.logReq(method, request.Name).Infof("response %v", response.Mountpoint) json.NewEncoder(w).Encode(&response) }
func (vd *volDriver) snapEnumerate(w http.ResponseWriter, r *http.Request) { var err error var labels api.Labels var ids []api.VolumeID var snaps []api.VolumeSnap method := "snapEnumerate" d, err := volume.Get(vd.name) if err != nil { vd.notFound(w, r) return } params := r.URL.Query() v := params[string(api.OptLabel)] if v != nil { if err = json.Unmarshal([]byte(v[0]), &labels); err != nil { e := fmt.Errorf("Failed to parse parse VolumeLabels: %s", err.Error()) vd.sendError(vd.name, method, w, e.Error(), http.StatusBadRequest) } } v, ok := params[string(api.OptSnapID)] if ok && v != nil { sids := make([]api.SnapID, len(params)) for i, s := range v { sids[i] = api.SnapID(s) } snaps, err = d.SnapInspect(sids) if err != nil { e := fmt.Errorf("Failed to inspect snaps: %s", err.Error()) vd.sendError(vd.name, method, w, e.Error(), http.StatusBadRequest) return } } else { v, ok = params[string(api.OptVolumeID)] if v != nil && ok { ids = make([]api.VolumeID, len(params)) for i, s := range v { ids[i] = api.VolumeID(s) } } snaps, err = d.SnapEnumerate(ids, labels) if err != nil { e := fmt.Errorf("Failed to enumerate snaps: %s", err.Error()) vd.sendError(vd.name, method, w, e.Error(), http.StatusBadRequest) return } } json.NewEncoder(w).Encode(snaps) }
func TestAll(t *testing.T) { _, err := volume.New(Name, volume.DriverParams{}) if err != nil { t.Fatalf("Failed to initialize Driver: %v", err) } d, err := volume.Get(Name) if err != nil { t.Fatalf("Failed to initialize Volume Driver: %v", err) } ctx := test.NewContext(d) ctx.Filesystem = "ext4" test.RunShort(t, ctx) }
func (vd *volApi) enumerate(w http.ResponseWriter, r *http.Request) { var locator api.VolumeLocator var configLabels api.Labels var err error var vols []api.Volume method := "enumerate" d, err := volume.Get(vd.name) if err != nil { notFound(w, r) return } params := r.URL.Query() v := params[string(api.OptName)] if v != nil { locator.Name = v[0] } v = params[string(api.OptLabel)] if v != nil { if err = json.Unmarshal([]byte(v[0]), &locator.VolumeLabels); err != nil { e := fmt.Errorf("Failed to parse parse VolumeLabels: %s", err.Error()) vd.sendError(vd.name, method, w, e.Error(), http.StatusBadRequest) } } v = params[string(api.OptConfigLabel)] if v != nil { if err = json.Unmarshal([]byte(v[0]), &configLabels); err != nil { e := fmt.Errorf("Failed to parse parse configLabels: %s", err.Error()) vd.sendError(vd.name, method, w, e.Error(), http.StatusBadRequest) } } v = params[string(api.OptVolumeID)] if v != nil { ids := make([]api.VolumeID, len(v)) for i, s := range v { ids[i] = api.VolumeID(s) } vols, err = d.Inspect(ids) if err != nil { e := fmt.Errorf("Failed to inspect volumeID: %s", err.Error()) vd.sendError(vd.name, method, w, e.Error(), http.StatusBadRequest) return } } else { vols, _ = d.Enumerate(locator, configLabels) } json.NewEncoder(w).Encode(vols) }
func TestAll(t *testing.T) { testPath := "/tmp/openstorage_driver_test" _, err := volume.New(Name, volume.DriverParams{RootParam: testPath}) if err != nil { t.Fatalf("Failed to initialize Driver: %v", err) } d, err := volume.Get(Name) if err != nil { t.Fatalf("Failed to initialize Volume Driver: %v", err) } ctx := test.NewContext(d) ctx.Filesystem = "btrfs" test.Run(t, ctx) }
func (d *driver) volFromName(name string) (*api.Volume, error) { v, err := volume.Get(d.name) if err != nil { return nil, fmt.Errorf("Cannot locate volume driver for %s: %s", d.name, err.Error()) } vols, err := v.Inspect([]string{name}) if err == nil && len(vols) == 1 { return vols[0], nil } vols, err = v.Enumerate(&api.VolumeLocator{Name: name}, nil) if err == nil && len(vols) == 1 { return vols[0], nil } return nil, fmt.Errorf("Cannot locate volume %s", name) }
func (d *driver) volFromName(name string) (*volumeInfo, error) { v, err := volume.Get(d.name) if err != nil { return nil, fmt.Errorf("Cannot locate volume driver for %s: %s", d.name, err.Error()) } vols, err := v.Inspect([]types.VolumeID{types.VolumeID(name)}) if err == nil && len(vols) == 1 { return &volumeInfo{vol: &vols[0]}, nil } vols, err = v.Enumerate(types.VolumeLocator{Name: name}, nil) if err == nil && len(vols) == 1 { return &volumeInfo{vol: &vols[0]}, nil } return nil, fmt.Errorf("Cannot locate volume %s", name) }
func TestAll(t *testing.T) { if _, err := credentials.NewEnvCredentials().Get(); err != nil { t.Skip("No AWS credentials, skipping AWS driver test: ", err) } _, err := volume.New(Name, volume.DriverParams{}) if err != nil { t.Logf("Failed to initialize Driver: %v", err) } d, err := volume.Get(Name) if err != nil { t.Fatalf("Failed to initialize Volume Driver: %v", err) } ctx := test.NewContext(d) ctx.Filesystem = api.FSType_FS_TYPE_EXT4 test.RunShort(t, ctx) }
func (vd *volApi) create(w http.ResponseWriter, r *http.Request) { var dcRes api.VolumeCreateResponse var dcReq api.VolumeCreateRequest method := "create" if err := json.NewDecoder(r.Body).Decode(&dcReq); err != nil { vd.sendError(vd.name, method, w, err.Error(), http.StatusBadRequest) return } d, err := volume.Get(vd.name) if err != nil { notFound(w, r) return } ID, err := d.Create(dcReq.Locator, dcReq.Options, dcReq.Spec) dcRes.VolumeResponse = api.VolumeResponse{Error: responseStatus(err)} dcRes.ID = ID json.NewEncoder(w).Encode(&dcRes) }
func (d *driver) volFromName(name string) (*volumeInfo, error) { s := strings.Split(name, ":") if len(s) != 2 { return nil, fmt.Errorf("Invalid d.logReq for name %s", name) } id, err := strconv.ParseUint(s[0], 10, 64) if err != nil { return nil, fmt.Errorf("Invalid name %s: %s", name, err.Error()) } volDriver, err := volume.Get(d.name) if err != nil { return nil, err } volumes, err := volDriver.Inspect([]types.VolumeID{types.VolumeID(id)}) if err != nil || len(volumes) == 0 { return nil, err } return &volumeInfo{metadata: s[1], vol: &volumes[0]}, nil }
func (vd *volApi) snap(w http.ResponseWriter, r *http.Request) { var snapReq api.SnapCreateRequest var snapRes api.SnapCreateResponse method := "snap" if err := json.NewDecoder(r.Body).Decode(&snapReq); err != nil { vd.sendError(vd.name, method, w, err.Error(), http.StatusBadRequest) return } d, err := volume.Get(vd.name) if err != nil { notFound(w, r) return } ID, err := d.Snapshot(snapReq.ID, snapReq.Readonly, snapReq.Locator) snapRes.VolumeCreateResponse.VolumeResponse = api.VolumeResponse{Error: responseStatus(err)} snapRes.VolumeCreateResponse.ID = ID json.NewEncoder(w).Encode(&snapRes) }
func TestAll(t *testing.T) { err := os.MkdirAll(testPath, 0744) if err != nil { t.Fatalf("Failed to create test path: %v", err) } _, err = volume.New(Name, volume.DriverParams{"path": testPath}) if err != nil { t.Fatalf("Failed to initialize Driver: %v", err) } d, err := volume.Get(Name) if err != nil { t.Fatalf("Failed to initialize Volume Driver: %v", err) } ctx := test.NewContext(d) ctx.Filesystem = api.FSType_FS_TYPE_NFS test.RunShort(t, ctx) }
func (vd *volApi) delete(w http.ResponseWriter, r *http.Request) { var volumeID api.VolumeID var err error method := "delete" if volumeID, err = vd.parseVolumeID(r); err != nil { e := fmt.Errorf("Failed to parse parse volumeID: %s", err.Error()) vd.sendError(vd.name, method, w, e.Error(), http.StatusBadRequest) return } d, err := volume.Get(vd.name) if err != nil { notFound(w, r) return } err = d.Delete(volumeID) res := api.ResponseStatusNew(err) json.NewEncoder(w).Encode(res) }
func (d *driver) unmount(w http.ResponseWriter, r *http.Request) { method := "unmount" v, err := volume.Get(d.name) if err != nil { d.logRequest(method, "").Warnf("Cannot locate volume driver: %v", err.Error()) d.errorResponse(w, err) return } request, err := d.decode(method, w, r) if err != nil { return } d.logRequest(method, request.Name).Infoln("") vol, err := d.volFromName(request.Name) if err != nil { e := d.volNotFound(method, request.Name, err, w) d.errorResponse(w, e) return } mountpoint := path.Join(config.MountBase, request.Name) err = v.Unmount(vol.Id, mountpoint) if err != nil { d.logRequest(method, request.Name).Warnf("Cannot unmount volume %v, %v", mountpoint, err) d.errorResponse(w, err) return } if v.Type() == api.DriverType_DRIVER_TYPE_BLOCK { _ = v.Detach(vol.Id) } d.emptyResponse(w) }
func (d *driver) unmount(w http.ResponseWriter, r *http.Request) { method := "unmount" v, err := volume.Get(d.name) if err != nil { d.logReq(method, "").Warnf("Cannot locate volume driver: %v", err.Error()) json.NewEncoder(w).Encode(&volumeResponse{Err: err}) return } request, err := d.decode(method, w, r) if err != nil { return } d.logReq(method, request.Name).Info("") volInfo, err := d.volFromName(request.Name) if err != nil { e := d.volNotFound(method, request.Name, err, w) json.NewEncoder(w).Encode(&volumeResponse{Err: e}) return } mountpoint := path.Join(config.MountBase, request.Name) err = v.Unmount(volInfo.vol.ID, mountpoint) if err != nil { d.logReq(method, request.Name).Warnf("Cannot unmount volume %v, %v", mountpoint, err) json.NewEncoder(w).Encode(&volumeResponse{Err: err}) return } if v.Type()&volume.Block != 0 { _ = v.Detach(volInfo.vol.ID) } d.emptyResponse(w) }
func (vd *volDriver) snapDelete(w http.ResponseWriter, r *http.Request) { var err error var snapID api.SnapID method := "snapDelete" d, err := volume.Get(vd.name) if err != nil { vd.notFound(w, r) return } if snapID, err = vd.parseSnapID(r); err != nil { e := fmt.Errorf("Failed to parse SnapID: %s", err.Error()) vd.sendError(vd.name, method, w, e.Error(), http.StatusBadRequest) return } err = d.SnapDelete(snapID) if err != nil { vd.sendError(vd.name, method, w, err.Error(), http.StatusNotFound) return } json.NewEncoder(w).Encode(api.VolumeResponse{Error: responseStatus(err)}) }
func (vd *volDriver) snapInspect(w http.ResponseWriter, r *http.Request) { var err error var snapID api.SnapID method := "snapInspect" d, err := volume.Get(vd.name) if err != nil { vd.notFound(w, r) return } if snapID, err = vd.parseSnapID(r); err != nil { e := fmt.Errorf("Failed to parse SnapID: %s", err.Error()) vd.sendError(vd.name, method, w, e.Error(), http.StatusBadRequest) return } dk, err := d.SnapInspect([]api.SnapID{snapID}) if err != nil { vd.sendError(vd.name, method, w, err.Error(), http.StatusNotFound) return } json.NewEncoder(w).Encode(dk) }