예제 #1
0
func wrapSnapshotAction(config config, action func(config config, tenant string, volume *cephdriver.CephVolume)) {
	for tenant, value := range config {
		mutex.Lock()
		duration, err := time.ParseDuration(config[tenant].Snapshot.Frequency)
		if err != nil {
			panic(fmt.Sprintf("Runtime configuration incorrect; cannot use %q as a snapshot frequency", config[tenant].Snapshot.Frequency))
		}

		if value.UseSnapshots && time.Now().Unix()%int64(duration.Seconds()) == 0 {
			for _, volumes := range volumeMap {
				rbdConfig, err := librbd.ReadConfig("/etc/rbdconfig.json")
				if err != nil {
					log.Errorf("Cannot read RBD configuration: %v", err)
					break
				}
				driver, err := cephdriver.NewCephDriver(rbdConfig, config[tenant].Pool)
				if err != nil {
					log.Errorf("Cannot snap volumes for tenant %q: %v", tenant, err)
					break
				}
				for volName := range volumes {
					volume := driver.NewVolume(volName, config[tenant].Size)
					action(config, tenant, volume)
				}
			}
		}
		mutex.Unlock()
	}
}
예제 #2
0
func configureRouter(tenant string, debug bool) *mux.Router {
	config, err := librbd.ReadConfig("/etc/rbdconfig.json")
	if err != nil {
		panic(err)
	}

	var routeMap = map[string]func(http.ResponseWriter, *http.Request){
		"/Plugin.Activate":      activate,
		"/Plugin.Deactivate":    nilAction,
		"/VolumeDriver.Create":  create(tenant, config),
		"/VolumeDriver.Remove":  nilAction,
		"/VolumeDriver.Path":    getPath(tenant, config),
		"/VolumeDriver.Mount":   mount(tenant, config),
		"/VolumeDriver.Unmount": unmount(tenant, config),
	}

	router := mux.NewRouter()
	s := router.Headers("Accept", "application/vnd.docker.plugins.v1+json").
		Methods("POST").Subrouter()

	for key, value := range routeMap {
		parts := strings.SplitN(key, ".", 2)
		s.HandleFunc(key, logHandler(parts[1], debug, value))
	}

	if debug {
		s.HandleFunc("/VolumeDriver.{action:.*}", action)
	}

	return router
}
예제 #3
0
func TestSnapshots(t *testing.T) {
	config, err := librbd.ReadConfig("/etc/rbdconfig.json")
	if err != nil {
		t.Fatal(err)
	}

	// Create a new driver
	cephDriver, err := NewCephDriver(config, "rbd")
	if err != nil {
		t.Fatal(err)
	}

	volumeSpec := cephDriver.NewVolume("pithos1234", 10000000)
	// Create a volume
	if err := volumeSpec.Create(); err != nil {
		t.Fatalf("Error creating the volume. Err: %v", err)
	}

	if err := volumeSpec.CreateSnapshot("hello"); err != nil {
		t.Fatal(err)
	}

	if err := volumeSpec.CreateSnapshot("hello"); err == nil {
		t.Fatal("Was able to create same snapshot name twice")
	}

	list, err := volumeSpec.ListSnapshots(100)
	if err != nil {
		t.Fatal(err)
	}

	if len(list) != 1 || !reflect.DeepEqual(list, []string{"hello"}) {
		t.Fatal("Did not see snapshot created earlier in list")
	}

	if err := volumeSpec.RemoveSnapshot("hello"); err != nil {
		t.Fatal(err)
	}

	if err := volumeSpec.RemoveSnapshot("hello"); err == nil {
		t.Fatal("Was able to remove same snapshot name twice")
	}

	list, err = volumeSpec.ListSnapshots(100)
	if err != nil {
		t.Fatal(err)
	}

	if len(list) != 0 {
		t.Fatal("Snapshot list is not empty and should be")
	}

	// delete the volume
	if err := volumeSpec.Remove(); err != nil {
		t.Fatalf("Error deleting the volume. Err: %v", err)
	}
}
예제 #4
0
func TestMountUnmountVolume(t *testing.T) {
	config, err := librbd.ReadConfig("/etc/rbdconfig.json")
	if err != nil {
		t.Fatal(err)
	}

	// Create a new driver
	cephDriver, err := NewCephDriver(config, "rbd")
	if err != nil {
		t.Fatal(err)
	}

	volumeSpec := cephDriver.NewVolume("pithos1234", 10240000)

	// we don't care if there's an error here, just want to make sure the create
	// succeeds. Easier restart of failed tests this way.
	volumeSpec.Unmount()
	volumeSpec.Remove()

	if err := volumeSpec.Create(); err != nil {
		t.Fatalf("Error creating the volume: %v", err)
	}

	// mount the volume
	if err := volumeSpec.Mount(); err != nil {
		t.Fatalf("Error mounting the volume. Err: %v", err)
	}

	if err := readWriteTest("/mnt/ceph/rbd/pithos1234"); err != nil {
		t.Fatalf("Error during read/write test. Err: %v", err)
	}

	// unmount the volume
	if err := volumeSpec.Unmount(); err != nil {
		t.Fatalf("Error unmounting the volume. Err: %v", err)
	}

	if err := volumeSpec.Remove(); err != nil {
		t.Fatalf("Error deleting the volume: %v", err)
	}
}
예제 #5
0
func TestRepeatedMountUnmount(t *testing.T) {
	config, err := librbd.ReadConfig("/etc/rbdconfig.json")
	if err != nil {
		t.Fatal(err)
	}

	// Create a new driver
	cephDriver, err := NewCephDriver(config, "rbd")
	if err != nil {
		t.Fatal(err)
	}

	volumeSpec := cephDriver.NewVolume("pithos1234", 10000000)
	// Create a volume
	if err := volumeSpec.Create(); err != nil {
		t.Fatalf("Error creating the volume. Err: %v", err)
	}

	// Repeatedly perform mount unmount test
	for i := 0; i < 10; i++ {
		// mount the volume
		if err := volumeSpec.Mount(); err != nil {
			t.Fatalf("Error mounting the volume. Err: %v", err)
		}

		if err := readWriteTest("/mnt/ceph/rbd/pithos1234"); err != nil {
			t.Fatalf("Error during read/write test. Err: %v", err)
		}

		// unmount the volume
		if err := volumeSpec.Unmount(); err != nil {
			t.Fatalf("Error unmounting the volume. Err: %v", err)
		}
	}

	// delete the volume
	if err := volumeSpec.Remove(); err != nil {
		t.Fatalf("Error deleting the volume. Err: %v", err)
	}
}