Пример #1
0
func (s *DetailFormatterSuite) TestFormatDetail(c *gc.C) {
	fp, err := charmresource.GenerateFingerprint(strings.NewReader("something"))
	c.Assert(err, jc.ErrorIsNil)

	svc := resource.Resource{
		Resource: charmresource.Resource{
			Meta: charmresource.Meta{
				Name:        "website",
				Description: "your website data",
				Type:        charmresource.TypeFile,
				Path:        "foobar",
			},
			Revision:    5,
			Origin:      charmresource.OriginStore,
			Fingerprint: fp,
			Size:        10,
		},
		Username:  "******",
		Timestamp: time.Now().Add(-1 * time.Hour * 24 * 365),
		ID:        "a-service/website",
		ServiceID: "a-service",
	}

	fp2, err := charmresource.GenerateFingerprint(strings.NewReader("other"))
	c.Assert(err, jc.ErrorIsNil)

	unit := resource.Resource{
		Resource: charmresource.Resource{
			Meta: charmresource.Meta{
				Name:        "website",
				Description: "your website data",
				Type:        charmresource.TypeFile,
				Path:        "foobar",
			},
			Revision:    7,
			Origin:      charmresource.OriginStore,
			Fingerprint: fp2,
			Size:        15,
		},
		Username:  "******",
		Timestamp: time.Now(),
		ID:        "a-service/website",
		ServiceID: "a-service",
	}
	tag := names.NewUnitTag("a-service/55")

	d, err := FormatDetailResource(tag, svc, unit, 8)
	c.Assert(err, jc.ErrorIsNil)
	c.Assert(d, gc.Equals,
		FormattedDetailResource{
			unitNumber:  55,
			UnitID:      "a-service/55",
			Expected:    FormatSvcResource(svc),
			Progress:    8,
			progress:    "80%",
			revProgress: "5 (fetching: 80%)",
			Unit:        FormatSvcResource(unit),
		},
	)
}
Пример #2
0
func (s *ClientSuite) TestResourceInfo(c *gc.C) {
	fp, err := resource.GenerateFingerprint(strings.NewReader("data"))
	c.Assert(err, jc.ErrorIsNil)
	apiRes := params.Resource{
		Name:        "name",
		Type:        "file",
		Path:        "foo.zip",
		Description: "something",
		Origin:      "store",
		Revision:    5,
		Fingerprint: fp.Bytes(),
		Size:        4,
	}
	s.wrapper.ReturnResourceMeta = apiRes

	client, err := newCachingClient(s.cache, nil, s.wrapper.makeWrapper)
	c.Assert(err, jc.ErrorIsNil)

	req := ResourceRequest{
		Charm:    charm.MustParseURL("cs:mysql"),
		Channel:  params.StableChannel,
		Name:     "name",
		Revision: 5,
	}
	res, err := client.ResourceInfo(req)
	c.Assert(err, jc.ErrorIsNil)
	expected, err := params.API2Resource(apiRes)
	c.Assert(err, jc.ErrorIsNil)
	c.Check(res, gc.DeepEquals, expected)
	// call #0 is a call to makeWrapper
	s.wrapper.stub.CheckCall(c, 1, "ResourceMeta", params.StableChannel, req.Charm, req.Name, req.Revision)
}
Пример #3
0
func (s *UploadSuite) TestPendingOkay(c *gc.C) {
	res, apiResult := newResourceResult(c, "a-service", "spam")
	uuid, err := utils.NewUUID()
	c.Assert(err, jc.ErrorIsNil)
	expected := uuid.String()
	s.response.Resource = apiResult.Resources[0]
	data := "<data>"
	fp, err := charmresource.GenerateFingerprint(strings.NewReader(data))
	c.Assert(err, jc.ErrorIsNil)
	req, err := http.NewRequest("PUT", "/services/a-service/resources/spam", nil)
	c.Assert(err, jc.ErrorIsNil)
	req.Header.Set("Content-Type", "application/octet-stream")
	req.Header.Set("Content-SHA384", fp.String())
	req.Header.Set("Content-Length", fmt.Sprint(len(data)))
	req.ContentLength = int64(len(data))
	req.URL.RawQuery = "pendingid=" + expected
	reader := &stubFile{stub: s.stub}
	reader.returnRead = strings.NewReader(data)
	s.facade.pendingIDs = []string{expected}
	cl := client.NewClient(s.facade, s, s.facade)

	uploadID, err := cl.AddPendingResource("a-service", res[0].Resource, reader)
	c.Assert(err, jc.ErrorIsNil)

	s.stub.CheckCallNames(c,
		"FacadeCall",
		"Read",
		"Read",
		"Seek",
		"Do",
	)
	s.stub.CheckCall(c, 4, "Do", req, reader, s.response)
	c.Check(uploadID, gc.Equals, expected)
}
Пример #4
0
func resourceHash(content string) charmresource.Fingerprint {
	fp, err := charmresource.GenerateFingerprint(strings.NewReader(content))
	if err != nil {
		panic(err)
	}
	return fp
}
Пример #5
0
func (s *UtilsSuite) newReader(c *gc.C, content string) (io.ReadCloser, charmresource.Fingerprint) {
	r := filetesting.NewStubFile(s.stub, bytes.NewBufferString(content))

	tmpReader := strings.NewReader(content)
	fp, err := charmresource.GenerateFingerprint(tmpReader)
	c.Assert(err, jc.ErrorIsNil)

	return r, fp
}
Пример #6
0
func (s *InternalClientSuite) TestListResources(c *gc.C) {
	fp, err := resource.GenerateFingerprint(strings.NewReader("data"))
	c.Assert(err, jc.ErrorIsNil)

	stable := params.Resource{
		Name:        "name",
		Type:        "file",
		Path:        "foo.zip",
		Description: "something",
		Origin:      "store",
		Revision:    5,
		Fingerprint: fp.Bytes(),
		Size:        4,
	}
	dev := params.Resource{
		Name:        "name2",
		Type:        "file",
		Path:        "bar.zip",
		Description: "something",
		Origin:      "store",
		Revision:    7,
		Fingerprint: fp.Bytes(),
		Size:        4,
	}
	s.lowLevel.ReturnListResourcesStable = map[string][]params.Resource{
		"cs:quantal/foo-1": []params.Resource{stable},
	}
	s.lowLevel.ReturnListResourcesDev = map[string][]params.Resource{
		"cs:quantal/bar-1": []params.Resource{dev},
	}

	client := Client{lowLevel: s.lowLevel}
	foo := charm.MustParseURL("cs:quantal/foo-1")
	bar := charm.MustParseURL("cs:quantal/bar-1")

	ret, err := client.ListResources([]CharmID{{
		URL:     foo,
		Channel: "stable",
	}, {
		URL:     bar,
		Channel: "development",
	}})
	c.Assert(err, jc.ErrorIsNil)

	stableOut, err := params.API2Resource(stable)
	c.Assert(err, jc.ErrorIsNil)

	devOut, err := params.API2Resource(dev)
	c.Assert(err, jc.ErrorIsNil)

	c.Assert(ret, gc.DeepEquals, [][]resource.Resource{
		{stableOut},
		{devOut},
	})
	s.lowLevel.stableStub.CheckCall(c, 0, "ListResources", params.StableChannel, []*charm.URL{foo})
	s.lowLevel.devStub.CheckCall(c, 0, "ListResources", params.DevelopmentChannel, []*charm.URL{bar})
}
Пример #7
0
func (s *SerializationSuite) TestDeserializeFingerprintOkay(c *gc.C) {
	content := "some data\n..."
	expected, err := charmresource.GenerateFingerprint(strings.NewReader(content))
	c.Assert(err, jc.ErrorIsNil)

	fp, err := resource.DeserializeFingerprint(expected.Bytes())
	c.Assert(err, jc.ErrorIsNil)

	c.Check(fp, jc.DeepEquals, expected)
}
Пример #8
0
func (s *ResourcesMongoSuite) TestResource2DocCharmstoreFull(c *gc.C) {
	content := "some data\n..."
	fp, err := charmresource.GenerateFingerprint(strings.NewReader(content))
	c.Assert(err, jc.ErrorIsNil)
	now := time.Now().UTC()

	applicationID := "a-application"
	docID := applicationResourceID("spam")
	res := resource.Resource{
		Resource: charmresource.Resource{
			Meta: charmresource.Meta{
				Name:        "spam",
				Type:        charmresource.TypeFile,
				Path:        "spam.tgz",
				Description: "you need this!",
			},
			Origin:      charmresource.OriginStore,
			Revision:    5,
			Fingerprint: fp,
			Size:        int64(len(content)),
		},
		ID:            "a-application/spam",
		PendingID:     "some-unique-ID",
		ApplicationID: applicationID,
		Username:      "******",
		Timestamp:     now,
	}
	doc := resource2doc(docID, storedResource{
		Resource:    res,
		storagePath: "application-a-application/resources/spam",
	})

	c.Check(doc, jc.DeepEquals, &resourceDoc{
		DocID:     docID,
		ID:        res.ID,
		PendingID: "some-unique-ID",

		ApplicationID: applicationID,

		Name:        "spam",
		Type:        "file",
		Path:        "spam.tgz",
		Description: "you need this!",

		Origin:      "store",
		Revision:    5,
		Fingerprint: fp.Bytes(),
		Size:        int64(len(content)),

		Username:  "******",
		Timestamp: now,

		StoragePath: "application-a-application/resources/spam",
	})
}
func (s *ListCharmSuite) TestChannelFlag(c *gc.C) {
	fp1, err := charmresource.GenerateFingerprint(strings.NewReader("abc"))
	c.Assert(err, jc.ErrorIsNil)
	fp2, err := charmresource.GenerateFingerprint(strings.NewReader("xyz"))
	c.Assert(err, jc.ErrorIsNil)
	resources := []charmresource.Resource{
		charmRes(c, "website", ".tgz", ".tgz of your website", string(fp1.Bytes())),
		charmRes(c, "music", ".mp3", "mp3 of your backing vocals", string(fp2.Bytes())),
	}
	s.client.ReturnListResources = [][]charmresource.Resource{resources}
	command := NewListCharmResourcesCommand(s.client)

	code, _, stderr := runCmd(c, command,
		"--channel", "development",
		"cs:a-charm",
	)

	c.Check(code, gc.Equals, 0)
	c.Check(stderr, gc.Equals, "")
	c.Check(command.channel, gc.Equals, "development")
}
Пример #10
0
func (s *ResourcesMongoSuite) TestDoc2BasicResourceCharmstoreFull(c *gc.C) {
	serviceID := "a-service"
	docID := serviceResourceID("spam")
	content := "some data\n..."
	fp, err := charmresource.GenerateFingerprint(strings.NewReader(content))
	c.Assert(err, jc.ErrorIsNil)
	now := time.Now().UTC()

	res, err := doc2basicResource(resourceDoc{
		DocID:     docID,
		ID:        "a-service/spam",
		PendingID: "some-unique-ID",

		ServiceID: serviceID,

		Name:        "spam",
		Type:        "file",
		Path:        "spam.tgz",
		Description: "you need this!",

		Origin:      "store",
		Revision:    5,
		Fingerprint: fp.Bytes(),
		Size:        int64(len(content)),

		Username:  "******",
		Timestamp: now,

		StoragePath: "service-a-service/resources/spam",
	})
	c.Assert(err, jc.ErrorIsNil)

	c.Check(res, jc.DeepEquals, resource.Resource{
		Resource: charmresource.Resource{
			Meta: charmresource.Meta{
				Name:        "spam",
				Type:        charmresource.TypeFile,
				Path:        "spam.tgz",
				Description: "you need this!",
			},
			Origin:      charmresource.OriginStore,
			Revision:    5,
			Fingerprint: fp,
			Size:        int64(len(content)),
		},
		ID:        "a-service/spam",
		PendingID: "some-unique-ID",
		ServiceID: serviceID,
		Username:  "******",
		Timestamp: now,
	})
}
Пример #11
0
func (s *ResourcesMongoSuite) TestDoc2BasicResourceUploadFull(c *gc.C) {
	applicationID := "a-application"
	docID := pendingResourceID("spam", "some-unique-ID-001")
	content := "some data\n..."
	fp, err := charmresource.GenerateFingerprint(strings.NewReader(content))
	c.Assert(err, jc.ErrorIsNil)
	now := time.Now().UTC()

	res, err := doc2basicResource(resourceDoc{
		DocID:         docID,
		ID:            "a-application/spam",
		ApplicationID: applicationID,
		PendingID:     "some-unique-ID-001",

		Name:        "spam",
		Type:        "file",
		Path:        "spam.tgz",
		Description: "you need this!",

		Origin:      "upload",
		Revision:    0,
		Fingerprint: fp.Bytes(),
		Size:        int64(len(content)),

		Username:  "******",
		Timestamp: now,

		StoragePath: "application-a-application/resources/spam",
	})
	c.Assert(err, jc.ErrorIsNil)

	c.Check(res, jc.DeepEquals, resource.Resource{
		Resource: charmresource.Resource{
			Meta: charmresource.Meta{
				Name:        "spam",
				Type:        charmresource.TypeFile,
				Path:        "spam.tgz",
				Description: "you need this!",
			},
			Origin:      charmresource.OriginUpload,
			Revision:    0,
			Fingerprint: fp,
			Size:        int64(len(content)),
		},
		ID:            "a-application/spam",
		PendingID:     "some-unique-ID-001",
		ApplicationID: applicationID,
		Username:      "******",
		Timestamp:     now,
	})
}
Пример #12
0
func (s *ResourcesMongoSuite) TestResource2DocUploadPending(c *gc.C) {
	content := "some data\n..."
	fp, err := charmresource.GenerateFingerprint(strings.NewReader(content))
	c.Assert(err, jc.ErrorIsNil)
	now := coretesting.ZeroTime()

	applicationID := "a-application"
	docID := pendingResourceID("spam", "some-unique-ID-001")
	res := resource.Resource{
		Resource: charmresource.Resource{
			Meta: charmresource.Meta{
				Name: "spam",
				Type: charmresource.TypeFile,
				Path: "spam.tgz",
			},
			Origin:      charmresource.OriginUpload,
			Fingerprint: fp,
			Size:        int64(len(content)),
		},
		ID:            applicationID + "/spam",
		PendingID:     "some-unique-ID-001",
		ApplicationID: applicationID,
		Username:      "******",
		Timestamp:     now,
	}
	doc := resource2doc(docID, storedResource{
		Resource:    res,
		storagePath: "application-a-application/resources/spam",
	})

	c.Check(doc, jc.DeepEquals, &resourceDoc{
		DocID:         docID,
		ID:            res.ID,
		PendingID:     "some-unique-ID-001",
		ApplicationID: applicationID,

		Name: "spam",
		Type: "file",
		Path: "spam.tgz",

		Origin:      "upload",
		Fingerprint: fp.Bytes(),
		Size:        int64(len(content)),

		Username:  "******",
		Timestamp: now,

		StoragePath: "application-a-application/resources/spam",
	})
}
Пример #13
0
func (s *ResourcesMongoSuite) TestDoc2Resource(c *gc.C) {
	serviceID := "a-service"
	docID := pendingResourceID("spam", "some-unique-ID-001")
	content := "some data\n..."
	fp, err := charmresource.GenerateFingerprint(strings.NewReader(content))
	c.Assert(err, jc.ErrorIsNil)
	now := time.Now().UTC()

	res, err := doc2resource(resourceDoc{
		DocID:     docID,
		ID:        "a-service/spam",
		PendingID: "some-unique-ID-001",
		ServiceID: serviceID,

		Name: "spam",
		Type: "file",
		Path: "spam.tgz",

		Origin:      "upload",
		Fingerprint: fp.Bytes(),
		Size:        int64(len(content)),

		Username:  "******",
		Timestamp: now,

		StoragePath: "service-a-service/resources/spam-some-unique-ID-001",
	})
	c.Assert(err, jc.ErrorIsNil)

	c.Check(res, jc.DeepEquals, storedResource{
		Resource: resource.Resource{
			Resource: charmresource.Resource{
				Meta: charmresource.Meta{
					Name: "spam",
					Type: charmresource.TypeFile,
					Path: "spam.tgz",
				},
				Origin:      charmresource.OriginUpload,
				Fingerprint: fp,
				Size:        int64(len(content)),
			},
			ID:        "a-service/spam",
			PendingID: "some-unique-ID-001",
			ServiceID: serviceID,
			Username:  "******",
			Timestamp: now,
		},
		storagePath: "service-a-service/resources/spam-some-unique-ID-001",
	})
}
Пример #14
0
func fakeParamsResource(name string, data []byte) params.Resource {
	fp, err := resource.GenerateFingerprint(bytes.NewReader(data))
	if err != nil {
		panic(err)
	}
	return params.Resource{
		Name:        name,
		Type:        "file",
		Path:        name + ".tgz",
		Description: "something about " + name,
		Revision:    len(name),
		Fingerprint: fp.Bytes(),
		Size:        int64(len(data)),
	}
}
Пример #15
0
func (s *ResourcesMongoSuite) TestResource2DocUploadBasic(c *gc.C) {
	content := "some data\n..."
	fp, err := charmresource.GenerateFingerprint(strings.NewReader(content))
	c.Assert(err, jc.ErrorIsNil)
	now := time.Now().UTC()

	serviceID := "a-service"
	docID := serviceResourceID("spam")
	res := resource.Resource{
		Resource: charmresource.Resource{
			Meta: charmresource.Meta{
				Name: "spam",
				Type: charmresource.TypeFile,
				Path: "spam.tgz",
			},
			Origin:      charmresource.OriginUpload,
			Fingerprint: fp,
			Size:        int64(len(content)),
		},
		ID:        serviceID + "/spam",
		ServiceID: serviceID,
		Username:  "******",
		Timestamp: now,
	}
	doc := resource2doc(docID, storedResource{
		Resource:    res,
		storagePath: "service-a-service/resources/spam",
	})

	c.Check(doc, jc.DeepEquals, &resourceDoc{
		DocID:     docID,
		ID:        res.ID,
		ServiceID: serviceID,

		Name: "spam",
		Type: "file",
		Path: "spam.tgz",

		Origin:      "upload",
		Fingerprint: fp.Bytes(),
		Size:        int64(len(content)),

		Username:  "******",
		Timestamp: now,

		StoragePath: "service-a-service/resources/spam",
	})
}
Пример #16
0
func (s *ResourcesMongoSuite) TestCharmStoreResource2DocFull(c *gc.C) {
	content := "some data\n..."
	fp, err := charmresource.GenerateFingerprint(strings.NewReader(content))
	c.Assert(err, jc.ErrorIsNil)
	now := time.Now().UTC()

	applicationID := "a-application"
	id := applicationID + "/spam"
	docID := applicationResourceID("spam") + "#charmstore"
	res := charmresource.Resource{
		Meta: charmresource.Meta{
			Name:        "spam",
			Type:        charmresource.TypeFile,
			Path:        "spam.tgz",
			Description: "you need this!",
		},
		Origin:      charmresource.OriginStore,
		Revision:    3,
		Fingerprint: fp,
		Size:        int64(len(content)),
	}
	doc := charmStoreResource2Doc(docID, charmStoreResource{
		Resource:      res,
		id:            id,
		applicationID: applicationID,
		lastPolled:    now,
	})

	c.Check(doc, jc.DeepEquals, &resourceDoc{
		DocID:         docID,
		ID:            id,
		ApplicationID: applicationID,

		Name:        "spam",
		Type:        "file",
		Path:        "spam.tgz",
		Description: "you need this!",

		Origin:      "store",
		Revision:    3,
		Fingerprint: fp.Bytes(),
		Size:        int64(len(content)),

		LastPolled: now,
	})
}
Пример #17
0
func (s *UpgradeCharmResourceSuite) TestUpgradeWithResources(c *gc.C) {
	myriakPath := testcharms.Repo.ClonedDir(c.MkDir(), "riak")
	err := ioutil.WriteFile(path.Join(myriakPath.Path, "metadata.yaml"), riakResourceMeta, 0644)
	c.Assert(err, jc.ErrorIsNil)

	data := []byte("some-data")
	fp, err := charmresource.GenerateFingerprint(bytes.NewReader(data))
	c.Assert(err, jc.ErrorIsNil)

	resourceFile := path.Join(c.MkDir(), "data.lib")
	err = ioutil.WriteFile(resourceFile, data, 0644)
	c.Assert(err, jc.ErrorIsNil)

	_, err = testing.RunCommand(c, application.NewUpgradeCharmCommand(),
		"riak", "--path="+myriakPath.Path, "--resource", "data="+resourceFile)
	c.Assert(err, jc.ErrorIsNil)

	resources, err := s.State.Resources()
	c.Assert(err, jc.ErrorIsNil)

	sr, err := resources.ListResources("riak")
	c.Assert(err, jc.ErrorIsNil)

	c.Check(sr.Resources, gc.HasLen, 1)

	c.Check(sr.Resources[0].ApplicationID, gc.Equals, "riak")

	// Most of this is just a sanity check... this is all tested elsewhere.
	c.Check(sr.Resources[0].PendingID, gc.Equals, "")
	c.Check(sr.Resources[0].Username, gc.Not(gc.Equals), "")
	c.Check(sr.Resources[0].ID, gc.Not(gc.Equals), "")
	c.Check(sr.Resources[0].Timestamp.IsZero(), jc.IsFalse)

	// Ensure we get the data we passed in from the metadata.yaml.
	c.Check(sr.Resources[0].Resource, gc.DeepEquals, charmresource.Resource{
		Meta: charmresource.Meta{
			Name:        "data",
			Type:        charmresource.TypeFile,
			Path:        "foo.lib",
			Description: "some comment",
		},
		Origin:      charmresource.OriginUpload,
		Fingerprint: fp,
		Size:        int64(len(data)),
	})
}
Пример #18
0
func (s *ResourcesMongoSuite) TestDoc2BasicResourceUploadBasic(c *gc.C) {
	applicationID := "a-application"
	docID := applicationResourceID("spam")
	content := "some data\n..."
	fp, err := charmresource.GenerateFingerprint(strings.NewReader(content))
	c.Assert(err, jc.ErrorIsNil)
	now := coretesting.NonZeroTime()

	res, err := doc2basicResource(resourceDoc{
		DocID:         docID,
		ID:            "a-application/spam",
		ApplicationID: applicationID,

		Name: "spam",
		Type: "file",
		Path: "spam.tgz",

		Origin:      "upload",
		Fingerprint: fp.Bytes(),
		Size:        int64(len(content)),

		Username:  "******",
		Timestamp: now,

		StoragePath: "application-a-application/resources/spam",
	})
	c.Assert(err, jc.ErrorIsNil)

	c.Check(res, jc.DeepEquals, resource.Resource{
		Resource: charmresource.Resource{
			Meta: charmresource.Meta{
				Name: "spam",
				Type: charmresource.TypeFile,
				Path: "spam.tgz",
			},
			Origin:      charmresource.OriginUpload,
			Fingerprint: fp,
			Size:        int64(len(content)),
		},
		ID:            "a-application/spam",
		ApplicationID: applicationID,
		Username:      "******",
		Timestamp:     now,
	})
}
Пример #19
0
func newUploadRequest(c *gc.C, name, service, content string) (*http.Request, io.Reader) {
	fp, err := charmresource.GenerateFingerprint(strings.NewReader(content))
	c.Assert(err, jc.ErrorIsNil)

	method := "PUT"
	urlStr := "https://api:17017/services/%s/resources/%s"
	urlStr += "?:service=%s&:resource=%s" // ...added by the mux.
	urlStr = fmt.Sprintf(urlStr, service, name, service, name)
	body := strings.NewReader(content)
	req, err := http.NewRequest(method, urlStr, body)
	c.Assert(err, jc.ErrorIsNil)

	req.Header.Set("Content-Type", "application/octet-stream")
	req.Header.Set("Content-Length", fmt.Sprint(len(content)))
	req.Header.Set("Content-SHA384", fp.String())

	return req, body
}
Пример #20
0
// GenerateContent returns a new Content for the given data stream.
func GenerateContent(reader io.ReadSeeker) (Content, error) {
	var sizer utils.SizeTracker
	sizingReader := io.TeeReader(reader, &sizer)
	fp, err := charmresource.GenerateFingerprint(sizingReader)
	if err != nil {
		return Content{}, errors.Trace(err)
	}
	if _, err := reader.Seek(0, os.SEEK_SET); err != nil {
		return Content{}, errors.Trace(err)
	}
	size := sizer.Size()

	content := Content{
		Data:        reader,
		Size:        size,
		Fingerprint: fp,
	}
	return content, nil
}
Пример #21
0
// NewCharmResource produces basic resource info for the given name
// and content. The origin is set set to "upload".
func NewCharmResource(c *gc.C, name, content string) charmresource.Resource {
	fp, err := charmresource.GenerateFingerprint(strings.NewReader(content))
	c.Assert(err, jc.ErrorIsNil)
	res := charmresource.Resource{
		Meta: charmresource.Meta{
			Name: name,
			Type: charmresource.TypeFile,
			Path: name + ".tgz",
		},
		Origin:      charmresource.OriginUpload,
		Revision:    0,
		Fingerprint: fp,
		Size:        int64(len(content)),
	}
	err = res.Validate()
	c.Assert(err, jc.ErrorIsNil)

	return res
}
Пример #22
0
func (s *SvcFormatterSuite) TestFormatSvcResource(c *gc.C) {
	fp, err := charmresource.GenerateFingerprint(strings.NewReader("something"))
	c.Assert(err, jc.ErrorIsNil)
	r := resource.Resource{
		Resource: charmresource.Resource{
			Meta: charmresource.Meta{
				Name:        "website",
				Description: "your website data",
				Type:        charmresource.TypeFile,
				Path:        "foobar",
			},
			Revision:    5,
			Origin:      charmresource.OriginStore,
			Fingerprint: fp,
			Size:        10,
		},
		Username:  "******",
		Timestamp: time.Now().Add(-1 * time.Hour * 24 * 365),
		ID:        "a-service/website",
		ServiceID: "a-service",
	}

	f := FormatSvcResource(r)
	c.Assert(f, gc.Equals, FormattedSvcResource{
		ID:               "a-service/website",
		ServiceID:        "a-service",
		Name:             r.Name,
		Type:             "file",
		Path:             r.Path,
		Used:             true,
		Revision:         r.Revision,
		Origin:           "store",
		Fingerprint:      fp.String(),
		Size:             10,
		Description:      r.Description,
		Timestamp:        r.Timestamp,
		Username:         r.Username,
		combinedRevision: "5",
		usedYesNo:        "yes",
		combinedOrigin:   "charmstore",
	})

}
Пример #23
0
func (s *UploadSuite) TestOkay(c *gc.C) {
	data := "<data>"
	_, s.response.Resource = newResource(c, "spam", "a-user", data)
	fp, err := charmresource.GenerateFingerprint(strings.NewReader(data))
	c.Assert(err, jc.ErrorIsNil)
	req, err := http.NewRequest("PUT", "/services/a-service/resources/spam", nil)
	c.Assert(err, jc.ErrorIsNil)
	req.Header.Set("Content-Type", "application/octet-stream")
	req.Header.Set("Content-SHA384", fp.String())
	req.Header.Set("Content-Length", fmt.Sprint(len(data)))
	req.ContentLength = int64(len(data))
	reader := &stubFile{stub: s.stub}
	reader.returnRead = strings.NewReader(data)
	cl := client.NewClient(s.facade, s, s.facade)

	err = cl.Upload("a-service", "spam", reader)
	c.Assert(err, jc.ErrorIsNil)

	s.stub.CheckCallNames(c, "Read", "Read", "Seek", "Do")
	s.stub.CheckCall(c, 3, "Do", req, reader, s.response)
}
Пример #24
0
func (s *ClientSuite) TestGetResource(c *gc.C) {
	fp, err := resource.GenerateFingerprint(strings.NewReader("data"))
	c.Assert(err, jc.ErrorIsNil)
	rc := ioutil.NopCloser(strings.NewReader("data"))
	s.wrapper.ReturnGetResource = csclient.ResourceData{
		ReadCloser: rc,
		Hash:       fp.String(),
		Size:       4,
	}
	apiRes := params.Resource{
		Name:        "name",
		Type:        "file",
		Path:        "foo.zip",
		Description: "something",
		Origin:      "store",
		Revision:    5,
		Fingerprint: fp.Bytes(),
		Size:        4,
	}
	s.wrapper.ReturnResourceMeta = apiRes

	client, err := newCachingClient(s.cache, nil, s.wrapper.makeWrapper)
	c.Assert(err, jc.ErrorIsNil)

	req := ResourceRequest{
		Charm:    charm.MustParseURL("cs:mysql"),
		Channel:  params.DevelopmentChannel,
		Name:     "name",
		Revision: 5,
	}
	data, err := client.GetResource(req)
	c.Assert(err, jc.ErrorIsNil)
	expected, err := params.API2Resource(apiRes)
	c.Assert(err, jc.ErrorIsNil)
	c.Check(data.Resource, gc.DeepEquals, expected)
	c.Check(data.ReadCloser, gc.DeepEquals, rc)
	// call #0 is a call to makeWrapper
	s.wrapper.stub.CheckCall(c, 1, "ResourceMeta", params.DevelopmentChannel, req.Charm, req.Name, req.Revision)
	s.wrapper.stub.CheckCall(c, 2, "GetResource", params.DevelopmentChannel, req.Charm, req.Name, req.Revision)
}
Пример #25
0
func charmRes(c *gc.C, name, suffix, description, content string) charmresource.Resource {
	if content == "" {
		content = name
	}

	fp, err := charmresource.GenerateFingerprint(strings.NewReader(content))
	c.Assert(err, jc.ErrorIsNil)

	res := charmresource.Resource{
		Meta: charmresource.Meta{
			Name:        name,
			Type:        charmresource.TypeFile,
			Path:        name + suffix,
			Description: description,
		},
		Origin:      charmresource.OriginStore,
		Revision:    1,
		Fingerprint: fp,
		Size:        int64(len(content)),
	}
	err = res.Validate()
	c.Assert(err, jc.ErrorIsNil)
	return res
}
Пример #26
0
func newFingerprint(c *gc.C, data string) charmresource.Fingerprint {
	fp, err := charmresource.GenerateFingerprint(strings.NewReader(data))
	c.Assert(err, jc.ErrorIsNil)
	return fp
}
Пример #27
0
func (s *ClientSuite) TestListResources(c *gc.C) {
	fp, err := resource.GenerateFingerprint(strings.NewReader("data"))
	c.Assert(err, jc.ErrorIsNil)

	stable := params.Resource{
		Name:        "name",
		Type:        "file",
		Path:        "foo.zip",
		Description: "something",
		Origin:      "store",
		Revision:    5,
		Fingerprint: fp.Bytes(),
		Size:        4,
	}
	dev := params.Resource{
		Name:        "name2",
		Type:        "file",
		Path:        "bar.zip",
		Description: "something",
		Origin:      "store",
		Revision:    7,
		Fingerprint: fp.Bytes(),
		Size:        4,
	}
	dev2 := params.Resource{
		Name:        "name3",
		Type:        "file",
		Path:        "bar.zip",
		Description: "something",
		Origin:      "store",
		Revision:    8,
		Fingerprint: fp.Bytes(),
		Size:        4,
	}

	s.wrapper.ReturnListResourcesStable = []resourceResult{oneResourceResult(stable), resourceResult{err: params.ErrNotFound}}
	s.wrapper.ReturnListResourcesDev = []resourceResult{oneResourceResult(dev), oneResourceResult(dev2)}

	client, err := newCachingClient(s.cache, nil, s.wrapper.makeWrapper)
	c.Assert(err, jc.ErrorIsNil)

	foo := charm.MustParseURL("cs:quantal/foo-1")
	bar := charm.MustParseURL("cs:quantal/bar-1")
	baz := charm.MustParseURL("cs:quantal/baz-1")

	ret, err := client.ListResources([]CharmID{{
		URL:     foo,
		Channel: params.StableChannel,
	}, {
		URL:     bar,
		Channel: params.DevelopmentChannel,
	}, {
		URL:     baz,
		Channel: params.DevelopmentChannel,
	}})
	c.Assert(err, jc.ErrorIsNil)

	stableOut, err := params.API2Resource(stable)
	c.Assert(err, jc.ErrorIsNil)

	devOut, err := params.API2Resource(dev)
	c.Assert(err, jc.ErrorIsNil)

	dev2Out, err := params.API2Resource(dev2)
	c.Assert(err, jc.ErrorIsNil)

	c.Assert(ret, gc.DeepEquals, [][]resource.Resource{
		{stableOut},
		{devOut},
		{dev2Out},
	})
	s.wrapper.stableStub.CheckCall(c, 0, "ListResources", params.StableChannel, foo)
	s.wrapper.devStub.CheckCall(c, 0, "ListResources", params.DevelopmentChannel, bar)
	s.wrapper.devStub.CheckCall(c, 1, "ListResources", params.DevelopmentChannel, baz)
}
Пример #28
0
func (s *ListCharmSuite) TestOutputFormats(c *gc.C) {
	fp1, err := charmresource.GenerateFingerprint(strings.NewReader("abc"))
	c.Assert(err, jc.ErrorIsNil)
	fp2, err := charmresource.GenerateFingerprint(strings.NewReader("xyz"))
	c.Assert(err, jc.ErrorIsNil)
	resources := []charmresource.Resource{
		charmRes(c, "website", ".tgz", ".tgz of your website", string(fp1.Bytes())),
		charmRes(c, "music", ".mp3", "mp3 of your backing vocals", string(fp2.Bytes())),
	}
	s.client.ReturnListResources = [][]charmresource.Resource{resources}

	formats := map[string]string{
		"tabular": `
RESOURCE  REVISION
website   1
music     1

`[1:],
		"yaml": `
- name: website
  type: file
  path: website.tgz
  description: .tgz of your website
  revision: 1
  fingerprint: 73100f01cf258766906c34a30f9a486f07259c627ea0696d97c4582560447f59a6df4a7cf960708271a30324b1481ef4
  size: 48
  origin: store
- name: music
  type: file
  path: music.mp3
  description: mp3 of your backing vocals
  revision: 1
  fingerprint: b0ea2a0f90267a8bd32848c65d7a61569a136f4e421b56127b6374b10a576d29e09294e620b4dcdee40f602115104bd5
  size: 48
  origin: store
`[1:],
		"json": strings.Replace(""+
			"["+
			"  {"+
			`    "name":"website",`+
			`    "type":"file",`+
			`    "path":"website.tgz",`+
			`    "description":".tgz of your website",`+
			`    "revision":1,`+
			`    "fingerprint":"73100f01cf258766906c34a30f9a486f07259c627ea0696d97c4582560447f59a6df4a7cf960708271a30324b1481ef4",`+
			`    "size":48,`+
			`    "origin":"store"`+
			"  },{"+
			`    "name":"music",`+
			`    "type":"file",`+
			`    "path":"music.mp3",`+
			`    "description":"mp3 of your backing vocals",`+
			`    "revision":1,`+
			`    "fingerprint":"b0ea2a0f90267a8bd32848c65d7a61569a136f4e421b56127b6374b10a576d29e09294e620b4dcdee40f602115104bd5",`+
			`    "size":48,`+
			`    "origin":"store"`+
			"  }"+
			"]\n",
			"  ", "", -1),
	}
	for format, expected := range formats {
		c.Logf("checking format %q", format)
		command := NewListCharmResourcesCommand()
		command.ResourceLister = s.client
		args := []string{
			"--format", format,
			"cs:a-charm",
		}
		code, stdout, stderr := runCmd(c, command, args...)
		c.Check(code, gc.Equals, 0)

		c.Check(stdout, gc.Equals, expected)
		c.Check(stderr, gc.Equals, "")
	}
}
func (s *UpgradeCharmStoreResourceSuite) TestDeployStarsaySuccess(c *gc.C) {
	testcharms.UploadCharm(c, s.client, "trusty/starsay-1", "starsay")

	// let's make a fake resource file to upload
	data := []byte("some-data")
	fp, err := charmresource.GenerateFingerprint(bytes.NewReader(data))
	c.Assert(err, jc.ErrorIsNil)

	resourceFile := path.Join(c.MkDir(), "data.xml")
	err = ioutil.WriteFile(resourceFile, data, 0644)
	c.Assert(err, jc.ErrorIsNil)

	ctx, err := testing.RunCommand(c, service.NewDeployCommand(), "trusty/starsay", "--resource", "upload-resource="+resourceFile)
	c.Assert(err, jc.ErrorIsNil)
	output := testing.Stderr(ctx)

	expectedOutput := `Added charm "cs:trusty/starsay-1" to the model.
Deploying charm "cs:trusty/starsay-1" with the charm series "trusty".
`
	c.Assert(output, gc.Equals, expectedOutput)
	s.assertCharmsUploaded(c, "cs:trusty/starsay-1")
	s.assertServicesDeployed(c, map[string]serviceInfo{
		"starsay": {charm: "cs:trusty/starsay-1"},
	})
	_, err = s.State.Unit("starsay/0")
	c.Assert(err, jc.ErrorIsNil)

	res, err := s.State.Resources()
	c.Assert(err, jc.ErrorIsNil)
	svcres, err := res.ListResources("starsay")
	c.Assert(err, jc.ErrorIsNil)

	sort.Sort(byname(svcres.Resources))

	c.Assert(svcres.Resources, gc.HasLen, 3)
	c.Check(svcres.Resources[2].Timestamp, gc.Not(gc.Equals), time.Time{})
	svcres.Resources[2].Timestamp = time.Time{}

	expectedResources := []resource.Resource{
		{
			Resource: charmresource.Resource{
				Meta: charmresource.Meta{
					Name:        "install-resource",
					Type:        charmresource.TypeFile,
					Path:        "gotta-have-it.txt",
					Description: "get things started",
				},
				Origin:   charmresource.OriginStore,
				Revision: -1,
			},
			ID:        "starsay/install-resource",
			ServiceID: "starsay",
		},
		{
			Resource: charmresource.Resource{
				Meta: charmresource.Meta{
					Name:        "store-resource",
					Type:        charmresource.TypeFile,
					Path:        "filename.tgz",
					Description: "One line that is useful when operators need to push it.",
				},
				Origin:   charmresource.OriginStore,
				Revision: -1,
			},
			ID:        "starsay/store-resource",
			ServiceID: "starsay",
		},
		{
			Resource: charmresource.Resource{
				Meta: charmresource.Meta{
					Name:        "upload-resource",
					Type:        charmresource.TypeFile,
					Path:        "somename.xml",
					Description: "Who uses xml anymore?",
				},
				Origin:      charmresource.OriginUpload,
				Revision:    0,
				Fingerprint: fp,
				Size:        int64(len(data)),
			},
			ID:        "starsay/upload-resource",
			ServiceID: "starsay",
			Username:  "******",
			// Timestamp is checked above
		},
	}

	c.Check(svcres.Resources, jc.DeepEquals, expectedResources)

	oldCharmStoreResources := make([]charmresource.Resource, len(svcres.CharmStoreResources))
	copy(oldCharmStoreResources, svcres.CharmStoreResources)

	sort.Sort(csbyname(oldCharmStoreResources))

	testcharms.UploadCharm(c, s.client, "trusty/starsay-2", "starsay")

	_, err = testing.RunCommand(c, service.NewUpgradeCharmCommand(), "starsay")
	c.Assert(err, jc.ErrorIsNil)

	s.assertServicesDeployed(c, map[string]serviceInfo{
		"starsay": {charm: "cs:trusty/starsay-2"},
	})

	res, err = s.State.Resources()
	c.Assert(err, jc.ErrorIsNil)
	svcres, err = res.ListResources("starsay")
	c.Assert(err, jc.ErrorIsNil)

	sort.Sort(byname(svcres.Resources))

	c.Assert(svcres.Resources, gc.HasLen, 3)
	c.Check(svcres.Resources[2].Timestamp, gc.Not(gc.Equals), time.Time{})
	svcres.Resources[2].Timestamp = time.Time{}

	// ensure that we haven't overridden the previously uploaded resource.
	c.Check(svcres.Resources, jc.DeepEquals, expectedResources)

	sort.Sort(csbyname(svcres.CharmStoreResources))
	c.Check(oldCharmStoreResources, gc.DeepEquals, svcres.CharmStoreResources)
}
Пример #30
0
func (HelpersSuite) TestAPIResult2ServiceResourcesOkay(c *gc.C) {
	fp, err := charmresource.NewFingerprint([]byte(fingerprint))
	c.Assert(err, jc.ErrorIsNil)
	now := time.Now()
	expected := resource.Resource{
		Resource: charmresource.Resource{
			Meta: charmresource.Meta{
				Name:        "spam",
				Type:        charmresource.TypeFile,
				Path:        "spam.tgz",
				Description: "you need it",
			},
			Origin:      charmresource.OriginUpload,
			Revision:    1,
			Fingerprint: fp,
			Size:        10,
		},
		ID:        "a-service/spam",
		PendingID: "some-unique-ID",
		ServiceID: "a-service",
		Username:  "******",
		Timestamp: now,
	}
	err = expected.Validate()
	c.Assert(err, jc.ErrorIsNil)

	unitExpected := resource.Resource{
		Resource: charmresource.Resource{
			Meta: charmresource.Meta{
				Name:        "unitspam",
				Type:        charmresource.TypeFile,
				Path:        "unitspam.tgz",
				Description: "you need it",
			},
			Origin:      charmresource.OriginUpload,
			Revision:    1,
			Fingerprint: fp,
			Size:        10,
		},
		ID:        "a-service/spam",
		PendingID: "some-unique-ID",
		ServiceID: "a-service",
		Username:  "******",
		Timestamp: now,
	}
	err = unitExpected.Validate()
	c.Assert(err, jc.ErrorIsNil)

	apiRes := api.Resource{
		CharmResource: api.CharmResource{
			Name:        "spam",
			Type:        "file",
			Path:        "spam.tgz",
			Description: "you need it",
			Origin:      "upload",
			Revision:    1,
			Fingerprint: []byte(fingerprint),
			Size:        10,
		},
		ID:        "a-service/spam",
		PendingID: "some-unique-ID",
		ServiceID: "a-service",
		Username:  "******",
		Timestamp: now,
	}

	unitRes := api.Resource{
		CharmResource: api.CharmResource{
			Name:        "unitspam",
			Type:        "file",
			Path:        "unitspam.tgz",
			Description: "you need it",
			Origin:      "upload",
			Revision:    1,
			Fingerprint: []byte(fingerprint),
			Size:        10,
		},
		ID:        "a-service/spam",
		PendingID: "some-unique-ID",
		ServiceID: "a-service",
		Username:  "******",
		Timestamp: now,
	}

	fp2, err := charmresource.GenerateFingerprint(strings.NewReader("boo!"))
	c.Assert(err, jc.ErrorIsNil)

	chRes := api.CharmResource{
		Name:        "unitspam2",
		Type:        "file",
		Path:        "unitspam.tgz2",
		Description: "you need it2",
		Origin:      "upload",
		Revision:    2,
		Fingerprint: fp2.Bytes(),
		Size:        11,
	}

	chExpected := charmresource.Resource{
		Meta: charmresource.Meta{
			Name:        "unitspam2",
			Type:        charmresource.TypeFile,
			Path:        "unitspam.tgz2",
			Description: "you need it2",
		},
		Origin:      charmresource.OriginUpload,
		Revision:    2,
		Fingerprint: fp2,
		Size:        11,
	}

	resources, err := api.APIResult2ServiceResources(api.ResourcesResult{
		Resources: []api.Resource{
			apiRes,
		},
		CharmStoreResources: []api.CharmResource{
			chRes,
		},
		UnitResources: []api.UnitResources{
			{
				Entity: params.Entity{
					Tag: "unit-foo-0",
				},
				Resources: []api.Resource{
					unitRes,
				},
				DownloadProgress: map[string]int64{
					unitRes.Name: 8,
				},
			},
		},
	})
	c.Assert(err, jc.ErrorIsNil)

	serviceResource := resource.ServiceResources{
		Resources: []resource.Resource{
			expected,
		},
		CharmStoreResources: []charmresource.Resource{
			chExpected,
		},
		UnitResources: []resource.UnitResources{
			{
				Tag: names.NewUnitTag("foo/0"),
				Resources: []resource.Resource{
					unitExpected,
				},
				DownloadProgress: map[string]int64{
					unitRes.Name: 8,
				},
			},
		},
	}

	c.Check(resources, jc.DeepEquals, serviceResource)
}