Esempio n. 1
0
// ListImages returns a list of images in a store
func (handler *StorageHandlersImpl) ListImages(params storage.ListImagesParams) middleware.Responder {
	u, err := util.ImageStoreNameToURL(params.StoreName)
	if err != nil {
		return storage.NewListImagesDefault(http.StatusInternalServerError).WithPayload(
			&models.Error{
				Code:    swag.Int64(http.StatusInternalServerError),
				Message: err.Error(),
			})
	}

	images, err := storageImageLayer.ListImages(context.TODO(), u, params.Ids)
	if err != nil {
		return storage.NewListImagesNotFound().WithPayload(
			&models.Error{
				Code:    swag.Int64(http.StatusNotFound),
				Message: err.Error(),
			})
	}

	result := make([]*models.Image, 0, len(images))

	for _, image := range images {
		result = append(result, convertImage(image))
	}
	return storage.NewListImagesOK().WithPayload(result)
}
Esempio n. 2
0
// GetImageStore checks to see if a named image store exists and returls the
// URL to it if so or error.
func (c *MockDataStore) GetImageStore(ctx context.Context, storeName string) (*url.URL, error) {
	u, err := util.ImageStoreNameToURL(storeName)
	if err != nil {
		return nil, err
	}
	return nil, fmt.Errorf("store (%s) doesn't exist", u.String())
}
Esempio n. 3
0
// WriteImage writes an image to an image store
func (handler *StorageHandlersImpl) WriteImage(params storage.WriteImageParams) middleware.Responder {
	u, err := util.ImageStoreNameToURL(params.StoreName)
	if err != nil {
		return storage.NewWriteImageDefault(http.StatusInternalServerError).WithPayload(
			&models.Error{
				Code:    swag.Int64(http.StatusInternalServerError),
				Message: err.Error(),
			})
	}

	parent := &spl.Image{
		Store: u,
		ID:    params.ParentID,
	}

	var meta map[string][]byte

	if params.Metadatakey != nil && params.Metadataval != nil {
		meta = map[string][]byte{*params.Metadatakey: []byte(*params.Metadataval)}
	}

	image, err := storageImageLayer.WriteImage(context.TODO(), parent, params.ImageID, meta, params.Sum, params.ImageFile)
	if err != nil {
		return storage.NewWriteImageDefault(http.StatusInternalServerError).WithPayload(
			&models.Error{
				Code:    swag.Int64(http.StatusInternalServerError),
				Message: err.Error(),
			})
	}
	i := convertImage(image)
	return storage.NewWriteImageCreated().WithPayload(i)
}
Esempio n. 4
0
File: image.go Progetto: vmware/vic
// GetImageStore checks to see if the image store exists on disk and returns an
// error or the store's URL.
func (v *ImageStore) GetImageStore(op trace.Operation, storeName string) (*url.URL, error) {
	u, err := util.ImageStoreNameToURL(storeName)
	if err != nil {
		return nil, err
	}

	p := v.imageStorePath(storeName)
	info, err := v.ds.Stat(op, p)
	if err != nil {
		return nil, err
	}

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

	if v.parents == nil {
		// This is startup.  Look for image directories without manifest files and
		// nuke them.
		if err := v.cleanup(op, u); err != nil {
			return nil, err
		}

		pm, err := restoreParentMap(op, v.ds, storeName)
		if err != nil {
			return nil, err
		}
		v.parents = pm
	}

	return u, nil
}
Esempio n. 5
0
// WriteImage writes an image to an image store
func (h *StorageHandlersImpl) WriteImage(params storage.WriteImageParams) middleware.Responder {
	u, err := util.ImageStoreNameToURL(params.StoreName)
	if err != nil {
		return storage.NewWriteImageDefault(http.StatusInternalServerError).WithPayload(
			&models.Error{
				Code:    swag.Int64(http.StatusInternalServerError),
				Message: err.Error(),
			})
	}

	parent := &spl.Image{
		Store: u,
		ID:    params.ParentID,
	}

	var meta map[string][]byte

	if params.Metadatakey != nil && params.Metadataval != nil {
		meta = map[string][]byte{*params.Metadatakey: []byte(*params.Metadataval)}
	}

	op := trace.NewOperation(context.Background(), fmt.Sprintf("WriteImage(%s)", params.ImageID))
	image, err := h.imageCache.WriteImage(op, parent, params.ImageID, meta, params.Sum, params.ImageFile)
	if err != nil {
		return storage.NewWriteImageDefault(http.StatusInternalServerError).WithPayload(
			&models.Error{
				Code:    swag.Int64(http.StatusInternalServerError),
				Message: err.Error(),
			})
	}
	i := convertImage(image)
	return storage.NewWriteImageCreated().WithPayload(i)
}
Esempio n. 6
0
// ListImages returns a list of images in a store
func (h *StorageHandlersImpl) ListImages(params storage.ListImagesParams) middleware.Responder {
	u, err := util.ImageStoreNameToURL(params.StoreName)
	if err != nil {
		return storage.NewListImagesDefault(http.StatusInternalServerError).WithPayload(
			&models.Error{
				Code:    swag.Int64(http.StatusInternalServerError),
				Message: err.Error(),
			})
	}

	op := trace.NewOperation(context.Background(), fmt.Sprintf("ListImages(%s, %q)", u.String(), params.Ids))
	images, err := h.imageCache.ListImages(op, u, params.Ids)
	if err != nil {
		return storage.NewListImagesNotFound().WithPayload(
			&models.Error{
				Code:    swag.Int64(http.StatusNotFound),
				Message: err.Error(),
			})
	}

	result := make([]*models.Image, 0, len(images))

	for _, image := range images {
		result = append(result, convertImage(image))
	}
	return storage.NewListImagesOK().WithPayload(result)
}
Esempio n. 7
0
File: image.go Progetto: kjplatz/vic
func Parse(u *url.URL) (*Image, error) {
	// Check the path isn't malformed.
	if !filepath.IsAbs(u.Path) {
		return nil, errors.New("invalid uri path")
	}

	segments := strings.Split(filepath.Clean(u.Path), "/")

	if segments[0] != util.StorageURLPath {
		return nil, errors.New("not a storage path")
	}

	if len(segments) < 3 {
		return nil, errors.New("uri path mismatch")
	}

	store, err := util.ImageStoreNameToURL(segments[2])
	if err != nil {
		return nil, err
	}

	id := segments[3]

	var SelfLink url.URL
	SelfLink = *u

	i := &Image{
		ID:       id,
		SelfLink: &SelfLink,
		Store:    store,
	}

	return i, nil
}
Esempio n. 8
0
func (c *NameLookupCache) CreateImageStore(op trace.Operation, storeName string) (*url.URL, error) {
	store, err := util.ImageStoreNameToURL(storeName)
	if err != nil {
		return nil, err
	}

	// Check for existence and rehydrate the cache if it exists on disk.
	_, err = c.GetImageStore(op, storeName)
	// we expect this not to exist.
	if err == nil {
		return nil, os.ErrExist
	}

	c.storeCacheLock.Lock()
	defer c.storeCacheLock.Unlock()

	store, err = c.DataStore.CreateImageStore(op, storeName)
	if err != nil {
		return nil, err
	}

	// Create the root image
	scratch, err := c.DataStore.WriteImage(op, &Image{Store: store}, Scratch.ID, nil, "", nil)
	if err != nil {
		return nil, err
	}

	indx := index.NewIndex()
	c.storeCache[*store] = indx
	if err = indx.Insert(scratch); err != nil {
		return nil, err
	}

	return store, nil
}
Esempio n. 9
0
func (c *MockDataStore) CreateImageStore(ctx context.Context, storeName string) (*url.URL, error) {
	u, err := util.ImageStoreNameToURL(storeName)
	if err != nil {
		return nil, err
	}

	return u, nil
}
Esempio n. 10
0
func (c *MockDataStore) CreateImageStore(op trace.Operation, storeName string) (*url.URL, error) {
	u, err := util.ImageStoreNameToURL(storeName)
	if err != nil {
		return nil, err
	}

	return u, nil
}
Esempio n. 11
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
	}
}
Esempio n. 12
0
// Cache population should be happening in order starting from parent(id1) to children(id4)
func TestPopulateCacheInExpectedOrder(t *testing.T) {
	logrus.SetLevel(logrus.DebugLevel)
	st := NewMockDataStore()
	op := trace.NewOperation(context.Background(), "test")

	storeURL, _ := util.ImageStoreNameToURL("testStore")

	storageURLStr := storeURL.String()

	url1, _ := url.Parse(storageURLStr + "/id1")
	url2, _ := url.Parse(storageURLStr + "/id2")
	url3, _ := url.Parse(storageURLStr + "/id3")
	url4, _ := url.Parse(storageURLStr + "/id4")
	scratchURL, _ := url.Parse(storageURLStr + Scratch.ID)

	img1 := &Image{ID: "id1", SelfLink: url1, ParentLink: scratchURL, Store: storeURL}
	img2 := &Image{ID: "id2", SelfLink: url2, ParentLink: url1, Store: storeURL}
	img3 := &Image{ID: "id3", SelfLink: url3, ParentLink: url2, Store: storeURL}
	img4 := &Image{ID: "id4", SelfLink: url4, ParentLink: url3, Store: storeURL}
	scratchImg := &Image{
		ID:         Scratch.ID,
		SelfLink:   scratchURL,
		ParentLink: scratchURL,
		Store:      storeURL,
	}

	// Order does matter for some reason.
	imageMap := map[string]*Image{
		img1.ID:       img1,
		img4.ID:       img4,
		img2.ID:       img2,
		img3.ID:       img3,
		scratchImg.ID: scratchImg,
	}

	st.db[*storeURL] = imageMap

	imageCache := NewLookupCache(st)
	imageCache.GetImageStore(op, "testStore")

	// Check if all images are available.
	imageIds := []string{"id1", "id2", "id3", "id4"}
	for _, imageID := range imageIds {
		v, _ := imageCache.GetImage(op, storeURL, imageID)
		assert.NotNil(t, v)
	}
}
Esempio n. 13
0
// GetImageStore checks to see if a named image store exists and returls the
// URL to it if so or error.
func (c *NameLookupCache) GetImageStore(ctx context.Context, storeName string) (*url.URL, error) {
	store, err := util.ImageStoreNameToURL(storeName)
	if err != nil {
		return nil, err
	}

	c.storeCacheLock.Lock()
	defer c.storeCacheLock.Unlock()

	// check the cache
	_, ok := c.storeCache[*store]
	if !ok {
		log.Info("Refreshing image cache from datastore.")
		// Store isn't in the cache.  Look it up in the datastore.
		storeName, err := util.ImageStoreName(store)
		if err != nil {
			return nil, err
		}

		// If the store doesn't exist, we'll fall out here.
		_, err = c.DataStore.GetImageStore(ctx, storeName)
		if err != nil {
			return nil, err
		}

		c.storeCache[*store] = make(map[string]Image)

		// Fall out here if there are no images.  We should at least have a scratch.
		images, err := c.DataStore.ListImages(ctx, store, nil)
		if err != nil {
			return nil, err
		}

		// add the images we retrieved to the cache.
		for _, v := range images {
			log.Infof("Imagestore: Found image %s on datastore.", v.ID)
			c.storeCache[*store][v.ID] = *v
		}

		// Assert there's a scratch
		if _, ok = c.storeCache[*store][Scratch.ID]; !ok {
			return nil, fmt.Errorf("Scratch does not exist.  Imagestore is corrrupt.")
		}
	}

	return store, nil
}
Esempio n. 14
0
File: image.go Progetto: vmware/vic
func (v *ImageStore) CreateImageStore(op trace.Operation, storeName string) (*url.URL, error) {
	// convert the store name to a port layer url.
	u, err := util.ImageStoreNameToURL(storeName)
	if err != nil {
		return nil, err
	}

	if _, err = v.ds.Mkdir(op, true, v.imageStorePath(storeName)); err != nil {
		return nil, err
	}

	if v.parents == nil {
		pm, err := restoreParentMap(op, v.ds, storeName)
		if err != nil {
			return nil, err
		}
		v.parents = pm
	}
	return u, nil
}
Esempio n. 15
0
// GetImage retrieves an image from a store
func (handler *StorageHandlersImpl) GetImage(params storage.GetImageParams) middleware.Responder {
	id := params.ID

	url, err := util.ImageStoreNameToURL(params.StoreName)
	if err != nil {
		return storage.NewGetImageDefault(http.StatusInternalServerError).WithPayload(
			&models.Error{
				Code:    swag.Int64(http.StatusInternalServerError),
				Message: err.Error(),
			})
	}

	image, err := storageImageLayer.GetImage(context.TODO(), url, id)
	if err != nil {
		e := &models.Error{Code: swag.Int64(http.StatusNotFound), Message: err.Error()}
		return storage.NewGetImageNotFound().WithPayload(e)
	}
	result := convertImage(image)
	return storage.NewGetImageOK().WithPayload(result)
}
Esempio n. 16
0
File: image.go Progetto: vmware/vic
func (v *ImageStore) ListImageStores(op trace.Operation) ([]*url.URL, error) {
	res, err := v.ds.Ls(op, v.imageStorePath(""))
	if err != nil {
		return nil, err
	}

	stores := []*url.URL{}
	for _, f := range res.File {
		folder, ok := f.(*types.FolderFileInfo)
		if !ok {
			continue
		}
		u, err := util.ImageStoreNameToURL(folder.Path)
		if err != nil {
			return nil, err
		}
		stores = append(stores, u)

	}

	return stores, nil
}
Esempio n. 17
0
// GetImage retrieves an image from a store
func (h *StorageHandlersImpl) GetImage(params storage.GetImageParams) middleware.Responder {
	id := params.ID

	url, err := util.ImageStoreNameToURL(params.StoreName)
	if err != nil {
		return storage.NewGetImageDefault(http.StatusInternalServerError).WithPayload(
			&models.Error{
				Code:    swag.Int64(http.StatusInternalServerError),
				Message: err.Error(),
			})
	}

	op := trace.NewOperation(context.Background(), fmt.Sprintf("GetImage(%s)", id))
	image, err := h.imageCache.GetImage(op, url, id)
	if err != nil {
		e := &models.Error{Code: swag.Int64(http.StatusNotFound), Message: err.Error()}
		return storage.NewGetImageNotFound().WithPayload(e)
	}

	result := convertImage(image)
	return storage.NewGetImageOK().WithPayload(result)
}
Esempio n. 18
0
// GetImageStore checks to see if a named image store exists and returls the
// URL to it if so or error.
func (c *NameLookupCache) GetImageStore(op trace.Operation, storeName string) (*url.URL, error) {
	store, err := util.ImageStoreNameToURL(storeName)
	if err != nil {
		return nil, err
	}

	c.storeCacheLock.Lock()
	defer c.storeCacheLock.Unlock()

	// check the cache
	_, ok := c.storeCache[*store]

	if !ok {
		infof("Refreshing image cache from datastore.")
		// Store isn't in the cache.  Look it up in the datastore.
		storeName, err := util.ImageStoreName(store)
		if err != nil {
			return nil, err
		}

		// If the store doesn't exist, we'll fall out here.
		_, err = c.DataStore.GetImageStore(op, storeName)
		if err != nil {
			return nil, err
		}

		idx := index.NewIndex()

		c.storeCache[*store] = idx

		// Add Scratch
		scratch, err := c.DataStore.GetImage(op, store, Scratch.ID)
		if err != nil {
			log.Errorf("ImageCache Error: looking up scratch on %s: %s", store.String(), err)
			return nil, ErrCorruptImageStore
		}

		if err = idx.Insert(scratch); err != nil {
			return nil, err
		}

		// XXX after creating the indx and populating the map, we can put the rest in a go routine

		// Fall out here if there are no images.  We should at least have a scratch.
		images, err := c.DataStore.ListImages(op, store, nil)
		if err != nil {
			return nil, err
		}

		debugf("Found %d images", len(images))

		// Build image map to simplify tree traversal.
		imageMap := make(map[string]*Image, len(images))
		for _, img := range images {
			if img.ID == Scratch.ID {
				continue
			}
			imageMap[img.Self()] = img
		}

		for k := range imageMap {
			parentTree(k, idx, imageMap)
		}
	}

	return store, nil
}