Ejemplo n.º 1
0
func setKey(value db.Entity) {
	path, err := value.Path()
	if err != nil {
		panic(err)
	}

	content, err := jsonio.Write(value)
	if err != nil {
		panic(err)
	}

	switch Driver {
	case "etcd":
		client, err := getEtcdClient()
		if err != nil {
			panic(err)
		}

		if _, err := client.Set(context.Background(), fmt.Sprintf("/volplugin/%v", path), string(content), nil); err != nil {
			panic(err)
		}
	case "consul":
		client, err := getConsulClient()
		if err != nil {
			panic(err)
		}

		if _, err := client.KV().Put(&api.KVPair{Key: fmt.Sprintf("volplugin/%v", path), Value: content}, nil); err != nil {
			panic(err)
		}
	}
}
Ejemplo n.º 2
0
func (s *testSuite) TestDump(c *C) {
	copy := testPolicies["basic"].Copy()
	for i := 0; i < 10; i++ {
		copy.(*db.Policy).Name = fmt.Sprintf("test%d", i)
		c.Assert(s.client.Set(copy), IsNil)
	}

	tarballPath, err := s.client.Dump("")
	c.Assert(err, IsNil)
	defer os.Remove(tarballPath)

	// check that the tarball was created in the expected spot
	_, err = os.Stat(tarballPath)
	c.Assert(os.IsNotExist(err), Equals, false)

	tarballFilename := filepath.Base(tarballPath)
	// can't use filepath.Ext() here because it thinks ".gz" is the extension
	dirName := tarballFilename[:strings.LastIndex(tarballFilename, ".tar.gz")]

	for i := 0; i < 10; i++ {
		testFilename := path.Join(dirName, "volplugin/policies", fmt.Sprintf("test%d", i))

		data, err := ioutil.ReadFile(tarballPath)
		c.Assert(err, IsNil)

		// check that our test key is present and has the expected value
		reader := bytes.NewReader(data)
		gzReader, err := gzip.NewReader(reader)
		c.Assert(err, IsNil)
		tarReader := tar.NewReader(gzReader)

		found := false

		for {
			header, err := tarReader.Next()
			if err == io.EOF {
				break
			}
			c.Assert(err, IsNil)

			if header.Name == testFilename {
				var b bytes.Buffer
				_, err = io.Copy(&b, tarReader)
				c.Assert(err, IsNil)

				copy := testPolicies["basic"].Copy()
				copy.(*db.Policy).Name = fmt.Sprintf("test%d", i)
				c.Assert(s.client.Get(copy), IsNil)

				content, err := jsonio.Write(copy)
				c.Assert(err, IsNil)
				c.Assert(b.String(), Equals, string(content))
				found = true
				break
			}
		}

		c.Assert(found, Equals, true, Commentf(testFilename))
	}
}
Ejemplo n.º 3
0
// Set takes the object and commits it to the database.
func (c *Client) Set(obj db.Entity) error {
	if err := obj.Validate(); err != nil {
		return err
	}

	if obj.Hooks().PreSet != nil {
		if err := obj.Hooks().PreSet(c, obj); err != nil {
			return errors.EtcdToErrored(err)
		}
	}

	content, err := jsonio.Write(obj)
	if err != nil {
		return err
	}

	path, err := obj.Path()
	if err != nil {
		return err
	}

	if _, err := c.client.Set(context.Background(), c.qualified(path), string(content), nil); err != nil {
		return errors.EtcdToErrored(err)
	}

	if obj.Hooks().PostSet != nil {
		if err := obj.Hooks().PostSet(c, obj); err != nil {
			return errors.EtcdToErrored(err)
		}
	}

	return nil
}
Ejemplo n.º 4
0
func setKey(value db.Entity) {
	client, err := getEtcdClient()
	if err != nil {
		panic(err)
	}

	path, err := value.Path()
	if err != nil {
		panic(err)
	}

	content, err := jsonio.Write(value)
	if err != nil {
		panic(err)
	}

	if _, err := client.Set(context.Background(), fmt.Sprintf("/volplugin/%v", path), string(content), nil); err != nil {
		panic(err)
	}
}
Ejemplo n.º 5
0
// Free a lock. Pass force=true to force it dead.
func (c *Client) Free(lock db.Lock, force bool) error {
	content, err := jsonio.Write(lock)
	if err != nil {
		return errors.LockFailed.Combine(err)
	}

	path, err := lock.Path()
	if err != nil {
		return errors.LockFailed.Combine(err)
	}

	opts := &client.DeleteOptions{PrevValue: string(content)}

	if force {
		opts = &client.DeleteOptions{}
	}

	_, err = c.client.Delete(context.Background(), c.qualified(path), opts)
	return err
}
Ejemplo n.º 6
0
func (c *Client) doAcquire(lock db.Lock, ttl time.Duration) error {
	content, err := jsonio.Write(lock)
	if err != nil {
		return errors.LockFailed.Combine(err)
	}

	path, err := lock.Path()
	if err != nil {
		return errors.LockFailed.Combine(err)
	}

	_, err = c.client.Set(context.Background(), c.qualified(path), string(content), &client.SetOptions{PrevValue: string(content), TTL: ttl})
	if er, ok := err.(client.Error); ok && er.Code == client.ErrorCodeKeyNotFound {
		_, err := c.client.Set(context.Background(), c.qualified(path), string(content), &client.SetOptions{PrevExist: client.PrevNoExist, TTL: ttl})
		if err != nil {
			return errors.LockFailed.Combine(err)
		}

		return nil
	}

	return err
}
Ejemplo n.º 7
0
// acquires and yields a *lock{} populated with all the values needed to
// persist and reap this lock. Returns true if it is already running and we
// have re-requested a running lock.
func (c *Client) lock(obj db.Lock, ttl time.Duration, refresh bool) (*lock, bool, error) {
	// consul has a minimum ttl of 10s. Adjust.
	if ttl < 10*time.Second {
		ttl = 10 * time.Second
	}

	path, err := obj.Path()
	if err != nil {
		return nil, false, errors.LockFailed.Combine(err)
	}

	tmplock, ok := c.getLock(path)
	if ok {
		if reflect.DeepEqual(tmplock.obj, obj) {
			return tmplock, true, nil
		}

		return nil, false, errors.LockFailed.Combine(errored.Errorf("Invalid lock attempted at %q -- already exists", path))
	}

	sessionID, err := c.getSession(obj, ttl, refresh)
	if err != nil {
		return nil, false, err
	}

	content, err := jsonio.Write(obj)
	if err != nil {
		return nil, false, err
	}

	mylock, err := c.client.LockOpts(&api.LockOptions{
		LockTryOnce:      true,
		Key:              c.qualified(path),
		Value:            content,
		SessionTTL:       ttl.String(),
		MonitorRetryTime: ttl,
		MonitorRetries:   -1,
	})

	if err != nil {
		return nil, false, err
	}

	stopChan := make(chan struct{})
	go func() {
		time.Sleep(100 * time.Millisecond)
		close(stopChan)
	}()

	monitor, err := mylock.Lock(stopChan)
	if err != nil {
		return nil, false, err
	}

	done := make(chan struct{})

	lockObj := &lock{
		lock:        mylock,
		sessionID:   sessionID,
		doneChan:    done,
		monitorChan: monitor,
		obj:         obj,
		ttl:         ttl,
		path:        path,
		refresh:     refresh,
	}

	return lockObj, false, nil
}