Example #1
0
func (c *MockDataStore) WriteImage(op trace.Operation, parent *Image, ID string, meta map[string][]byte, sum string, r io.Reader) (*Image, error) {
	storeName, err := util.ImageStoreName(parent.Store)
	if err != nil {
		return nil, err
	}

	selflink, err := util.ImageURL(storeName, ID)
	if err != nil {
		return nil, err
	}

	var parentLink *url.URL
	if parent.ID != "" {
		parentLink, err = util.ImageURL(storeName, parent.ID)
		if err != nil {
			return nil, err
		}
	}

	i := &Image{
		ID:         ID,
		Store:      parent.Store,
		ParentLink: parentLink,
		SelfLink:   selflink,
		Metadata:   meta,
	}

	c.db[*parent.Store][ID] = i

	return i, nil
}
Example #2
0
File: image.go Project: kjplatz/vic
func (v *ImageStore) GetImage(ctx context.Context, store *url.URL, ID string) (*portlayer.Image, error) {

	defer trace.End(trace.Begin(store.String()))
	storeName, err := util.ImageStoreName(store)
	if err != nil {
		return nil, err
	}

	imageURL, err := util.ImageURL(storeName, ID)
	if err != nil {
		return nil, err
	}

	p := v.imageDirPath(storeName, ID)
	info, err := v.ds.Stat(ctx, p)
	if err != nil {
		return nil, err
	}

	_, ok := info.(*types.FolderFileInfo)
	if !ok {
		return nil, fmt.Errorf("Stat error:  image doesn't exist (%s)", p)
	}

	// get the metadata
	metaDataDir := v.imageMetadataDirPath(storeName, ID)
	meta, err := getMetadata(ctx, v.ds, metaDataDir)
	if err != nil {
		return nil, err
	}

	var s = *store
	var parentURL *url.URL

	parentID := v.parents.Get(ID)
	if parentID != "" {
		parentURL, _ = util.ImageURL(storeName, parentID)
	}

	newImage := &portlayer.Image{
		ID:       ID,
		SelfLink: imageURL,
		// We're relying on the parent map for this since we don't currently have a
		// way to get the disk's spec.  See VIC #482 for details.  Parent:
		// parent.SelfLink,
		Store:    &s,
		Parent:   parentURL,
		Metadata: meta,
	}

	log.Debugf("Returning image from location %s with parent url %s", newImage.SelfLink, newImage.Parent)
	return newImage, nil
}
Example #3
0
func TestImageCopy(t *testing.T) {
	storeName := "testStore"
	ID := "testImageID"

	imageURL, err := util.ImageURL(storeName, ID)
	if !assert.NoError(t, err) {
		return
	}

	parentURL, err := util.ImageURL(storeName, Scratch.ID)
	if !assert.NoError(t, err) {
		return
	}

	img, err := Parse(imageURL)
	if !assert.NoError(t, err) || !assert.NotNil(t, img) {
		return
	}

	storeURL, err := util.ImageStoreNameToURL(storeName)
	if !assert.NoError(t, err) {
		return
	}

	expected := &Image{
		ID:         ID,
		SelfLink:   imageURL,
		ParentLink: parentURL,
		Store:      storeURL,
		Metadata: map[string][]byte{
			"1": {byte(1)},
			"2": {byte(2)},
			"3": []byte("three"),
		},
	}

	actual := expected.Copy().(*Image)

	if !assert.Equal(t, expected, actual) {
		return
	}

	actual.Metadata["4"] = []byte("four")

	if !assert.NotEqual(t, expected, actual) {
		return
	}
}
Example #4
0
File: image.go Project: vmware/vic
func (v *ImageStore) GetImage(op trace.Operation, store *url.URL, ID string) (*portlayer.Image, error) {

	defer trace.End(trace.Begin(store.String()))
	storeName, err := util.ImageStoreName(store)
	if err != nil {
		return nil, err
	}

	imageURL, err := util.ImageURL(storeName, ID)
	if err != nil {
		return nil, err
	}

	if err = v.verifyImage(op, storeName, ID); err != nil {
		return nil, err
	}

	// get the metadata
	metaDataDir := v.imageMetadataDirPath(storeName, ID)
	meta, err := getMetadata(op, v.ds, metaDataDir)
	if err != nil {
		return nil, err
	}

	var s = *store
	var parentURL *url.URL

	parentID := v.parents.Get(ID)
	if parentID != "" {
		parentURL, _ = util.ImageURL(storeName, parentID)
	}

	newImage := &portlayer.Image{
		ID:       ID,
		SelfLink: imageURL,
		// We're relying on the parent map for this since we don't currently have a
		// way to get the disk's spec.  See VIC #482 for details.  Parent:
		// parent.SelfLink,
		Store:      &s,
		ParentLink: parentURL,
		Metadata:   meta,
	}

	op.Debugf("Returning image from location %s with parent url %s", newImage.SelfLink, newImage.Parent())
	return newImage, nil
}
Example #5
0
File: image.go Project: vmware/vic
// WriteImage creates a new image layer from the given parent.
// Eg parentImage + newLayer = new Image built from parent
//
// parent - The parent image to create the new image from.
// ID - textual ID for the image to be written
// meta - metadata associated with the image
// Tag - the tag of the image to be written
func (v *ImageStore) WriteImage(op trace.Operation, parent *portlayer.Image, ID string, meta map[string][]byte, sum string,
	r io.Reader) (*portlayer.Image, error) {

	storeName, err := util.ImageStoreName(parent.Store)
	if err != nil {
		return nil, err
	}

	imageURL, err := util.ImageURL(storeName, ID)
	if err != nil {
		return nil, err
	}

	// If this is scratch, then it's the root of the image store.  All images
	// will be descended from this created and prepared fs.
	if ID == portlayer.Scratch.ID {
		// Create the scratch layer
		if err := v.scratch(op, storeName); err != nil {
			return nil, err
		}
	} else {

		if parent.ID == "" {
			return nil, fmt.Errorf("parent ID is empty")
		}

		// persist the relationship
		v.parents.Add(ID, parent.ID)

		if err := v.parents.Save(op); err != nil {
			return nil, err
		}

		if err := v.writeImage(op, storeName, parent.ID, ID, meta, sum, r); err != nil {
			return nil, err
		}

	}

	newImage := &portlayer.Image{
		ID:         ID,
		SelfLink:   imageURL,
		ParentLink: parent.SelfLink,
		Store:      parent.Store,
		Metadata:   meta,
	}

	return newImage, nil
}
Example #6
0
// GetImage gets the specified image from the given store by retreiving it from the cache.
func (c *NameLookupCache) GetImage(op trace.Operation, store *url.URL, ID string) (*Image, error) {

	op.Debugf("Getting image %s from %s", ID, store.String())

	storeName, err := util.ImageStoreName(store)
	if err != nil {
		return nil, err
	}

	// Check the store exists
	if _, err = c.GetImageStore(op, storeName); err != nil {
		return nil, err
	}

	c.storeCacheLock.Lock()
	indx := c.storeCache[*store]
	c.storeCacheLock.Unlock()

	imgURL, err := util.ImageURL(storeName, ID)
	if err != nil {
		return nil, err
	}
	node, err := c.storeCache[*store].Get(imgURL.String())

	var img *Image
	if err != nil {
		if err == index.ErrNodeNotFound {
			debugf("Image %s not in cache, retreiving from datastore", ID)
			// Not in the cache.  Try to load it.
			img, err = c.DataStore.GetImage(op, store, ID)
			if err != nil {
				return nil, err
			}

			if err = indx.Insert(img); err != nil {
				return nil, err
			}
		} else {
			return nil, err
		}
	} else {
		img, _ = node.(*Image)
	}

	return img, nil
}
Example #7
0
func (c *MockDataStore) WriteImage(op trace.Operation, parent *spl.Image, ID string, meta map[string][]byte, sum string, r io.Reader) (*spl.Image, error) {
	storeName, err := util.ImageStoreName(parent.Store)
	if err != nil {
		return nil, err
	}

	selflink, err := util.ImageURL(storeName, ID)
	if err != nil {
		return nil, err
	}

	i := spl.Image{
		ID:         ID,
		Store:      parent.Store,
		ParentLink: parent.SelfLink,
		SelfLink:   selflink,
		Metadata:   meta,
	}

	return &i, nil
}
Example #8
0
// DeleteImage deletes an image from a store
func (h *StorageHandlersImpl) DeleteImage(params storage.DeleteImageParams) middleware.Responder {

	ferr := func(err error, code int) middleware.Responder {
		log.Errorf("DeleteImage: error %s", err.Error())
		return storage.NewDeleteImageDefault(code).WithPayload(
			&models.Error{
				Code:    swag.Int64(int64(code)),
				Message: err.Error(),
			})
	}

	imageURL, err := util.ImageURL(params.StoreName, params.ID)
	if err != nil {
		return ferr(err, http.StatusInternalServerError)
	}

	image, err := spl.Parse(imageURL)
	if err != nil {
		return ferr(err, http.StatusInternalServerError)
	}

	op := trace.NewOperation(context.Background(), fmt.Sprintf("DeleteImage(%s)", image.ID))
	if err = h.imageCache.DeleteImage(op, image); err != nil {
		switch {
		case spl.IsErrImageInUse(err):
			return ferr(err, http.StatusLocked)

		case os.IsNotExist(err):
			return ferr(err, http.StatusNotFound)

		default:
			return ferr(err, http.StatusInternalServerError)
		}
	}

	return storage.NewDeleteImageOK()
}
Example #9
0
func TestWriteImage(t *testing.T) {
	ic := spl.NewLookupCache(&MockDataStore{})

	// create image store
	op := trace.NewOperation(context.Background(), "test")
	_, err := ic.CreateImageStore(op, testStoreName)
	if err != nil {
		return
	}

	s := &StorageHandlersImpl{
		imageCache: ic,
	}

	eMeta := make(map[string]string)
	eMeta["foo"] = "bar"

	name := new(string)
	val := new(string)
	*name = "foo"
	*val = eMeta["foo"]

	params := &storage.WriteImageParams{
		StoreName:   testStoreName,
		ImageID:     testImageID,
		ParentID:    "scratch",
		Sum:         testImageSum,
		Metadatakey: name,
		Metadataval: val,
		ImageFile:   nil,
	}

	parentlink, err := util.ImageURL(testStoreName, params.ParentID)
	if !assert.NoError(t, err) {
		return
	}
	p := parentlink.String()

	selflink, err := util.ImageURL(testStoreName, testImageID)
	if !assert.NoError(t, err) {
		return
	}
	sl := selflink.String()

	expected := &storage.WriteImageCreated{
		Payload: &models.Image{
			ID:       testImageID,
			Parent:   &p,
			SelfLink: &sl,
			Store:    testStoreURL.String(),
			Metadata: eMeta,
		},
	}

	result := s.WriteImage(*params)
	if !assert.NotNil(t, result) {
		return
	}
	if !assert.Equal(t, expected, result) {
		return
	}
}
Example #10
0
func TestGetImage(t *testing.T) {

	s := &StorageHandlersImpl{
		imageCache: spl.NewLookupCache(&MockDataStore{}),
	}

	params := &storage.GetImageParams{
		ID:        testImageID,
		StoreName: testStoreName,
	}

	// expect 404 since no image store exists by that name
	storeNotFound := &storage.GetImageNotFound{
		Payload: &models.Error{
			Code:    swag.Int64(http.StatusNotFound),
			Message: fmt.Sprintf("store (%s) doesn't exist", testStoreURL.String()),
		},
	}

	result := s.GetImage(*params)
	if !assert.NotNil(t, result) {
		return
	}
	if !assert.Equal(t, storeNotFound, result) {
		return
	}

	op := trace.NewOperation(context.Background(), "test")

	// create the image store
	url, err := s.imageCache.CreateImageStore(op, testStoreName)
	// TODO(jzt): these are testing NameLookupCache, do we need them here?
	if !assert.Nil(t, err, "Error while creating image store") {
		return
	}
	if !assert.Equal(t, testStoreURL.String(), url.String()) {
		return
	}

	// expect 404 since no image exists by that name in that store
	imageNotFound := &storage.GetImageNotFound{
		Payload: &models.Error{
			Code:    swag.Int64(http.StatusNotFound),
			Message: fmt.Sprintf("store (%s) doesn't have image %s", testStoreURL.String(), testImageID),
		},
	}
	// try GetImage again
	result = s.GetImage(*params)
	if !assert.NotNil(t, result) {
		return
	}
	if !assert.Equal(t, imageNotFound, result) {
		return
	}

	// add image to store
	parent := spl.Image{
		ID:         "scratch",
		SelfLink:   nil,
		ParentLink: nil,
		Store:      &testStoreURL,
	}

	expectedMeta := make(map[string][]byte)
	expectedMeta["foo"] = []byte("bar")
	// add the image to the store
	image, err := s.imageCache.WriteImage(op, &parent, testImageID, expectedMeta, testImageSum, nil)
	if !assert.NoError(t, err) || !assert.NotNil(t, image) {
		return
	}

	selflink, err := util.ImageURL(testStoreName, testImageID)
	if !assert.NoError(t, err) {
		return
	}
	sl := selflink.String()

	parentlink, err := util.ImageURL(testStoreName, parent.ID)
	if !assert.NoError(t, err) {
		return
	}
	p := parentlink.String()

	eMeta := make(map[string]string)
	eMeta["foo"] = "bar"
	// expect our image back now that we've created it
	expected := &storage.GetImageOK{
		Payload: &models.Image{
			ID:       image.ID,
			SelfLink: &sl,
			Parent:   &p,
			Store:    testStoreURL.String(),
			Metadata: eMeta,
		},
	}

	result = s.GetImage(*params)
	if !assert.NotNil(t, result) {
		return
	}
	if !assert.Equal(t, expected, result) {
		return
	}
}