Exemplo n.º 1
0
func (d *DaemonConfig) handleListAll(w http.ResponseWriter, r *http.Request) {
	vols, err := d.Config.ListAllVolumes()
	if err != nil {
		api.RESTHTTPError(w, errors.ListVolume.Combine(err))
		return
	}

	response := []*config.Volume{}
	for _, vol := range vols {
		parts := strings.SplitN(vol, "/", 2)
		if len(parts) != 2 {
			api.RESTHTTPError(w, errors.InvalidVolume.Combine(errored.New(vol)))
			return
		}
		// FIXME make this take a single string and not a split one
		volConfig, err := d.Config.GetVolume(parts[0], parts[1])
		if err != nil {
			api.RESTHTTPError(w, errors.ListVolume.Combine(err))
			return
		}

		response = append(response, volConfig)
	}

	content, err := json.Marshal(response)
	if err != nil {
		api.RESTHTTPError(w, errors.ListVolume.Combine(err))
		return
	}

	w.Write(content)
}
Exemplo n.º 2
0
func (d *DaemonConfig) handleRuntimeUpload(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	policy := vars["policy"]
	volumeName := vars["volume"]

	volume, err := d.Config.GetVolume(policy, volumeName)
	if err != nil {
		api.RESTHTTPError(w, errors.GetVolume.Combine(err))
		return
	}

	data, err := ioutil.ReadAll(r.Body)
	if err != nil {
		api.RESTHTTPError(w, errors.ReadBody.Combine(err))
		return
	}

	runtime := config.RuntimeOptions{}
	if err := json.Unmarshal(data, &runtime); err != nil {
		api.RESTHTTPError(w, errors.UnmarshalRuntime.Combine(err))
		return
	}

	if err := d.Config.PublishVolumeRuntime(volume, runtime); err != nil {
		api.RESTHTTPError(w, errors.PublishRuntime.Combine(err))
		return
	}
}
Exemplo n.º 3
0
func (d *DaemonConfig) handlePolicyList(w http.ResponseWriter, r *http.Request) {
	policies, err := d.Config.ListPolicies()
	if err != nil {
		api.RESTHTTPError(w, errors.ListPolicy.Combine(err))
		return
	}

	content, err := json.Marshal(policies)
	if err != nil {
		api.RESTHTTPError(w, errors.ListPolicy.Combine(err))
		return
	}

	w.Write(content)
}
Exemplo n.º 4
0
func (d *DaemonConfig) handleGlobal(w http.ResponseWriter, r *http.Request) {
	content, err := json.Marshal(d.Global.Published())
	if err != nil {
		api.RESTHTTPError(w, errors.MarshalGlobal.Combine(err))
		return
	}

	w.Write(content)
}
Exemplo n.º 5
0
func (d *DaemonConfig) handlePolicy(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	policy := vars["policy"]

	policyObj, err := d.Config.GetPolicy(policy)
	if err != nil {
		api.RESTHTTPError(w, errors.GetPolicy.Combine(err))
		return
	}

	content, err := json.Marshal(policyObj)
	if err != nil {
		api.RESTHTTPError(w, errors.MarshalPolicy.Combine(err))
		return
	}

	w.Write(content)
}
Exemplo n.º 6
0
func (d *DaemonConfig) handleRemoveForce(w http.ResponseWriter, r *http.Request) {
	req, err := unmarshalRequest(r)
	if err != nil {
		api.RESTHTTPError(w, errors.UnmarshalRequest.Combine(err))
		return
	}

	err = d.Config.RemoveVolume(req.Policy, req.Name)
	if err == errors.NotExists {
		w.WriteHeader(404)
		return
	}

	if err != nil {
		api.RESTHTTPError(w, errors.RemoveVolume.Combine(errored.Errorf("%v/%v", req.Policy, req.Name)).Combine(err))
		return
	}
}
Exemplo n.º 7
0
func (d *DaemonConfig) handlePolicyListRevisions(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	policy := vars["policy"]

	revisions, err := d.Config.ListPolicyRevisions(policy)
	if err != nil {
		api.RESTHTTPError(w, errors.ListPolicyRevision.Combine(err))
		return
	}

	content, err := json.Marshal(revisions)
	if err != nil {
		api.RESTHTTPError(w, errors.ListPolicyRevision.Combine(err))
		return
	}

	w.Write(content)
}
Exemplo n.º 8
0
func (d *DaemonConfig) handlePolicyDelete(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	policy := vars["policy"]

	if err := d.Config.DeletePolicy(policy); err != nil {
		api.RESTHTTPError(w, errors.PublishGlobal.Combine(err))
		return
	}
}
Exemplo n.º 9
0
func (d *DaemonConfig) handleGlobalUpload(w http.ResponseWriter, r *http.Request) {
	data, err := ioutil.ReadAll(r.Body)
	if err != nil {
		api.RESTHTTPError(w, errors.ReadBody.Combine(err))
		return
	}

	global := config.NewGlobalConfig()
	if err := json.Unmarshal(data, global); err != nil {
		api.RESTHTTPError(w, errors.UnmarshalGlobal.Combine(err))
		return
	}

	if err := d.Config.PublishGlobal(global); err != nil {
		api.RESTHTTPError(w, errors.PublishGlobal.Combine(err))
		return
	}
}
Exemplo n.º 10
0
func (d *DaemonConfig) handleSnapshotList(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	policy := vars["policy"]
	volumeName := vars["volume"]

	volConfig, err := d.Config.GetVolume(policy, volumeName)
	if err != nil {
		api.RESTHTTPError(w, errors.GetVolume.Combine(err))
		return
	}

	if volConfig.Backends.Snapshot == "" {
		api.RESTHTTPError(w, errors.SnapshotsUnsupported.Combine(errored.Errorf("%q", volConfig)))
		return
	}

	driver, err := backend.NewSnapshotDriver(volConfig.Backends.Snapshot)
	if err != nil {
		api.RESTHTTPError(w, errors.GetDriver.Combine(err))
		return
	}

	do := storage.DriverOptions{
		Volume: storage.Volume{
			Name:   volConfig.String(),
			Params: volConfig.DriverOptions,
		},
		Timeout: d.Global.Timeout,
	}

	results, err := driver.ListSnapshots(do)
	if err != nil {
		api.RESTHTTPError(w, errors.ListSnapshots.Combine(err))
		return
	}

	content, err := json.Marshal(results)
	if err != nil {
		api.RESTHTTPError(w, errors.MarshalResponse.Combine(err))
		return
	}

	w.Write(content)
}
Exemplo n.º 11
0
func (d *DaemonConfig) handleRuntime(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	policy := vars["policy"]
	volumeName := vars["volume"]

	runtime, err := d.Config.GetVolumeRuntime(policy, volumeName)
	if err != nil {
		api.RESTHTTPError(w, errors.GetVolume.Combine(err))
		return
	}

	content, err := json.Marshal(runtime)
	if err != nil {
		api.RESTHTTPError(w, errors.MarshalResponse.Combine(err))
		return
	}

	w.Write(content)
}
Exemplo n.º 12
0
func (d *DaemonConfig) handleSnapshotTake(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	policy := vars["policy"]
	volume := vars["volume"]

	if err := d.Config.TakeSnapshot(fmt.Sprintf("%v/%v", policy, volume)); err != nil {
		api.RESTHTTPError(w, errors.SnapshotFailed.Combine(err))
		return
	}
}
Exemplo n.º 13
0
func (d *DaemonConfig) handleCreate(w http.ResponseWriter, r *http.Request) {
	content, err := ioutil.ReadAll(r.Body)
	if err != nil {
		api.RESTHTTPError(w, errors.ReadBody.Combine(err))
		return
	}

	req := &config.VolumeRequest{}

	if err := json.Unmarshal(content, req); err != nil {
		api.RESTHTTPError(w, errors.UnmarshalRequest.Combine(err))
		return
	}

	if req.Policy == "" {
		api.RESTHTTPError(w, errors.GetPolicy.Combine(errored.Errorf("policy was blank")))
		return
	}

	if req.Name == "" {
		api.RESTHTTPError(w, errors.GetVolume.Combine(errored.Errorf("volume was blank")))
		return
	}

	hostname, err := os.Hostname()
	if err != nil {
		api.RESTHTTPError(w, errors.GetHostname.Combine(err))
		return
	}

	policy, err := d.Config.GetPolicy(req.Policy)
	if err != nil {
		api.RESTHTTPError(w, errors.GetPolicy.Combine(errored.New(req.Policy).Combine(err)))
		return
	}

	uc := &config.UseMount{
		Volume:   strings.Join([]string{req.Policy, req.Name}, "/"),
		Reason:   lock.ReasonCreate,
		Hostname: hostname,
	}

	snapUC := &config.UseSnapshot{
		Volume: strings.Join([]string{req.Policy, req.Name}, "/"),
		Reason: lock.ReasonCreate,
	}

	err = lock.NewDriver(d.Config).ExecuteWithMultiUseLock(
		[]config.UseLocker{uc, snapUC},
		d.Global.Timeout,
		d.createVolume(w, req, policy),
	)
	if err != nil && err != errors.Exists {
		api.RESTHTTPError(w, errors.CreateVolume.Combine(err))
		return
	}
}
Exemplo n.º 14
0
func (d *DaemonConfig) handlePolicyUpload(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	policyName := vars["policy"]

	data, err := ioutil.ReadAll(r.Body)
	if err != nil {
		api.RESTHTTPError(w, errors.ReadBody.Combine(err))
		return
	}

	policy := config.NewPolicy()
	if err := json.Unmarshal(data, policy); err != nil {
		api.RESTHTTPError(w, errors.UnmarshalPolicy.Combine(err))
		return
	}

	if err := d.Config.PublishPolicy(policyName, policy); err != nil {
		api.RESTHTTPError(w, errors.PublishPolicy.Combine(err))
		return
	}
}
Exemplo n.º 15
0
func (d *DaemonConfig) handlePolicyGetRevision(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	policy := vars["policy"]
	revision := vars["revision"]

	policyText, err := d.Config.GetPolicyRevision(policy, revision)
	if err != nil {
		api.RESTHTTPError(w, errors.GetPolicyRevision.Combine(err))
		return
	}

	w.Write([]byte(policyText))
}
Exemplo n.º 16
0
func (d *DaemonConfig) handleGet(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	policy := vars["policy"]
	volumeName := vars["volume"]

	volConfig, err := d.Config.GetVolume(policy, volumeName)
	if erd, ok := err.(*errored.Error); ok && erd.Contains(errors.NotExists) {
		w.WriteHeader(404)
		return
	} else if err != nil {
		api.RESTHTTPError(w, errors.GetVolume.Combine(err))
		return
	}

	content, err := json.Marshal(volConfig)
	if err != nil {
		api.RESTHTTPError(w, errors.MarshalResponse.Combine(err))
		return
	}

	w.Write(content)
}
Exemplo n.º 17
0
func (d *DaemonConfig) handleUserEndpoints(ul config.UseLocker, w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	policy := vars["policy"]
	volumeName := vars["volume"]

	vc := &config.Volume{
		PolicyName: policy,
		VolumeName: volumeName,
	}

	if err := d.Config.GetUse(ul, vc); err != nil {
		api.RESTHTTPError(w, errors.GetMount.Combine(err))
		return
	}

	content, err := json.Marshal(ul)
	if err != nil {
		api.RESTHTTPError(w, errors.MarshalResponse.Combine(err))
		return
	}

	w.Write(content)
}
Exemplo n.º 18
0
func (d *DaemonConfig) handleRequest(w http.ResponseWriter, r *http.Request) {
	req, err := unmarshalRequest(r)
	if err != nil {
		api.RESTHTTPError(w, errors.UnmarshalRequest.Combine(err))
		return
	}

	tenConfig, err := d.Config.GetVolume(req.Policy, req.Name)
	if erd, ok := err.(*errored.Error); ok && erd.Contains(errors.NotExists) {
		w.WriteHeader(404)
		return
	} else if err != nil {
		api.RESTHTTPError(w, errors.GetVolume.Combine(err))
		return
	}

	content, err := json.Marshal(tenConfig)
	if err != nil {
		api.RESTHTTPError(w, errors.MarshalResponse.Combine(err))
		return
	}

	w.Write(content)
}
Exemplo n.º 19
0
func (d *DaemonConfig) handleRemove(w http.ResponseWriter, r *http.Request) {
	// set a default timeout if none is specified
	timeout := d.Global.Timeout
	req, err := unmarshalRequest(r)
	if err != nil {
		api.RESTHTTPError(w, errors.UnmarshalRequest.Combine(err))
		return
	}

	if req.Options["timeout"] != "" {
		var t time.Duration
		if t, err = time.ParseDuration(req.Options["timeout"]); err != nil {
			api.RESTHTTPError(w, errors.RemoveVolume.Combine(err))
			return
		}
		timeout = t
	}

	vc, err := d.Config.GetVolume(req.Policy, req.Name)
	if err != nil {
		api.RESTHTTPError(w, errors.GetVolume.Combine(err))
		return
	}

	locks, err := d.createRemoveLocks(vc)
	if err != nil {
		api.RESTHTTPError(w, err)
		return
	}

	if req.Options["force"] == "true" {
		if err := d.handleForceRemoveLock(req, vc, locks); err != nil {
			api.RESTHTTPError(w, err)
			return
		}
	}

	err = lock.NewDriver(d.Config).ExecuteWithMultiUseLock(locks, timeout, func(ld *lock.Driver, ucs []config.UseLocker) error {
		exists, err := control.ExistsVolume(vc, timeout)
		if err != nil && err != errors.NoActionTaken {
			return err
		}

		if err == errors.NoActionTaken {
			return d.completeRemove(req, vc)
		}

		if !exists {
			d.removeVolume(req, vc)
			return errors.NotExists
		}

		return d.completeRemove(req, vc)
	})

	if err == errors.NotExists {
		w.WriteHeader(404)
		return
	}

	if err != nil {
		api.RESTHTTPError(w, errors.RemoveVolume.Combine(errored.New(vc.String())).Combine(err))
		return
	}
}
Exemplo n.º 20
0
func (d *DaemonConfig) handleCopy(w http.ResponseWriter, r *http.Request) {
	req, err := unmarshalRequest(r)
	if err != nil {
		api.RESTHTTPError(w, errors.UnmarshalRequest.Combine(err))
		return
	}

	if _, ok := req.Options["snapshot"]; !ok {
		api.RESTHTTPError(w, errors.MissingSnapshotOption)
		return
	}

	if _, ok := req.Options["target"]; !ok {
		api.RESTHTTPError(w, errors.MissingTargetOption)
		return
	}

	if strings.Contains(req.Options["target"], "/") {
		api.RESTHTTPError(w, errors.InvalidVolume.Combine(errored.New("/")))
		return
	}

	volConfig, err := d.Config.GetVolume(req.Policy, req.Name)
	if err != nil {
		api.RESTHTTPError(w, errors.GetVolume.Combine(err))
		return
	}

	if volConfig.Backends.Snapshot == "" {
		api.RESTHTTPError(w, errors.SnapshotsUnsupported.Combine(errored.New(volConfig.Backends.Snapshot)))
		return
	}

	driver, err := backend.NewSnapshotDriver(volConfig.Backends.Snapshot)
	if err != nil {
		api.RESTHTTPError(w, errors.GetDriver.Combine(err))
		return
	}

	newVolConfig, err := d.Config.GetVolume(req.Policy, req.Name)
	if err != nil {
		api.RESTHTTPError(w, errors.GetVolume.Combine(err))
		return
	}

	newVolConfig.VolumeName = req.Options["target"]

	do := storage.DriverOptions{
		Volume: storage.Volume{
			Name:   volConfig.String(),
			Params: volConfig.DriverOptions,
		},
		Timeout: d.Global.Timeout,
	}

	host, err := os.Hostname()
	if err != nil {
		api.RESTHTTPError(w, errors.GetHostname.Combine(err))
		return
	}

	if volConfig.VolumeName == newVolConfig.VolumeName {
		api.RESTHTTPError(w, errors.CannotCopyVolume.Combine(errored.Errorf("You cannot copy volume %q onto itself.", volConfig.VolumeName)))
		return
	}

	snapUC := &config.UseSnapshot{
		Volume: volConfig.String(),
		Reason: lock.ReasonCopy,
	}

	newUC := &config.UseMount{
		Volume:   newVolConfig.String(),
		Reason:   lock.ReasonCopy,
		Hostname: host,
	}

	newSnapUC := &config.UseSnapshot{
		Volume: newVolConfig.String(),
		Reason: lock.ReasonCopy,
	}

	err = lock.NewDriver(d.Config).ExecuteWithMultiUseLock([]config.UseLocker{newUC, newSnapUC, snapUC}, d.Global.Timeout, func(ld *lock.Driver, ucs []config.UseLocker) error {
		if err := d.Config.PublishVolume(newVolConfig); err != nil {
			return err
		}

		if err := driver.CopySnapshot(do, req.Options["snapshot"], newVolConfig.String()); err != nil {
			return err
		}
		return nil
	})

	if err != nil {
		api.RESTHTTPError(w, errors.PublishVolume.Combine(errored.Errorf(
			"Creating new volume %q from volume %q, snapshot %q",
			req.Options["target"],
			volConfig.String(),
			req.Options["snapshot"],
		)).Combine(err))
		return
	}

	content, err := json.Marshal(newVolConfig)
	if err != nil {
		api.RESTHTTPError(w, errors.PublishVolume.Combine(errored.Errorf(
			"Creating new volume %q from volume %q, snapshot %q",
			req.Options["target"],
			volConfig.String(),
			req.Options["snapshot"],
		)).Combine(err))
	}

	w.Write(content)
}