merge new-channels-model branch #71

Merged
merged 9 commits into from Mar 11, 2016
View
@@ -40,6 +40,7 @@ type Client struct {
bclient httpClient
header http.Header
statsDisabled bool
+ channel params.Channel
}
// Params holds parameters for creating a new charm store client.
@@ -101,6 +102,14 @@ func (c *Client) DisableStats() {
c.statsDisabled = true
}
+// WithChannel returns a new client whose requests are done using the
+// given channel.
+func (c *Client) WithChannel(channel params.Channel) *Client {
+ client := *c
+ client.channel = channel
+ return &client
+}
+
// SetHTTPHeader sets custom HTTP headers that will be sent to the charm store
// on each request.
func (c *Client) SetHTTPHeader(header http.Header) {
@@ -661,6 +670,11 @@ func (c *Client) DoWithBody(req *http.Request, path string, body io.ReadSeeker)
if err != nil {
return nil, errgo.Mask(err)
}
+ if c.channel != params.NoChannel {
+ values := u.Query()
+ values.Set("channel", string(c.channel))
+ u.RawQuery = values.Encode()
+ }
req.URL = u
// Send the request.
@@ -298,22 +298,27 @@ func (s *suite) TestPutSuccess(c *gc.C) {
}
func (s *suite) TestPutWithResponseSuccess(c *gc.C) {
- err := s.client.UploadCharmWithRevision(
- charm.MustParseURL("~charmers/development/wily/wordpress-42"),
- charmRepo.CharmDir("wordpress"),
- 42)
- c.Assert(err, gc.IsNil)
-
- publish := &params.PublishRequest{
- Published: true,
+ // There are currently no endpoints that return a response
+ // on PUT, so we'll create a fake server just to test
+ // the PutWithResponse method.
+ handler := func(w http.ResponseWriter, req *http.Request) {
+ io.Copy(w, req.Body)
}
- var result params.PublishResponse
- err = s.client.PutWithResponse("/~charmers/wily/wordpress-42/publish", publish, &result)
+ srv := httptest.NewServer(http.HandlerFunc(handler))
+ defer srv.Close()
+ client := csclient.New(csclient.Params{
+ URL: srv.URL,
+ })
+
+ sendBody := "hello"
+
+ var result string
+ err := client.PutWithResponse("/somewhere", sendBody, &result)
c.Assert(err, gc.IsNil)
- c.Assert(result.Id, jc.DeepEquals, charm.MustParseURL("~charmers/wily/wordpress-42"))
+ c.Assert(result, gc.Equals, sendBody)
// Check that the method accepts a nil result.
- err = s.client.PutWithResponse("/~charmers/wily/wordpress-42/publish", publish, nil)
+ err = client.PutWithResponse("/somewhere", sendBody, nil)
c.Assert(err, gc.IsNil)
}
@@ -992,6 +997,32 @@ func (s *suite) TestDo(c *gc.C) {
c.Assert(string(data), gc.Equals, `"bar"`)
}
+func (s *suite) TestWithChannel(c *gc.C) {
+ srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
+ fmt.Fprint(w, req.URL.Query().Encode())
+ }))
+ client := csclient.New(csclient.Params{
+ URL: srv.URL,
+ })
+
+ makeRequest := func(client *csclient.Client) string {
+ req, err := http.NewRequest("GET", "", nil)
+ c.Assert(err, jc.ErrorIsNil)
+ resp, err := client.DoWithBody(req, "/", nil)
+ c.Assert(err, jc.ErrorIsNil)
+ c.Assert(resp.StatusCode, gc.Equals, http.StatusOK)
+ b, err := ioutil.ReadAll(resp.Body)
+ c.Assert(err, jc.ErrorIsNil)
+ return string(b)
+ }
+
+ c.Assert(makeRequest(client), gc.Equals, "")
+ devClient := client.WithChannel(params.DevelopmentChannel)
+ c.Assert(makeRequest(devClient), gc.Equals, "channel=development")
+ // Ensure the original client has not been mutated.
+ c.Assert(makeRequest(client), gc.Equals, "")
+}
+
var metaBadTypeTests = []struct {
result interface{}
expectError string
@@ -35,6 +35,23 @@ const (
Admin = "admin"
)
+// Channel is the name of a channel in which an entity may be published.
+type Channel string
+
+const (
+ // DevelopmentChannel is the channel used for charms or bundles under development.
+ DevelopmentChannel Channel = "development"
+
+ // StableChannel is the channel used for stable charms or bundles.
+ StableChannel Channel = "stable"
+
+ // UnpublishedChannel is the default channel to which charms are uploaded.
+ UnpublishedChannel Channel = "unpublished"
+
+ // NoChannel represents where no channel has been specifically requested.
+ NoChannel Channel = ""
+)
+
// MetaAnyResponse holds the result of a meta/any request.
// See https://github.com/juju/charmstore/blob/v4/docs/API.md#get-idmetaany
type MetaAnyResponse EntityResult
@@ -242,6 +259,9 @@ type PromulgateRequest struct {
// PublishRequest holds the request of an id/publish PUT request.
// See https://github.com/juju/charmstore/blob/v4/docs/API.md#put-idpublish
type PublishRequest struct {
+ Channels []Channel
+ // TODO(rog) remove this when we've updated the charmstore dependency
+ // to use the new PublishRequest type.
Published bool
// Resources defines the resource revisions to use for the charm.
// Each resource in the charm's metadata.yaml (if any) must have its
@@ -257,6 +277,27 @@ type PublishResponse struct {
PromulgatedId *charm.URL `json:",omitempty"`
}
+// PublishedResponse holds the result of an id/meta/published GET request.
+type PublishedResponse struct {
+ // Channels holds an entry for each channel that the
+ // entity has been published to.
+ Info []PublishedInfo
+}
+
+// PublishedInfo holds information on a channel that an entity
+// has been published to.
+type PublishedInfo struct {
+ // Channel holds the value of the channel that
+ // the entity has been published to.
+ // This will never be "unpublished" as entities
+ // cannot be published to that channel.
+ Channel Channel
+
+ // Current holds whether the entity is the most
+ // recently published member of the channel.
+ Current bool
+}
+
// WhoAmIResponse holds the result of a whoami GET request.
// See https://github.com/juju/charmstore/blob/v4/docs/API.md#whoami
type WhoAmIResponse struct {