Merge lp:~dstroppa/juju-core/joyent-provider-storage into lp:~go-bot/juju-core/trunk

Proposed by Daniele Stroppa
Status: Work in progress
Proposed branch: lp:~dstroppa/juju-core/joyent-provider-storage
Merge into: lp:~go-bot/juju-core/trunk
Diff against target: 1198 lines (+685/-134)
13 files modified
.bzrignore (+2/-0)
dependencies.tsv (+1/-0)
provider/joyent/config.go (+41/-15)
provider/joyent/config_test.go (+63/-47)
provider/joyent/environ.go (+28/-13)
provider/joyent/environ_firewall.go (+3/-3)
provider/joyent/environ_instance.go (+4/-4)
provider/joyent/export_test.go (+3/-2)
provider/joyent/instance.go (+1/-1)
provider/joyent/joyent_test.go (+167/-14)
provider/joyent/provider.go (+5/-1)
provider/joyent/storage.go (+178/-34)
provider/joyent/storage_test.go (+189/-0)
To merge this branch: bzr merge lp:~dstroppa/juju-core/joyent-provider-storage
Reviewer Review Type Date Requested Status
Juju Engineering Pending
Review via email: mp+200851@code.launchpad.net

Commit message

provider/joyent: Implementation of storage

Add storage implementation to joyent provider. Also
pulls in new gojoyent library dependency.

R=gz, jameinel

Description of the change

Joyent Provider - Storage impl

https://codereview.appspot.com/49050044/

To post a comment you must log in.
Revision history for this message
Daniele Stroppa (dstroppa) wrote :

Reviewers: mp+200851_code.launchpad.net,

Message:
Please take a look.

Description:
Joyent Provider - Storage impl

https://code.launchpad.net/~dstroppa/juju-core/joyent-provider-storage/+merge/200851

(do not edit description out of merge proposal)

Please review this at https://codereview.appspot.com/49050044/

Affected files (+566, -151 lines):
   M .bzrignore
   A [revision details]
   M dependencies.tsv
   M provider/joyent/config.go
   M provider/joyent/config_test.go
   M provider/joyent/environ.go
   M provider/joyent/environ_firewall.go
   M provider/joyent/environ_instance.go
   M provider/joyent/instance.go
   M provider/joyent/joyent_test.go
   M provider/joyent/provider.go
   M provider/joyent/storage.go
   A provider/joyent/storage_test.go

Revision history for this message
Daniele Stroppa (dstroppa) wrote :
Revision history for this message
Martin Packman (gz) wrote :
Download full text (4.4 KiB)

Thanks for getting this next step up for review! Several things in need
of fixing:

https://codereview.appspot.com/49050044/diff/20001/dependencies.tsv
File dependencies.tsv (right):

https://codereview.appspot.com/49050044/diff/20001/dependencies.tsv#newcode7
dependencies.tsv:7:
launchpad.net/gojoyent bzr
<email address hidden> 47
It seems gojoyent in turn depends on github.com/nu7hatch/gouuid for
tests in localservices/manta/service.go

That would also need adding here - do we want it as a dep or should the
tests just generate sample uuids through some other method?

https://codereview.appspot.com/49050044/diff/20001/provider/joyent/config_test.go
File provider/joyent/config_test.go (right):

https://codereview.appspot.com/49050044/diff/20001/provider/joyent/config_test.go#newcode4
provider/joyent/config_test.go:4: package joyent
What's the reason to change this from external to internal testing?

https://codereview.appspot.com/49050044/diff/20001/provider/joyent/config_test.go#newcode26
provider/joyent/config_test.go:26: "sdc-key-id":
"12:c3:a7:cb:a2:29:e2:90:88:3f:04:53:3b:4e:75:40",
Not changed here, but duplicated later, so mentioning. These fake values
should be faker, rather than being for name and a real-looking key id.
Better to spot in test assertions and such like if it's testuser and
00:11:22:... or similar obvious made up values.

https://codereview.appspot.com/49050044/diff/20001/provider/joyent/joyent_test.go
File provider/joyent/joyent_test.go (right):

https://codereview.appspot.com/49050044/diff/20001/provider/joyent/joyent_test.go#newcode57
provider/joyent/joyent_test.go:57: "sdc-key-id":
"12:c3:a7:cb:a2:29:e2:90:88:3f:04:53:3b:4e:75:40",
These values look very similar to the earlier ones, perhaps they need to
be in a shared location and accessed from there. Otherwise, same comment
applies, user and key-id should be more obviously fake.

https://codereview.appspot.com/49050044/diff/20001/provider/joyent/storage.go
File provider/joyent/storage.go (right):

https://codereview.appspot.com/49050044/diff/20001/provider/joyent/storage.go#newcode83
provider/joyent/storage.go:83: // deleteContainer deletes the named
comtainer from the storage account.
Typo, 'coNtainer'.

https://codereview.appspot.com/49050044/diff/20001/provider/joyent/storage.go#newcode107
provider/joyent/storage.go:107: //return something that a random wget
can retrieve the object at, without any credentials
This may as well be an actual function doc comment.

https://codereview.appspot.com/49050044/diff/20001/provider/joyent/storage.go#newcode109
provider/joyent/storage.go:109: return s.manta.SignURL(path,
time.Now().Add(time.Minute*5))
I think the EC2 provider uses a mcuh longer duration, what a sensible
value is I'm less sure.

https://codereview.appspot.com/49050044/diff/20001/provider/joyent/storage.go#newcode125
provider/joyent/storage.go:125: //obj := r.Read()
Remove.

https://codereview.appspot.com/49050044/diff/20001/provider/joyent/storage.go#newcode141
provider/joyent/storage.go:141: func (s *joyentStorage) RemoveAll()
error {
This is logic I'm not wild about having done (and slightly differently)
in all provide...

Read more...

Revision history for this message
Daniele Stroppa (dstroppa) wrote :

https://codereview.appspot.com/49050044/diff/20001/provider/joyent/storage.go
File provider/joyent/storage.go (right):

https://codereview.appspot.com/49050044/diff/20001/provider/joyent/storage.go#newcode83
provider/joyent/storage.go:83: // deleteContainer deletes the named
comtainer from the storage account.
On 2014/01/09 17:50:34, gz wrote:
> Typo, 'coNtainer'.

Done.

https://codereview.appspot.com/49050044/diff/20001/provider/joyent/storage.go#newcode107
provider/joyent/storage.go:107: //return something that a random wget
can retrieve the object at, without any credentials
On 2014/01/09 17:50:34, gz wrote:
> This may as well be an actual function doc comment.

Done.

https://codereview.appspot.com/49050044/diff/20001/provider/joyent/storage.go#newcode109
provider/joyent/storage.go:109: return s.manta.SignURL(path,
time.Now().Add(time.Minute*5))
On 2014/01/09 17:50:34, gz wrote:
> I think the EC2 provider uses a mcuh longer duration, what a sensible
value is
> I'm less sure.

5 minutes is the value used in the Node.js SDK (used as reference). EC2,
Azure and OpenStack providers use 10 years. Changed to 10 years to be
consistent.

https://codereview.appspot.com/49050044/diff/20001/provider/joyent/storage.go#newcode125
provider/joyent/storage.go:125: //obj := r.Read()
On 2014/01/09 17:50:34, gz wrote:
> Remove.

Done.

https://codereview.appspot.com/49050044/

Revision history for this message
Daniele Stroppa (dstroppa) wrote :

https://codereview.appspot.com/49050044/diff/20001/dependencies.tsv
File dependencies.tsv (right):

https://codereview.appspot.com/49050044/diff/20001/dependencies.tsv#newcode7
dependencies.tsv:7:
launchpad.net/gojoyent bzr
<email address hidden> 47
On 2014/01/09 17:50:34, gz wrote:
> It seems gojoyent in turn depends on github.com/nu7hatch/gouuid for
tests in
> localservices/manta/service.go

> That would also need adding here - do we want it as a dep or should
the tests
> just generate sample uuids through some other method?

Replaced the gouuid dep with a custom method implemented with std libs.

https://codereview.appspot.com/49050044/

Revision history for this message
Daniele Stroppa (dstroppa) wrote :

https://codereview.appspot.com/49050044/diff/20001/provider/joyent/config_test.go
File provider/joyent/config_test.go (right):

https://codereview.appspot.com/49050044/diff/20001/provider/joyent/config_test.go#newcode4
provider/joyent/config_test.go:4: package joyent
On 2014/01/09 17:50:34, gz wrote:
> What's the reason to change this from external to internal testing?

No reason actually, it was just a mistake. Changed it to external
testing.

https://codereview.appspot.com/49050044/

Revision history for this message
Daniele Stroppa (dstroppa) wrote :

https://codereview.appspot.com/49050044/diff/20001/provider/joyent/config_test.go
File provider/joyent/config_test.go (right):

https://codereview.appspot.com/49050044/diff/20001/provider/joyent/config_test.go#newcode26
provider/joyent/config_test.go:26: "sdc-key-id":
"12:c3:a7:cb:a2:29:e2:90:88:3f:04:53:3b:4e:75:40",
On 2014/01/09 17:50:34, gz wrote:
> Not changed here, but duplicated later, so mentioning. These fake
values should
> be faker, rather than being for name and a real-looking key id. Better
to spot
> in test assertions and such like if it's testuser and 00:11:22:... or
similar
> obvious made up values.

Changed to obvious made up values.

https://codereview.appspot.com/49050044/

Revision history for this message
Daniele Stroppa (dstroppa) wrote :

https://codereview.appspot.com/49050044/diff/20001/provider/joyent/joyent_test.go
File provider/joyent/joyent_test.go (right):

https://codereview.appspot.com/49050044/diff/20001/provider/joyent/joyent_test.go#newcode57
provider/joyent/joyent_test.go:57: "sdc-key-id":
"12:c3:a7:cb:a2:29:e2:90:88:3f:04:53:3b:4e:75:40",
On 2014/01/09 17:50:34, gz wrote:
> These values look very similar to the earlier ones, perhaps they need
to be in a
> shared location and accessed from there. Otherwise, same comment
applies, user
> and key-id should be more obviously fake.

Changed to valid fake values.

https://codereview.appspot.com/49050044/

Revision history for this message
Daniele Stroppa (dstroppa) wrote :

https://codereview.appspot.com/49050044/diff/20001/provider/joyent/storage_test.go
File provider/joyent/storage_test.go (right):

https://codereview.appspot.com/49050044/diff/20001/provider/joyent/storage_test.go#newcode1
provider/joyent/storage_test.go:1: // Copyright 2013 Joyent Inc.
On 2014/01/09 17:50:34, gz wrote:
> All the tests in this file bar TestURL fail when I run them here, with
> variations on:

> FAIL: storage_test.go:140: storageSuite.TestCreateContainer

> storage_test.go:143:
> s.assertContainer(mantaStorage, c)
> storage_test.go:43:
> c.Assert(err, gc.IsNil)
> ... value *errors.gojoyentError =
> &errors.gojoyentError{error:(*errors.errorString)(0xc2002f33b0),
> errcode:"UnkownError", cause:(*errors.gojoyentError)(0xc200304510)}
("failed to
> create directory: juju-test\ncaused by: Bad request
> https://us-east.manta.joyent.com/dstroppa/stor/juju-test%5Cncaused by:
request
> (https://us-east.manta.joyent.com/dstroppa/stor/juju-test) returned
unexpected
> status: 400; error info:
{\"code\":\"InvalidHeader\",\"message\":\"Authorization
> header invalid: signature was not specified\"}")

> It seems they're escaping isolation, rather than using the test
services?

Changed the storage test to run against the local services instead of
the Joyent Live environment

https://codereview.appspot.com/49050044/

Revision history for this message
Daniele Stroppa (dstroppa) wrote :
Revision history for this message
Martin Packman (gz) wrote :

LGTM, should be ready to go with a settled gojoyent version.

https://codereview.appspot.com/49050044/

Revision history for this message
William Reade (fwereade) wrote :

Martin, is this ready to land now?

Revision history for this message
John A Meinel (jameinel) wrote :

On 2014/01/23 16:23:42, gz wrote:
> LGTM, should be ready to go with a settled gojoyent version.

We're still hanging on this 10 days later. It does seem like we should
just land it so that we can start ratcheting forward rather than
delaying it.

https://codereview.appspot.com/49050044/

Revision history for this message
Daniele Stroppa (dstroppa) wrote :
Revision history for this message
Go Bot (go-bot) wrote :

The attempt to merge lp:~dstroppa/juju-core/joyent-provider-storage into lp:juju-core failed. Below is the output from the failed tests.

provider/joyent/storage.go:16:2: cannot find package "launchpad.net/gojoyent/client" in any of:
 /usr/lib/go/src/pkg/launchpad.net/gojoyent/client (from $GOROOT)
 /home/tarmac/trees/src/launchpad.net/gojoyent/client (from $GOPATH)
provider/joyent/storage.go:17:2: cannot find package "launchpad.net/gojoyent/jpc" in any of:
 /usr/lib/go/src/pkg/launchpad.net/gojoyent/jpc (from $GOROOT)
 /home/tarmac/trees/src/launchpad.net/gojoyent/jpc (from $GOPATH)
provider/joyent/storage.go:18:2: cannot find package "launchpad.net/gojoyent/manta" in any of:
 /usr/lib/go/src/pkg/launchpad.net/gojoyent/manta (from $GOROOT)
 /home/tarmac/trees/src/launchpad.net/gojoyent/manta (from $GOPATH)

Revision history for this message
Go Bot (go-bot) wrote :
Download full text (9.9 KiB)

The attempt to merge lp:~dstroppa/juju-core/joyent-provider-storage into lp:juju-core failed. Below is the output from the failed tests.

----------------------------------------------------------------------
FAIL: dependencies_test.go:30: dependenciesTest.TestDependenciesTsvFormat

dependencies_test.go:40:
    c.Assert(segments, gc.HasLen, 4)
... obtained []string = []string{"launchpad.net/gojoyent bzr <email address hidden> 61"}
... n int = 4

OOPS: 0 passed, 1 FAILED
--- FAIL: Test (0.00 seconds)
FAIL
FAIL launchpad.net/juju-core 0.017s
ok launchpad.net/juju-core/agent 1.521s
ok launchpad.net/juju-core/agent/tools 0.280s
ok launchpad.net/juju-core/bzr 8.022s
ok launchpad.net/juju-core/cert 3.132s
ok launchpad.net/juju-core/charm 0.629s
? launchpad.net/juju-core/charm/hooks [no test files]
? launchpad.net/juju-core/charm/testing [no test files]
ok launchpad.net/juju-core/cloudinit 0.061s
ok launchpad.net/juju-core/cloudinit/sshinit 1.125s
ok launchpad.net/juju-core/cmd 0.276s
ok launchpad.net/juju-core/cmd/charm-admin 0.832s
? launchpad.net/juju-core/cmd/charmd [no test files]
? launchpad.net/juju-core/cmd/charmload [no test files]
ok launchpad.net/juju-core/cmd/juju 283.660s
ok launchpad.net/juju-core/cmd/jujud 76.837s
ok launchpad.net/juju-core/cmd/plugins/juju-metadata 12.096s
? launchpad.net/juju-core/cmd/plugins/juju-restore [no test files]
ok launchpad.net/juju-core/constraints 0.030s
ok launchpad.net/juju-core/container 0.039s
ok launchpad.net/juju-core/container/factory 0.053s
ok launchpad.net/juju-core/container/kvm 0.300s
ok launchpad.net/juju-core/container/kvm/mock 0.045s
? launchpad.net/juju-core/container/kvm/testing [no test files]
ok launchpad.net/juju-core/container/lxc 0.407s
? launchpad.net/juju-core/container/lxc/mock [no test files]
? launchpad.net/juju-core/container/lxc/testing [no test files]
? launchpad.net/juju-core/container/testing [no test files]
ok launchpad.net/juju-core/downloader 5.444s
ok launchpad.net/juju-core/environs 3.281s
ok launchpad.net/juju-core/environs/bootstrap 5.837s
ok launchpad.net/juju-core/environs/cloudinit 0.874s
ok launchpad.net/juju-core/environs/config 4.834s
ok launchpad.net/juju-core/environs/configstore 0.043s
ok launchpad.net/juju-core/environs/filestorage 0.032s
ok launchpad.net/juju-core/environs/httpstorage 1.134s
ok launchpad.net/juju-core/environs/imagemetadata 0.739s
? launchpad.net/juju-core/environs/imagemetadata/testing [no test files]
ok launchpad.net/juju-core/environs/instances 0.064s
ok launchpad.net/juju-core/environs/jujutest 0.308s
ok launchpad.net/juju-core/environs/manual 13.000s
ok launchpad.net/juju-core/environs/simplestreams 0.332s
? launchpad.net/juju-core/environs/simplestreams/testing [no test files]
ok launchpad.net/juju-core/environs/sshstorage 1.302s
ok launchpad.net/juju-core/environs/storage 1.177s
ok launchpad.net/juju-core/environs/sync 43.801s
ok launchpad.net/juju-core/environs/testing 0.226s
ok launchpad.net/juju-core/environs/tools 7.397s
? launchpad.net/juju-core/environs/tools/testing [no test fi...

Revision history for this message
Go Bot (go-bot) wrote :

There are additional revisions which have not been approved in review. Please seek review and approval of these new revisions.

Revision history for this message
Go Bot (go-bot) wrote :
Download full text (9.5 KiB)

The attempt to merge lp:~dstroppa/juju-core/joyent-provider-storage into lp:juju-core failed. Below is the output from the failed tests.

ok launchpad.net/juju-core 0.017s
ok launchpad.net/juju-core/agent 1.822s
ok launchpad.net/juju-core/agent/tools 0.422s
ok launchpad.net/juju-core/bzr 13.422s
ok launchpad.net/juju-core/cert 3.682s
ok launchpad.net/juju-core/charm 0.843s
? launchpad.net/juju-core/charm/hooks [no test files]
? launchpad.net/juju-core/charm/testing [no test files]
ok launchpad.net/juju-core/cloudinit 0.055s
ok launchpad.net/juju-core/cloudinit/sshinit 1.303s
ok launchpad.net/juju-core/cmd 0.245s
ok launchpad.net/juju-core/cmd/charm-admin 0.940s
? launchpad.net/juju-core/cmd/charmd [no test files]
? launchpad.net/juju-core/cmd/charmload [no test files]
ok launchpad.net/juju-core/cmd/juju 317.348s
ok launchpad.net/juju-core/cmd/jujud 83.188s
ok launchpad.net/juju-core/cmd/plugins/juju-metadata 15.117s
? launchpad.net/juju-core/cmd/plugins/juju-restore [no test files]
ok launchpad.net/juju-core/constraints 0.056s
ok launchpad.net/juju-core/container 0.148s
ok launchpad.net/juju-core/container/factory 0.070s
ok launchpad.net/juju-core/container/kvm 0.403s
ok launchpad.net/juju-core/container/kvm/mock 0.093s
? launchpad.net/juju-core/container/kvm/testing [no test files]
ok launchpad.net/juju-core/container/lxc 0.531s
? launchpad.net/juju-core/container/lxc/mock [no test files]
? launchpad.net/juju-core/container/lxc/testing [no test files]
? launchpad.net/juju-core/container/testing [no test files]
ok launchpad.net/juju-core/downloader 5.339s
ok launchpad.net/juju-core/environs 3.208s
ok launchpad.net/juju-core/environs/bootstrap 5.410s
ok launchpad.net/juju-core/environs/cloudinit 0.652s
ok launchpad.net/juju-core/environs/config 5.612s
ok launchpad.net/juju-core/environs/configstore 0.189s
ok launchpad.net/juju-core/environs/filestorage 0.032s
ok launchpad.net/juju-core/environs/httpstorage 1.047s
ok launchpad.net/juju-core/environs/imagemetadata 1.067s
? launchpad.net/juju-core/environs/imagemetadata/testing [no test files]
ok launchpad.net/juju-core/environs/instances 0.982s
ok launchpad.net/juju-core/environs/jujutest 0.280s
ok launchpad.net/juju-core/environs/manual 14.988s
ok launchpad.net/juju-core/environs/simplestreams 2.050s
? launchpad.net/juju-core/environs/simplestreams/testing [no test files]
ok launchpad.net/juju-core/environs/sshstorage 3.161s
ok launchpad.net/juju-core/environs/storage 1.238s
ok launchpad.net/juju-core/environs/sync 43.628s
ok launchpad.net/juju-core/environs/testing 0.784s
ok launchpad.net/juju-core/environs/tools 7.430s
? launchpad.net/juju-core/environs/tools/testing [no test files]
ok launchpad.net/juju-core/errors 0.016s
ok launchpad.net/juju-core/instance 0.027s
? launchpad.net/juju-core/instance/testing [no test files]
ok launchpad.net/juju-core/juju 30.506s
ok launchpad.net/juju-core/juju/osenv 0.033s
? launchpad.net/juju-core/juju/testing [no test files]
ok launchpad.net/juju-core/log 0.061s
ok launchpad.net/juju-core/log/syslog 0.038s
? launchpad.net/juju-c...

Read more...

Revision history for this message
Go Bot (go-bot) wrote :
Download full text (273.8 KiB)

The attempt to merge lp:~dstroppa/juju-core/joyent-provider-storage into lp:juju-core failed. Below is the output from the failed tests.

ok launchpad.net/juju-core 0.939s
ok launchpad.net/juju-core/agent 43.657s
ok launchpad.net/juju-core/agent/tools 12.708s
ok launchpad.net/juju-core/bzr 411.407s
ok launchpad.net/juju-core/cert 184.764s
ok launchpad.net/juju-core/charm 28.462s
? launchpad.net/juju-core/charm/hooks [no test files]
? launchpad.net/juju-core/charm/testing [no test files]
ok launchpad.net/juju-core/cloudinit 2.280s
ok launchpad.net/juju-core/cloudinit/sshinit 45.480s
ok launchpad.net/juju-core/cmd 8.938s
ok launchpad.net/juju-core/cmd/charm-admin 21.053s
? launchpad.net/juju-core/cmd/charmd [no test files]
? launchpad.net/juju-core/cmd/charmload [no test files]
*** Test killed: ran too long (10m0s).
FAIL launchpad.net/juju-core/cmd/juju 600.586s

----------------------------------------------------------------------
FAIL: machine_test.go:197: MachineSuite.TestDyingMachine

[LOG] 39.51530 DEBUG juju.environs.configstore Making /tmp/gocheck-8249030965139585917/1/home/ubuntu/.juju/environments
[LOG] 44.18314 DEBUG juju.environs.tools reading v1.* tools
[LOG] 44.18320 INFO juju environs/testing: uploading FAKE tools 1.17.4-precise-amd64
[LOG] 44.18412 DEBUG juju.environs.tools no architecture specified when finding tools, looking for any
[LOG] 44.18413 DEBUG juju.environs.tools no series specified when finding tools, looking for any
[LOG] 44.18430 DEBUG juju.environs.simplestreams fetchData failed for "tools/streams/v1/index.sjson": file "tools/streams/v1/index.sjson" not found not found
[LOG] 44.18432 DEBUG juju.environs.simplestreams cannot load index "streams/v1/index.sjson": invalid URL "tools/streams/v1/index.sjson" not found
[LOG] 44.18436 DEBUG juju.environs.simplestreams fetchData failed for "tools/streams/v1/index.json": file "tools/streams/v1/index.json" not found not found
[LOG] 44.18437 DEBUG juju.environs.simplestreams cannot load index "streams/v1/index.json": invalid URL "tools/streams/v1/index.json" not found
[LOG] 44.18482 INFO juju.environs.tools Writing tools/streams/v1/index.json
[LOG] 44.18504 INFO juju.environs.tools Writing tools/streams/v1/com.ubuntu.juju:released:tools.json
[LOG] 44.18508 INFO juju.environs.bootstrap bootstrapping environment "dummyenv"
[LOG] 44.18512 DEBUG juju.environs.bootstrap looking for bootstrap tools: series="precise", arch=<nil>, version=1.17.4
[LOG] 44.18514 INFO juju.environs.tools reading tools with major.minor version 1.17
[LOG] 44.18515 INFO juju.environs.tools filtering tools by version: 1.17.4
[LOG] 44.18517 INFO juju.environs.tools filtering tools by series: precise
[LOG] 44.18519 DEBUG juju.environs.tools no architecture specified when finding tools, looking for any
[LOG] 44.18522 DEBUG juju.environs.simplestreams fetchData failed for "tools/streams/v1/index.sjson": file "tools/streams/v1/index.sjson" not found not found
[LOG] 44.18524 DEBUG juju.environs.simplestreams cannot load index "streams/v1/index.sjson": invalid URL "tools/streams/v1/index.sjson" not found
[LOG] 44.18534 DEBUG juju.environs.simplestreams fetchData failed for "tools/s...

Revision history for this message
Go Bot (go-bot) wrote :

The attempt to merge lp:~dstroppa/juju-core/joyent-provider-storage into lp:juju-core failed. Below is the output from the failed tests.

provider/joyent/storage.go:16:2: cannot find package "launchpad.net/gojoyent/client" in any of:
 /usr/lib/go/src/pkg/launchpad.net/gojoyent/client (from $GOROOT)
 /home/tarmac/trees/src/launchpad.net/gojoyent/client (from $GOPATH)
provider/joyent/storage.go:17:2: cannot find package "launchpad.net/gojoyent/jpc" in any of:
 /usr/lib/go/src/pkg/launchpad.net/gojoyent/jpc (from $GOROOT)
 /home/tarmac/trees/src/launchpad.net/gojoyent/jpc (from $GOPATH)
provider/joyent/storage.go:18:2: cannot find package "launchpad.net/gojoyent/manta" in any of:
 /usr/lib/go/src/pkg/launchpad.net/gojoyent/manta (from $GOROOT)
 /home/tarmac/trees/src/launchpad.net/gojoyent/manta (from $GOPATH)

Unmerged revisions

1983. By Daniele Stroppa

Updated dependencies.tsv: tabs instead of spaces

1982. By Daniele Stroppa

Merged trunk

1981. By Daniele Stroppa

Updated GoJoyent dependency

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file '.bzrignore'
2--- .bzrignore 2013-08-27 15:27:47 +0000
3+++ .bzrignore 2014-02-27 18:08:22 +0000
4@@ -8,3 +8,5 @@
5 .emacs.desktop
6 .emacs.desktop.lock
7 *.test
8+.idea
9+add-joyent-provider.iml
10
11=== modified file 'dependencies.tsv'
12--- dependencies.tsv 2014-02-25 22:19:30 +0000
13+++ dependencies.tsv 2014-02-27 18:08:22 +0000
14@@ -6,6 +6,7 @@
15 launchpad.net/gnuflag bzr roger.peppe@canonical.com-20121003093437-zcyyw0lpvj2nifpk 12
16 launchpad.net/goamz bzr roger.peppe@canonical.com-20131218155244-hbnkvlkkzy3vmlh9 44
17 launchpad.net/gocheck bzr gustavo@niemeyer.net-20130302024745-6ikofwq2c03h7giu 85
18+launchpad.net/gojoyent bzr daniele.stroppa@joyent.com-20140225172734-ltce6n3vrhj3cngg 61
19 launchpad.net/golxc bzr ian.booth@canonical.com-20140116225718-lvoikrb0me6zugin 6
20 launchpad.net/gomaasapi bzr ian.booth@canonical.com-20131017011445-m1hmr0ap14osd7li 47
21 launchpad.net/goose bzr tarmac-20140124165235-h9rloooc531udms5 116
22
23=== modified file 'provider/joyent/config.go'
24--- provider/joyent/config.go 2013-11-21 17:53:05 +0000
25+++ provider/joyent/config.go 2014-02-27 18:08:22 +0000
26@@ -22,16 +22,21 @@
27 # sdc-user: <secret>
28 # Can be set via env variables, or specified here
29 # sdc-key-id: <secret>
30- # region defaults to us-west-1, override if required
31- # sdc-region: us-west-1
32+ # url defaults to us-west-1 DC, override if required
33+ # sdc-url: https://us-west-1.api.joyentcloud.com
34
35 # Manta config
36 # Can be set via env variables, or specified here
37 # manta-user: <secret>
38 # Can be set via env variables, or specified here
39 # manta-key-id: <secret>
40- # region defaults to us-east, override if required
41- # manta-region: us-east
42+ # url defaults to us-east DC, override if required
43+ # manta-url: https://us-east.manta.joyent.com
44+
45+ # Auth config
46+ # key-file: <secret>
47+ # algorithm defaults to rsa-sha256, override if required
48+ # algorithm: rsa-sha256
49 `
50
51 const (
52@@ -41,6 +46,7 @@
53 MantaUser = "MANTA_USER"
54 MantaKeyId = "MANTA_KEY_ID"
55 MantaUrl = "MANTA_URL"
56+ Home = "HOME"
57 )
58
59 var environmentVariables = map[string]string{
60@@ -48,21 +54,25 @@
61 "sdc-key-id": SdcKeyId,
62 "manta-user": MantaUser,
63 "manta-key-id": MantaKeyId,
64+ "key-file": Home,
65 }
66
67 var configFields = schema.Fields{
68 "sdc-user": schema.String(),
69 "sdc-key-id": schema.String(),
70- "sdc-region": schema.String(),
71+ "sdc-url": schema.String(),
72 "manta-user": schema.String(),
73 "manta-key-id": schema.String(),
74- "manta-region": schema.String(),
75+ "manta-url": schema.String(),
76+ "key-file": schema.String(),
77+ "algorithm": schema.String(),
78 "control-dir": schema.String(),
79 }
80
81 var configDefaultFields = schema.Defaults{
82- "sdc-region": "us-west-1",
83- "manta-region": "us-east",
84+ "sdc-url": "https://us-west-1.api.joyentcloud.com",
85+ "manta-url": "https://us-east.manta.joyent.com",
86+ "algorithm": "rsa-sha256",
87 }
88
89 var configSecretFields = []string{
90@@ -70,11 +80,14 @@
91 "sdc-key-id",
92 "manta-user",
93 "manta-key-id",
94+ "key-file",
95 }
96
97 var configImmutableFields = []string{
98- "sdc-region",
99- "manta-region",
100+ "sdc-url",
101+ "manta-url",
102+ "key-file",
103+ "algorithm",
104 }
105
106 func prepareConfig(cfg *config.Config) (*config.Config, error) {
107@@ -86,7 +99,12 @@
108 if err != nil {
109 return nil, err
110 }
111- attrs["control-bucket"] = fmt.Sprintf("%x", uuid.Raw())
112+ attrs["control-dir"] = fmt.Sprintf("%x", uuid.Raw())
113+ }
114+
115+ if _, ok := attrs["key-file"]; !ok {
116+ localEnvVariableHome := os.Getenv(environmentVariables["key-file"])
117+ attrs["key-file"] = fmt.Sprintf("%s/.ssh/id_rsa", localEnvVariableHome)
118 }
119
120 // Read env variables
121@@ -165,8 +183,8 @@
122 attrs map[string]interface{}
123 }
124
125-func (ecfg *environConfig) sdcRegion() string {
126- return ecfg.attrs["sdc-region"].(string)
127+func (ecfg *environConfig) sdcUrl() string {
128+ return ecfg.attrs["sdc-url"].(string)
129 }
130
131 func (ecfg *environConfig) sdcUser() string {
132@@ -177,8 +195,8 @@
133 return ecfg.attrs["sdc-key-id"].(string)
134 }
135
136-func (ecfg *environConfig) mantaRegion() string {
137- return ecfg.attrs["manta-region"].(string)
138+func (ecfg *environConfig) mantaUrl() string {
139+ return ecfg.attrs["manta-url"].(string)
140 }
141
142 func (ecfg *environConfig) mantaUser() string {
143@@ -189,6 +207,14 @@
144 return ecfg.attrs["manta-key-id"].(string)
145 }
146
147+func (ecfg *environConfig) keyFile() string {
148+ return ecfg.attrs["key-file"].(string)
149+}
150+
151+func (ecfg *environConfig) algorithm() string {
152+ return ecfg.attrs["algorithm"].(string)
153+}
154+
155 func (c *environConfig) controlDir() string {
156 return c.attrs["control-dir"].(string)
157 }
158
159=== modified file 'provider/joyent/config_test.go'
160--- provider/joyent/config_test.go 2014-02-13 02:46:58 +0000
161+++ provider/joyent/config_test.go 2014-02-27 18:08:22 +0000
162@@ -8,7 +8,7 @@
163
164 "launchpad.net/juju-core/environs"
165 "launchpad.net/juju-core/environs/config"
166- "launchpad.net/juju-core/provider/joyent"
167+ jp "launchpad.net/juju-core/provider/joyent"
168 "launchpad.net/juju-core/testing"
169 "launchpad.net/juju-core/testing/testbase"
170 )
171@@ -23,12 +23,14 @@
172 func validAttrs() testing.Attrs {
173 return testing.FakeConfig().Merge(testing.Attrs{
174 "type": "joyent",
175- "sdc-user": "dstroppa",
176- "sdc-key-id": "12:c3:a7:cb:a2:29:e2:90:88:3f:04:53:3b:4e:75:40",
177- "sdc-region": "us-west-1",
178- "manta-user": "dstroppa",
179- "manta-key-id": "12:c3:a7:cb:a2:29:e2:90:88:3f:04:53:3b:4e:75:40",
180- "manta-region": "us-east",
181+ "sdc-user": "juju-test",
182+ "sdc-key-id": "00:11:22:33:44:55:66:77:88:99:aa:bb:cc:dd:ee:ff",
183+ "sdc-url": "https://test.api.joyentcloud.com",
184+ "manta-user": "juju-test",
185+ "manta-key-id": "00:11:22:33:44:55:66:77:88:99:aa:bb:cc:dd:ee:ff",
186+ "manta-url": "https://test.manta.joyent.com",
187+ "key-file": "~/.ssh/id_rsa",
188+ "algorithm": "rsa-sha256",
189 "control-dir": "juju-test",
190 })
191 }
192@@ -41,10 +43,10 @@
193 var _ = gc.Suite(&ConfigSuite{})
194
195 func (s *ConfigSuite) SetUpSuite(c *gc.C) {
196- s.PatchEnvironment(joyent.SdcAccount, "tester")
197- s.PatchEnvironment(joyent.SdcKeyId, "11:c4:b6:c0:a3:24:22:96:a8:1f:07:53:3f:8e:14:7a")
198- s.PatchEnvironment(joyent.MantaUser, "tester")
199- s.PatchEnvironment(joyent.MantaKeyId, "11:c4:b6:c0:a3:24:22:96:a8:1f:07:53:3f:8e:14:7a")
200+ s.PatchEnvironment(jp.SdcAccount, "tester")
201+ s.PatchEnvironment(jp.SdcKeyId, "ff:ee:dd:cc:bb:aa:99:88:77:66:55:44:33:22:11:00")
202+ s.PatchEnvironment(jp.MantaUser, "tester")
203+ s.PatchEnvironment(jp.MantaKeyId, "ff:ee:dd:cc:bb:aa:99:88:77:66:55:44:33:22:11:00")
204 }
205
206 var newConfigTests = []struct {
207@@ -70,16 +72,16 @@
208 insert: testing.Attrs{"sdc-key-id": ""},
209 err: "sdc-key-id: must not be empty",
210 }, {
211- info: "sdc-region is inserted if missing",
212- expect: testing.Attrs{"sdc-region": "us-west-1"},
213-}, {
214- info: "sdc-region cannot be empty",
215- insert: testing.Attrs{"sdc-region": ""},
216- err: "sdc-region: must not be empty",
217-}, {
218- info: "sdc-region is untouched if present",
219- insert: testing.Attrs{"sdc-region": "us-west-1"},
220- expect: testing.Attrs{"sdc-region": "us-west-1"},
221+ info: "sdc-url is inserted if missing",
222+ expect: testing.Attrs{"sdc-url": "https://test.api.joyentcloud.com"},
223+}, {
224+ info: "sdc-url cannot be empty",
225+ insert: testing.Attrs{"sdc-url": ""},
226+ err: "sdc-url: must not be empty",
227+}, {
228+ info: "sdc-url is untouched if present",
229+ insert: testing.Attrs{"sdc-url": "https://test.api.joyentcloud.com"},
230+ expect: testing.Attrs{"sdc-url": "https://test.api.joyentcloud.com"},
231 }, {
232 info: "manta-user is required",
233 remove: []string{"manta-user"},
234@@ -97,16 +99,30 @@
235 insert: testing.Attrs{"manta-key-id": ""},
236 err: "manta-key-id: must not be empty",
237 }, {
238- info: "manta-region is inserted if missing",
239- expect: testing.Attrs{"manta-region": "us-east"},
240-}, {
241- info: "manta-region cannot be empty",
242- insert: testing.Attrs{"manta-region": ""},
243- err: "manta-region: must not be empty",
244-}, {
245- info: "manta-region is untouched if present",
246- insert: testing.Attrs{"manta-region": "us-east"},
247- expect: testing.Attrs{"manta-region": "us-east"},
248+ info: "manta-url is inserted if missing",
249+ expect: testing.Attrs{"manta-url": "https://test.manta.joyent.com"},
250+}, {
251+ info: "manta-url cannot be empty",
252+ insert: testing.Attrs{"manta-url": ""},
253+ err: "manta-url: must not be empty",
254+}, {
255+ info: "manta-url is untouched if present",
256+ insert: testing.Attrs{"manta-url": "https://test.manta.joyent.com"},
257+ expect: testing.Attrs{"manta-url": "https://test.manta.joyent.com"},
258+}, {
259+ info: "key-file is inserted if missing",
260+ expect: testing.Attrs{"key-file": "~/.ssh/id_rsa"},
261+}, {
262+ info: "key-file cannot be empty",
263+ insert: testing.Attrs{"key-file": ""},
264+ err: "key-file: must not be empty",
265+}, {
266+ info: "algorithm is inserted if missing",
267+ expect: testing.Attrs{"algorithm": "rsa-sha256"},
268+}, {
269+ info: "algorithm cannot be empty",
270+ insert: testing.Attrs{"algorithm": ""},
271+ err: "algorithm: must not be empty",
272 }, {
273 info: "unknown field is not touched",
274 insert: testing.Attrs{"unknown-field": 12345},
275@@ -137,7 +153,7 @@
276 c.Logf("test %d: %s", i, test.info)
277 attrs := validAttrs().Merge(test.insert).Delete(test.remove...)
278 testConfig := newConfig(c, attrs)
279- validatedConfig, err := joyent.Provider.Validate(testConfig, nil)
280+ validatedConfig, err := Provider.Validate(testConfig, nil)
281 if test.err == "" {
282 c.Assert(err, gc.IsNil)
283 attrs := validatedConfig.AllAttrs()
284@@ -157,7 +173,7 @@
285 c.Logf("test %d: %s", i, test.info)
286 attrs := validAttrs().Merge(test.insert).Delete(test.remove...)
287 testConfig := newConfig(c, attrs)
288- validatedConfig, err := joyent.Provider.Validate(knownGoodConfig, testConfig)
289+ validatedConfig, err := Provider.Validate(knownGoodConfig, testConfig)
290 if test.err == "" {
291 c.Assert(err, gc.IsNil)
292 attrs := validatedConfig.AllAttrs()
293@@ -186,24 +202,24 @@
294 expect: testing.Attrs{"sdc-user": "joyent_user"},
295 }, {
296 info: "can change sdc-key-id",
297- insert: testing.Attrs{"sdc-key-id": "11:c4:b6:c0:a3:24:22:96:a8:1f:07:53:3f:8e:14:7a"},
298- expect: testing.Attrs{"sdc-key-id": "11:c4:b6:c0:a3:24:22:96:a8:1f:07:53:3f:8e:14:7a"},
299+ insert: testing.Attrs{"sdc-key-id": "ff:ee:dd:cc:bb:aa:99:88:77:66:55:44:33:22:11:00"},
300+ expect: testing.Attrs{"sdc-key-id": "ff:ee:dd:cc:bb:aa:99:88:77:66:55:44:33:22:11:00"},
301 }, {
302- info: "can change sdc-region",
303- insert: testing.Attrs{"sdc-region": "us-west-1"},
304- expect: testing.Attrs{"sdc-region": "us-west-1"},
305+ info: "can change sdc-url",
306+ insert: testing.Attrs{"sdc-url": "https://test.api.joyentcloud.com"},
307+ expect: testing.Attrs{"sdc-url": "https://test.api.joyentcloud.com"},
308 }, {
309 info: "can change manta-user",
310 insert: testing.Attrs{"manta-user": "manta_user"},
311 expect: testing.Attrs{"manta-user": "manta_user"},
312 }, {
313 info: "can change manta-key-id",
314- insert: testing.Attrs{"manta-key-id": "11:c4:b6:c0:a3:24:22:96:a8:1f:07:53:3f:8e:14:7a"},
315- expect: testing.Attrs{"manta-key-id": "11:c4:b6:c0:a3:24:22:96:a8:1f:07:53:3f:8e:14:7a"},
316+ insert: testing.Attrs{"manta-key-id": "ff:ee:dd:cc:bb:aa:99:88:77:66:55:44:33:22:11:00"},
317+ expect: testing.Attrs{"manta-key-id": "ff:ee:dd:cc:bb:aa:99:88:77:66:55:44:33:22:11:00"},
318 }, {
319- info: "can change manta-region",
320- insert: testing.Attrs{"manta-region": "us-east"},
321- expect: testing.Attrs{"manta-region": "us-east"},
322+ info: "can change manta-url",
323+ insert: testing.Attrs{"manta-url": "https://test.manta.joyent.com"},
324+ expect: testing.Attrs{"manta-url": "https://test.manta.joyent.com"},
325 }, {
326 info: "can insert unknown field",
327 insert: testing.Attrs{"unknown": "ignoti"},
328@@ -216,7 +232,7 @@
329 c.Logf("test %d: %s", i, test.info)
330 attrs := validAttrs().Merge(test.insert).Delete(test.remove...)
331 testConfig := newConfig(c, attrs)
332- validatedConfig, err := joyent.Provider.Validate(testConfig, baseConfig)
333+ validatedConfig, err := Provider.Validate(testConfig, baseConfig)
334 if test.err == "" {
335 c.Assert(err, gc.IsNil)
336 attrs := validatedConfig.AllAttrs()
337@@ -270,7 +286,7 @@
338 }, {
339 info: "can get sdc-key-id from env variable",
340 insert: testing.Attrs{"sdc-key-id": ""},
341- expect: testing.Attrs{"sdc-key-id": "11:c4:b6:c0:a3:24:22:96:a8:1f:07:53:3f:8e:14:7a"},
342+ expect: testing.Attrs{"sdc-key-id": "ff:ee:dd:cc:bb:aa:99:88:77:66:55:44:33:22:11:00"},
343 }, {
344 info: "can get manta-user from env variable",
345 insert: testing.Attrs{"manta-user": ""},
346@@ -278,7 +294,7 @@
347 }, {
348 info: "can get manta-key-id from env variable",
349 insert: testing.Attrs{"manta-key-id": ""},
350- expect: testing.Attrs{"manta-key-id": "11:c4:b6:c0:a3:24:22:96:a8:1f:07:53:3f:8e:14:7a"},
351+ expect: testing.Attrs{"manta-key-id": "ff:ee:dd:cc:bb:aa:99:88:77:66:55:44:33:22:11:00"},
352 }}
353
354 func (s *ConfigSuite) TestPrepare(c *gc.C) {
355@@ -286,7 +302,7 @@
356 c.Logf("test %d: %s", i, test.info)
357 attrs := validAttrs().Merge(test.insert).Delete(test.remove...)
358 testConfig := newConfig(c, attrs)
359- preparedConfig, err := joyent.Provider.Prepare(testing.Context(c), testConfig)
360+ preparedConfig, err := Provider.Prepare(testing.Context(c), testConfig)
361 if test.err == "" {
362 c.Assert(err, gc.IsNil)
363 attrs := preparedConfig.Config().AllAttrs()
364
365=== modified file 'provider/joyent/environ.go'
366--- provider/joyent/environ.go 2013-12-19 08:40:11 +0000
367+++ provider/joyent/environ.go 2014-02-27 18:08:22 +0000
368@@ -23,7 +23,7 @@
369 // must be implemented ) and environ_firewall.go (which can be safely
370 // ignored until you've got an environment bootstrapping successfully).
371
372-type environ struct {
373+type JoyentEnviron struct {
374 name string
375 // All mutating operations should lock the mutex. Non-mutating operations
376 // should read all fields (other than name, which is immutable) from a
377@@ -35,17 +35,32 @@
378 storage storage.Storage
379 }
380
381-var _ environs.Environ = (*environ)(nil)
382-
383-func (env *environ) Name() string {
384+var _ environs.Environ = (*JoyentEnviron)(nil)
385+
386+func NewEnviron(cfg *config.Config) (*JoyentEnviron, error) {
387+ env := new(JoyentEnviron)
388+ err := env.SetConfig(cfg)
389+ if err != nil {
390+ return nil, err
391+ }
392+ env.name = cfg.Name()
393+ env.storage = NewStorage(env)
394+ return env, nil
395+}
396+
397+func (env *JoyentEnviron) SetName(envName string) {
398+ env.name = envName
399+}
400+
401+func (env *JoyentEnviron) Name() string {
402 return env.name
403 }
404
405-func (*environ) Provider() environs.EnvironProvider {
406+func (*JoyentEnviron) Provider() environs.EnvironProvider {
407 return providerInstance
408 }
409
410-func (env *environ) SetConfig(cfg *config.Config) error {
411+func (env *JoyentEnviron) SetConfig(cfg *config.Config) error {
412 env.lock.Lock()
413 defer env.lock.Unlock()
414 ecfg, err := validateConfig(cfg, env.ecfg)
415@@ -61,7 +76,7 @@
416 return nil
417 }
418
419-func (env *environ) getSnapshot() *environ {
420+func (env *JoyentEnviron) getSnapshot() *JoyentEnviron {
421 env.lock.Lock()
422 clone := *env
423 env.lock.Unlock()
424@@ -69,26 +84,26 @@
425 return &clone
426 }
427
428-func (env *environ) Config() *config.Config {
429+func (env *JoyentEnviron) Config() *config.Config {
430 return env.getSnapshot().ecfg.Config
431 }
432
433-func (env *environ) Storage() storage.Storage {
434+func (env *JoyentEnviron) Storage() storage.Storage {
435 return env.getSnapshot().storage
436 }
437
438-func (env *environ) PublicStorage() storage.StorageReader {
439+func (env *JoyentEnviron) PublicStorage() storage.StorageReader {
440 return environs.EmptyStorage
441 }
442
443-func (env *environ) Bootstrap(ctx environs.BootstrapContext, cons constraints.Value) error {
444+func (env *JoyentEnviron) Bootstrap(ctx environs.BootstrapContext, cons constraints.Value) error {
445 return common.Bootstrap(ctx, env, cons)
446 }
447
448-func (env *environ) StateInfo() (*state.Info, *api.Info, error) {
449+func (env *JoyentEnviron) StateInfo() (*state.Info, *api.Info, error) {
450 return common.StateInfo(env)
451 }
452
453-func (env *environ) Destroy() error {
454+func (env *JoyentEnviron) Destroy() error {
455 return common.Destroy(env)
456 }
457
458=== modified file 'provider/joyent/environ_firewall.go'
459--- provider/joyent/environ_firewall.go 2013-10-07 10:57:04 +0000
460+++ provider/joyent/environ_firewall.go 2014-02-27 18:08:22 +0000
461@@ -11,19 +11,19 @@
462 // cause `juju expose` to work when the firewall-mode is "global". If you
463 // implement one of them, you should implement them all.
464
465-func (env *environ) OpenPorts(ports []instance.Port) error {
466+func (env *JoyentEnviron) OpenPorts(ports []instance.Port) error {
467 logger.Warningf("pretending to open ports %v for all instances", ports)
468 _ = env.getSnapshot()
469 return nil
470 }
471
472-func (env *environ) ClosePorts(ports []instance.Port) error {
473+func (env *JoyentEnviron) ClosePorts(ports []instance.Port) error {
474 logger.Warningf("pretending to close ports %v for all instances", ports)
475 _ = env.getSnapshot()
476 return nil
477 }
478
479-func (env *environ) Ports() ([]instance.Port, error) {
480+func (env *JoyentEnviron) Ports() ([]instance.Port, error) {
481 _ = env.getSnapshot()
482 return nil, nil
483 }
484
485=== modified file 'provider/joyent/environ_instance.go'
486--- provider/joyent/environ_instance.go 2013-10-07 10:57:04 +0000
487+++ provider/joyent/environ_instance.go 2014-02-27 18:08:22 +0000
488@@ -10,7 +10,7 @@
489 "launchpad.net/juju-core/tools"
490 )
491
492-func (env *environ) StartInstance(
493+func (env *JoyentEnviron) StartInstance(
494 cons constraints.Value, possibleTools tools.List, machineConf *cloudinit.MachineConfig,
495 ) (
496 instance.Instance, *instance.HardwareCharacteristics, error,
497@@ -22,7 +22,7 @@
498 return nil, nil, errNotImplemented
499 }
500
501-func (env *environ) AllInstances() ([]instance.Instance, error) {
502+func (env *JoyentEnviron) AllInstances() ([]instance.Instance, error) {
503 // Please note that this must *not* return instances that have not been
504 // allocated as part of this environment -- if it does, juju will see they
505 // are not tracked in state, assume they're stale/rogue, and shut them down.
506@@ -30,7 +30,7 @@
507 return nil, errNotImplemented
508 }
509
510-func (env *environ) Instances(ids []instance.Id) ([]instance.Instance, error) {
511+func (env *JoyentEnviron) Instances(ids []instance.Id) ([]instance.Instance, error) {
512 // Please note that this must *not* return instances that have not been
513 // allocated as part of this environment -- if it does, juju will see they
514 // are not tracked in state, assume they're stale/rogue, and shut them down.
515@@ -41,7 +41,7 @@
516 return nil, errNotImplemented
517 }
518
519-func (env *environ) StopInstances(instances []instance.Instance) error {
520+func (env *JoyentEnviron) StopInstances(instances []instance.Instance) error {
521 _ = env.getSnapshot()
522 return errNotImplemented
523 }
524
525=== modified file 'provider/joyent/export_test.go'
526--- provider/joyent/export_test.go 2013-10-07 10:57:04 +0000
527+++ provider/joyent/export_test.go 2014-02-27 18:08:22 +0000
528@@ -1,10 +1,11 @@
529 // Copyright 2013 Joyent Inc.
530 // Licensed under the AGPLv3, see LICENCE file for details.
531
532-package joyent
533+package joyent_test
534
535 import (
536 "launchpad.net/juju-core/environs"
537+ jp "launchpad.net/juju-core/provider/joyent"
538 )
539
540-var Provider environs.EnvironProvider = providerInstance
541+var Provider environs.EnvironProvider = jp.GetProviderInstance()
542
543=== modified file 'provider/joyent/instance.go'
544--- provider/joyent/instance.go 2013-12-16 09:53:26 +0000
545+++ provider/joyent/instance.go 2014-02-27 18:08:22 +0000
546@@ -10,7 +10,7 @@
547
548 type environInstance struct {
549 id instance.Id
550- env *environ
551+ env *JoyentEnviron
552 }
553
554 var _ instance.Instance = (*environInstance)(nil)
555
556=== modified file 'provider/joyent/joyent_test.go'
557--- provider/joyent/joyent_test.go 2013-10-10 09:24:18 +0000
558+++ provider/joyent/joyent_test.go 2014-02-27 18:08:22 +0000
559@@ -4,24 +4,177 @@
560 package joyent_test
561
562 import (
563- "testing"
564+ "fmt"
565+ "io/ioutil"
566+ "net/http"
567+ "net/http/httptest"
568+ "os"
569+ stdtesting "testing"
570
571 gc "launchpad.net/gocheck"
572
573- "launchpad.net/juju-core/environs"
574- "launchpad.net/juju-core/provider/joyent"
575-)
576-
577-func TestPackage(t *testing.T) {
578+ "launchpad.net/juju-core/environs/config"
579+ envtesting "launchpad.net/juju-core/environs/testing"
580+ jp "launchpad.net/juju-core/provider/joyent"
581+ coretesting "launchpad.net/juju-core/testing"
582+ "launchpad.net/juju-core/testing/testbase"
583+
584+ "launchpad.net/gojoyent/jpc"
585+ localmanta "launchpad.net/gojoyent/localservices/manta"
586+)
587+
588+const (
589+ testUser = "test"
590+ testKeyFileName = "provider_id_rsa"
591+ testPrivateKey = `-----BEGIN RSA PRIVATE KEY-----
592+MIIEpAIBAAKCAQEAza+KvczCrcpQGRq9e347VHx9oEvuhseJt0ydR+UMAveyQprU
593+4JHvzwUUhGnG147GJQYyfQ4nzaSG62az/YThoZJzw8gtxGkVHv0wlAlRkYhxbKbq
594+8WQIh73xDQkHLw2lXLvf7Tt0Mhow0qGEmkOjTb5fPsj2evphrV3jJ15QlhL4cv33
595+t8jVadIrL0iIpwdqWiPqUKpsrSfKJghkoXS6quPy78P820TnuoBG+/Ppr8Kkvn6m
596+A7j4xnOQ12QE6jPK4zkikj5ZczSC4fTG0d3BwwX4VYu+4y/T/BX0L9VNUmQU22Y+
597+/MRXAUZxsa8VhNB+xXF5XSubyb2n6loMWWaYGwIDAQABAoIBAQDCJt9JxYxGS+BL
598+sigF9+O9Hj3fH42p/5QJR/J2uMgbzP+hS1GCIX9B5MO3MbmWI5j5vd3OmZwMyy7n
599+6Wwg9FufDgTkW4KIEcD0HX7LXfh27VpTe0PuU8SRjUOKUGlNiw36eQUog6Rs3rgT
600+Oo9Wpl3xtq9lLoErGEk3QpZ2xNpArTfsN9N3pdmD4sv7wmJq0PZQyej482g9R0g/
601+5k2ni6JpcEifzBQ6Bzx3EV2l9UipEIqbqDpMOtYFCpnLQhEaDfUribqXINGIsjiq
602+VyFa3Mbg/eayqG3UX3rVTCif2NnW2ojl4mMgWCyxgWfb4Jg1trc3v7X4SXfbgPWD
603+WcfrOhOhAoGBAP7ZC8KHAnjujwvXf3PxVNm6CTs5evbByQVyxNciGxRuOomJIR4D
604+euqepQ4PuNAabnrbMyQWXpibIKpmLnBVoj1q0IMXYvi2MZF5e2tH/Gx01UvxamHh
605+bKhHmp9ImHhVl6kObXOdNvLVTt/BI5FZBblvm7qOoiVwImPbqqVHP7Q5AoGBAM6d
606+mNsrW0iV/nP1m7d8mcFw74PI0FNlNdfUoePUgokO0t5OU0Ri/lPBDCRGlvVF3pj1
607+HnmwroNtdWr9oPVB6km8193fb2zIWe53tj+6yRFQpz5elrSPfeZaZXlJZAGCCCdN
608+gBggWQFPeQiT54aPywPpcTZHIs72XBqQ6QsIPrbzAoGAdW2hg5MeSobyFuzHZ69N
609+/70/P7DuvgDxFbeah97JR5K7GmC7h87mtnE/cMlByXJEcgvK9tfv4rWoSZwnzc9H
610+oLE1PxJpolyhXnzxp69V2svC9OlasZtjq+7Cip6y0s/twBJL0Lgid6ZeX6/pKbIx
611+dw68XSwX/tQ6pHS1ns7DxdECgYBJbBWapNCefbbbjEcWsC+PX0uuABmP2SKGHSie
612+ZrEwdVUX7KuIXMlWB/8BkRgp9vdAUbLPuap6R9Z2+8RMA213YKUxUiotdREIPgBE
613+q2KyRX/5GPHjHi62Qh9XN25TXtr45ICFklEutwgitTSMS+Lv8+/oQuUquL9ILYCz
614+C+4FYwKBgQDE9yZTUpJjG2424z6bl/MHzwl5RB4pMronp0BbeVqPwhCBfj0W5I42
615+1ZL4+8eniHfUs4GXzf5tb9YwVt3EltIF2JybaBvFsv2o356yJUQmqQ+jyYRoEpT5
616+2SwilFo/XCotCXxi5n8sm9V94a0oix4ehZrohTA/FZLsggwFCPmXfw==
617+-----END RSA PRIVATE KEY-----`
618+ testKeyFingerprint = "66:ca:1c:09:75:99:35:69:be:91:08:25:03:c0:17:c0"
619+)
620+
621+func TestJoyentProvider(t *stdtesting.T) {
622 gc.TestingT(t)
623 }
624
625-type JoyentSuite struct{}
626-
627-var _ = gc.Suite(&JoyentSuite{})
628-
629-func (*JoyentSuite) TestRegistered(c *gc.C) {
630- provider, err := environs.Provider("joyent")
631- c.Assert(err, gc.IsNil)
632- c.Assert(provider, gc.Equals, joyent.Provider)
633+type localMantaService struct {
634+ creds *jpc.Credentials
635+ Server *httptest.Server
636+ Mux *http.ServeMux
637+ oldHandler http.Handler
638+ manta *localmanta.Manta
639+}
640+
641+func (s *localMantaService) Start(c *gc.C) {
642+ // Set up the HTTP server.
643+ s.Server = httptest.NewServer(nil)
644+ c.Assert(s.Server, gc.NotNil)
645+ s.oldHandler = s.Server.Config.Handler
646+ s.Mux = http.NewServeMux()
647+ s.Server.Config.Handler = s.Mux
648+
649+ // Set up a Joyent Manta service.
650+ auth := jpc.Auth{User: testUser, KeyFile: testKeyFileName, Algorithm: "rsa-sha256"}
651+
652+ s.creds = &jpc.Credentials{
653+ UserAuthentication: auth,
654+ MantaKeyId: testKeyFingerprint,
655+ MantaEndpoint: jpc.Endpoint{URL: s.Server.URL},
656+ }
657+ s.manta = localmanta.New(s.creds.MantaEndpoint.URL, s.creds.UserAuthentication.User)
658+ s.manta.SetupHTTP(s.Mux)
659+ c.Logf("Started local Manta service at: %v", s.Server.URL)
660+}
661+
662+func (s *localMantaService) Stop() {
663+ s.Mux = nil
664+ s.Server.Config.Handler = s.oldHandler
665+ s.Server.Close()
666+}
667+
668+type providerSuite struct {
669+ testbase.LoggingSuite
670+ envtesting.ToolsFixture
671+ restoreTimeouts func()
672+}
673+
674+var _ = gc.Suite(&providerSuite{})
675+
676+func (s *providerSuite) SetUpSuite(c *gc.C) {
677+ s.restoreTimeouts = envtesting.PatchAttemptStrategies()
678+ s.LoggingSuite.SetUpSuite(c)
679+ createTestKey()
680+}
681+
682+func (s *providerSuite) TearDownSuite(c *gc.C) {
683+ removeTestKey()
684+ s.restoreTimeouts()
685+ s.LoggingSuite.TearDownSuite(c)
686+}
687+
688+func (s *providerSuite) SetUpTest(c *gc.C) {
689+ s.LoggingSuite.SetUpTest(c)
690+ s.ToolsFixture.SetUpTest(c)
691+}
692+
693+func (s *providerSuite) TearDownTest(c *gc.C) {
694+ s.ToolsFixture.TearDownTest(c)
695+ s.LoggingSuite.TearDownTest(c)
696+}
697+
698+func GetFakeConfig(sdcUrl, mantaUrl string) coretesting.Attrs {
699+ return coretesting.FakeConfig().Merge(coretesting.Attrs{
700+ "name": "joyent test environment",
701+ "type": "joyent",
702+ "sdc-user": testUser,
703+ "sdc-key-id": testKeyFingerprint,
704+ "sdc-url": sdcUrl,
705+ "manta-user": testUser,
706+ "manta-key-id": testKeyFingerprint,
707+ "manta-url": mantaUrl,
708+ "key-file": fmt.Sprintf("%s/.ssh/%s", os.Getenv("HOME"), testKeyFileName),
709+ "algorithm": "rsa-sha256",
710+ "control-dir": "juju-test",
711+ })
712+}
713+
714+// makeEnviron creates a functional Joyent environ for a test.
715+func (suite *providerSuite) makeEnviron(sdcUrl, mantaUrl string) *jp.JoyentEnviron {
716+ /*attrs := coretesting.FakeConfig().Merge(coretesting.Attrs{
717+ "name": "joyent test environment",
718+ "type": "joyent",
719+ "sdc-user": "dstroppa",
720+ "sdc-key-id": "12:c3:a7:cb:a2:29:e2:90:88:3f:04:53:3b:4e:75:40",
721+ "sdc-url": "https://us-west-1.api.joyentcloud.com",
722+ "manta-user": "dstroppa",
723+ "manta-key-id": "12:c3:a7:cb:a2:29:e2:90:88:3f:04:53:3b:4e:75:40",
724+ "manta-url": "https://us-east.manta.joyent.com",
725+ "key-file": fmt.Sprintf("%s/.ssh/id_rsa", os.Getenv("HOME")),
726+ "algorithm": "rsa-sha256",
727+ "control-dir": "juju-test",
728+ })*/
729+
730+ attrs := GetFakeConfig(sdcUrl, mantaUrl)
731+ cfg, err := config.New(config.NoDefaults, attrs)
732+ if err != nil {
733+ panic(err)
734+ }
735+ env, err := jp.NewEnviron(cfg)
736+ if err != nil {
737+ panic(err)
738+ }
739+ return env
740+}
741+
742+func createTestKey() error {
743+ keyFile := fmt.Sprintf("%s/.ssh/%s", os.Getenv("HOME"), testKeyFileName)
744+ return ioutil.WriteFile(keyFile, []byte(testPrivateKey), 400)
745+}
746+
747+func removeTestKey() error {
748+ keyFile := fmt.Sprintf("%s/.ssh/%s", os.Getenv("HOME"), testKeyFileName)
749+ return os.Remove(keyFile)
750 }
751
752=== modified file 'provider/joyent/provider.go'
753--- provider/joyent/provider.go 2014-02-13 02:46:58 +0000
754+++ provider/joyent/provider.go 2014-02-27 18:08:22 +0000
755@@ -45,7 +45,7 @@
756 }
757
758 func (environProvider) Open(cfg *config.Config) (environs.Environ, error) {
759- env := &environ{name: cfg.Name()}
760+ env := &JoyentEnviron{name: cfg.Name()}
761 if err := env.SetConfig(cfg); err != nil {
762 return nil, err
763 }
764@@ -118,3 +118,7 @@
765 // provider; and it needs to return the address of *that* instance.
766 return "", errNotImplemented
767 }
768+
769+func GetProviderInstance() environs.EnvironProvider {
770+ return providerInstance
771+}
772
773=== modified file 'provider/joyent/storage.go'
774--- provider/joyent/storage.go 2013-11-21 17:37:18 +0000
775+++ provider/joyent/storage.go 2014-02-27 18:08:22 +0000
776@@ -4,50 +4,194 @@
777 package joyent
778
779 import (
780+ "bytes"
781+ "fmt"
782 "io"
783+ "sync"
784+ "time"
785
786 "launchpad.net/juju-core/environs/storage"
787 "launchpad.net/juju-core/utils"
788+
789+ "launchpad.net/gojoyent/client"
790+ "launchpad.net/gojoyent/jpc"
791+ "launchpad.net/gojoyent/manta"
792 )
793
794-type environStorage struct {
795- ecfg *environConfig
796-}
797-
798-var _ storage.Storage = (*environStorage)(nil)
799+type JoyentStorage struct {
800+ sync.Mutex
801+ ecfg *environConfig
802+ madeContainer bool
803+ containerName string
804+ manta *manta.Client
805+}
806+
807+type byteCloser struct {
808+ io.Reader
809+}
810+
811+func (byteCloser) Close() error {
812+ return nil
813+}
814+
815+var _ storage.Storage = (*JoyentStorage)(nil)
816+
817+func NewStorage(env *JoyentEnviron) storage.Storage {
818+ if stor, err := newStorage(env.ecfg); err == nil {
819+ return stor
820+ }
821+ return nil
822+}
823+
824+func getCredentials(ecfg *environConfig) *jpc.Credentials {
825+ auth := jpc.Auth{User: ecfg.mantaUser(), KeyFile: ecfg.keyFile(), Algorithm: ecfg.algorithm()}
826+
827+ return &jpc.Credentials{
828+ UserAuthentication: auth,
829+ MantaKeyId: ecfg.mantaKeyId(),
830+ MantaEndpoint: jpc.Endpoint{URL: ecfg.mantaUrl()},
831+ }
832+}
833
834 func newStorage(ecfg *environConfig) (storage.Storage, error) {
835- return &environStorage{ecfg}, nil
836-}
837-
838-func (s *environStorage) List(prefix string) ([]string, error) {
839- return nil, errNotImplemented
840-}
841-
842-func (s *environStorage) URL(name string) (string, error) {
843- return "", errNotImplemented
844-}
845-
846-func (s *environStorage) Get(name string) (io.ReadCloser, error) {
847- return nil, errNotImplemented
848-}
849-
850-func (s *environStorage) Put(name string, r io.Reader, length int64) error {
851- return errNotImplemented
852-}
853-
854-func (s *environStorage) Remove(name string) error {
855- return errNotImplemented
856-}
857-
858-func (s *environStorage) RemoveAll() error {
859- return errNotImplemented
860-}
861-
862-func (s *environStorage) DefaultConsistencyStrategy() utils.AttemptStrategy {
863+ client := client.NewClient(ecfg.mantaUrl(), "", getCredentials(ecfg), &logger)
864+
865+ return &JoyentStorage{
866+ ecfg: ecfg,
867+ containerName: ecfg.controlDir(),
868+ manta: manta.New(client)}, nil
869+}
870+
871+func (s *JoyentStorage) GetContainerName() string {
872+ return s.containerName
873+}
874+
875+func (s *JoyentStorage) GetMantaUrl() string {
876+ return s.ecfg.mantaUrl()
877+}
878+
879+func (s *JoyentStorage) GetMantaUser() string {
880+ return s.ecfg.mantaUser()
881+}
882+
883+// CreateContainer makes the environment's control container, the
884+// place where bootstrap information and deployed charms
885+// are stored. To avoid two round trips on every PUT operation,
886+// we do this only once for each environ.
887+func (s *JoyentStorage) CreateContainer() error {
888+ s.Lock()
889+ defer s.Unlock()
890+ if s.madeContainer {
891+ return nil
892+ }
893+ // try to make the container
894+ err := s.manta.PutDirectory(s.containerName)
895+ if err == nil {
896+ s.madeContainer = true
897+ }
898+ return err
899+}
900+
901+// deleteContainer deletes the named container from the storage account.
902+func (s *JoyentStorage) DeleteContainer(containerName string) error {
903+ err := s.manta.DeleteDirectory(containerName)
904+ if err == nil {
905+ s.madeContainer = false
906+ }
907+ return err
908+}
909+
910+func (s *JoyentStorage) List(prefix string) ([]string, error) {
911+ // use empty opts, i.e. default values
912+ // -- might be added in the provider config?
913+ contents, err := s.manta.ListDirectory(s.containerName, manta.ListDirectoryOpts{})
914+ if err != nil {
915+ return nil, err
916+ }
917+ var names []string
918+ for _, item := range contents {
919+ names = append(names, item.Name)
920+ }
921+ return names, nil
922+}
923+
924+//return something that a random wget can retrieve the object at, without any credentials
925+func (s *JoyentStorage) URL(name string) (string, error) {
926+ path := fmt.Sprintf("/%s/stor/%s/%s", s.ecfg.mantaUser(), s.containerName, name)
927+ return s.manta.SignURL(path, time.Now().AddDate(10, 0, 0))
928+}
929+
930+func (s *JoyentStorage) Get(name string) (io.ReadCloser, error) {
931+ b, err := s.manta.GetObject(s.containerName, name)
932+ if err != nil {
933+ return nil, err
934+ }
935+ r := byteCloser{bytes.NewReader(b)}
936+ return r, nil
937+}
938+
939+func (s *JoyentStorage) Put(name string, r io.Reader, length int64) error {
940+ if err := s.CreateContainer(); err != nil {
941+ return fmt.Errorf("cannot make Manta control container: %v", err)
942+ }
943+ err := s.manta.PutObject(s.containerName, name, r)
944+ if err != nil {
945+ return fmt.Errorf("cannot write file %q to control container %q: %v", name, s.containerName, err)
946+ }
947+ return nil
948+}
949+
950+func (s *JoyentStorage) Remove(name string) error {
951+ err := s.manta.DeleteObject(s.containerName, name)
952+ if err != nil {
953+ return err
954+ }
955+ return nil
956+}
957+
958+func (s *JoyentStorage) RemoveAll() error {
959+ names, err := storage.List(s, "")
960+ if err != nil {
961+ return err
962+ }
963+ // Remove all the objects in parallel so that we incur less round-trips.
964+ // If we're in danger of having hundreds of objects,
965+ // we'll want to change this to limit the number
966+ // of concurrent operations.
967+ var wg sync.WaitGroup
968+ wg.Add(len(names))
969+ errc := make(chan error, len(names))
970+ for _, name := range names {
971+ name := name
972+ go func() {
973+ defer wg.Done()
974+ if err := s.Remove(name); err != nil {
975+ errc <- err
976+ }
977+ }()
978+ }
979+ wg.Wait()
980+ select {
981+ case err := <-errc:
982+ return fmt.Errorf("cannot delete all provider state: %v", err)
983+ default:
984+ }
985+
986+ s.Lock()
987+ defer s.Unlock()
988+ // Even DeleteContainer fails, it won't harm if we try again - the
989+ // operation might have succeeded even if we get an error.
990+ s.madeContainer = false
991+ if err = s.manta.DeleteDirectory(s.containerName); err != nil {
992+ return err
993+ }
994+ return nil
995+}
996+
997+func (s *JoyentStorage) DefaultConsistencyStrategy() utils.AttemptStrategy {
998 return utils.AttemptStrategy{}
999 }
1000
1001-func (s *environStorage) ShouldRetry(err error) bool {
1002+func (s *JoyentStorage) ShouldRetry(err error) bool {
1003 return false
1004 }
1005
1006=== added file 'provider/joyent/storage_test.go'
1007--- provider/joyent/storage_test.go 1970-01-01 00:00:00 +0000
1008+++ provider/joyent/storage_test.go 2014-02-27 18:08:22 +0000
1009@@ -0,0 +1,189 @@
1010+// Copyright 2013 Joyent Inc.
1011+// Licensed under the AGPLv3, see LICENCE file for details.
1012+
1013+package joyent_test
1014+
1015+import (
1016+ "fmt"
1017+ "io/ioutil"
1018+ "math/rand"
1019+ "net/http"
1020+ "net/url"
1021+ "strings"
1022+
1023+ gc "launchpad.net/gocheck"
1024+ jp "launchpad.net/juju-core/provider/joyent"
1025+ jc "launchpad.net/juju-core/testing/checkers"
1026+
1027+ "launchpad.net/gojoyent/errors"
1028+)
1029+
1030+type storageSuite struct {
1031+ providerSuite
1032+ localMantaService
1033+}
1034+
1035+const (
1036+ storageName = "testStorage"
1037+ fileName = "testFile"
1038+ fileBlobContent = "Juju Joyent Provider Storage - Test"
1039+)
1040+
1041+var _ = gc.Suite(&storageSuite{})
1042+
1043+func (s *storageSuite) SetUpSuite(c *gc.C) {
1044+ s.providerSuite.SetUpSuite(c)
1045+ s.localMantaService.Start(c)
1046+}
1047+
1048+func (s *storageSuite) TearDownSuite(c *gc.C) {
1049+ s.localMantaService.Stop()
1050+ s.providerSuite.TearDownSuite(c)
1051+}
1052+
1053+// s.makeStorage creates a Manta storage object for the running test.
1054+func (s *storageSuite) assertStorage(name string, c *gc.C) *jp.JoyentStorage {
1055+ env := s.makeEnviron("localhost", s.localMantaService.Server.URL)
1056+ env.SetName(name)
1057+ storage := jp.NewStorage(env).(*jp.JoyentStorage)
1058+ c.Assert(storage, gc.NotNil)
1059+ return storage
1060+}
1061+
1062+func (s *storageSuite) assertContainer(storage *jp.JoyentStorage, c *gc.C) {
1063+ err := storage.CreateContainer()
1064+ c.Assert(err, gc.IsNil)
1065+}
1066+
1067+func (s *storageSuite) assertFile(storage *jp.JoyentStorage, c *gc.C) {
1068+ err := storage.Put(fileName, strings.NewReader(fileBlobContent), int64(len(fileBlobContent)))
1069+ c.Assert(err, gc.IsNil)
1070+}
1071+
1072+// makeRandomBytes returns an array of arbitrary byte values.
1073+func makeRandomBytes(length int) []byte {
1074+ data := make([]byte, length)
1075+ for index := range data {
1076+ data[index] = byte(rand.Intn(256))
1077+ }
1078+ return data
1079+}
1080+
1081+func makeResponse(content string, status int) *http.Response {
1082+ return &http.Response{
1083+ Status: fmt.Sprintf("%d", status),
1084+ StatusCode: status,
1085+ Body: ioutil.NopCloser(strings.NewReader(content)),
1086+ }
1087+}
1088+
1089+func (s *storageSuite) TestList(c *gc.C) {
1090+ mantaStorage := s.assertStorage(storageName, c)
1091+ s.assertContainer(mantaStorage, c)
1092+ s.assertFile(mantaStorage, c)
1093+
1094+ names, err := mantaStorage.List("prefix")
1095+ c.Assert(err, gc.IsNil)
1096+ c.Check(names, gc.DeepEquals, []string{fileName})
1097+}
1098+
1099+func (s *storageSuite) TestGet(c *gc.C) {
1100+ mantaStorage := s.assertStorage(storageName, c)
1101+ s.assertFile(mantaStorage, c)
1102+
1103+ reader, err := mantaStorage.Get(fileName)
1104+ c.Assert(err, gc.IsNil)
1105+ c.Assert(reader, gc.NotNil)
1106+ defer reader.Close()
1107+
1108+ data, err := ioutil.ReadAll(reader)
1109+ c.Assert(err, gc.IsNil)
1110+ c.Check(string(data), gc.Equals, fileBlobContent)
1111+}
1112+
1113+func (s *storageSuite) TestGetFileNotExists(c *gc.C) {
1114+ mantaStorage := s.assertStorage(storageName, c)
1115+
1116+ _, err := mantaStorage.Get("noFile")
1117+ c.Assert(err, gc.NotNil)
1118+ c.Assert(err, jc.Satisfies, errors.IsResourceNotFound)
1119+}
1120+
1121+func (s *storageSuite) TestPut(c *gc.C) {
1122+ mantaStorage := s.assertStorage(storageName, c)
1123+
1124+ s.assertFile(mantaStorage, c)
1125+}
1126+
1127+func (s *storageSuite) TestRemove(c *gc.C) {
1128+ mantaStorage := s.assertStorage(storageName, c)
1129+ s.assertFile(mantaStorage, c)
1130+
1131+ err := mantaStorage.Remove(fileName)
1132+ c.Assert(err, gc.IsNil)
1133+}
1134+
1135+func (s *storageSuite) TestRemoveFileNotExists(c *gc.C) {
1136+ mantaStorage := s.assertStorage(storageName, c)
1137+
1138+ err := mantaStorage.Remove("nofile")
1139+ c.Assert(err, gc.NotNil)
1140+ c.Assert(err, jc.Satisfies, errors.IsResourceNotFound)
1141+}
1142+
1143+func (s *storageSuite) TestRemoveAll(c *gc.C) {
1144+ mantaStorage := s.assertStorage(storageName, c)
1145+
1146+ err := mantaStorage.RemoveAll()
1147+ c.Assert(err, gc.IsNil)
1148+}
1149+
1150+func (s *storageSuite) TestURL(c *gc.C) {
1151+ mantaStorage := s.assertStorage(storageName, c)
1152+
1153+ URL, err := mantaStorage.URL(fileName)
1154+ c.Assert(err, gc.IsNil)
1155+ parsedURL, err := url.Parse(URL)
1156+ c.Assert(err, gc.IsNil)
1157+ c.Check(parsedURL.Host, gc.Matches, mantaStorage.GetMantaUrl()[strings.LastIndex(mantaStorage.GetMantaUrl(), "/")+1:])
1158+ c.Check(parsedURL.Path, gc.Matches, fmt.Sprintf("/%s/stor/%s/%s", mantaStorage.GetMantaUser(), mantaStorage.GetContainerName(), fileName))
1159+}
1160+
1161+func (s *storageSuite) TestCreateContainer(c *gc.C) {
1162+ mantaStorage := s.assertStorage(storageName, c)
1163+
1164+ s.assertContainer(mantaStorage, c)
1165+}
1166+
1167+func (s *storageSuite) TestCreateContainerAlreadyExists(c *gc.C) {
1168+ mantaStorage := s.assertStorage(storageName, c)
1169+
1170+ s.assertContainer(mantaStorage, c)
1171+ s.assertContainer(mantaStorage, c)
1172+}
1173+
1174+func (s *storageSuite) TestDeleteContainer(c *gc.C) {
1175+ mantaStorage := s.assertStorage(storageName, c)
1176+ s.assertContainer(mantaStorage, c)
1177+
1178+ err := mantaStorage.DeleteContainer(mantaStorage.GetContainerName())
1179+ c.Assert(err, gc.IsNil)
1180+}
1181+
1182+func (s *storageSuite) TestDeleteContainerNotEmpty(c *gc.C) {
1183+ mantaStorage := s.assertStorage(storageName, c)
1184+ s.assertContainer(mantaStorage, c)
1185+ s.assertFile(mantaStorage, c)
1186+
1187+ err := mantaStorage.DeleteContainer(mantaStorage.GetContainerName())
1188+ c.Assert(err, gc.NotNil)
1189+ c.Assert(err, jc.Satisfies, errors.IsBadRequest)
1190+}
1191+
1192+func (s *storageSuite) TestDeleteContainerNotExists(c *gc.C) {
1193+ mantaStorage := s.assertStorage(storageName, c)
1194+
1195+ err := mantaStorage.DeleteContainer("noContainer")
1196+ c.Assert(err, gc.NotNil)
1197+ c.Assert(err, jc.Satisfies, errors.IsResourceNotFound)
1198+}

Subscribers

People subscribed via source and target branches

to status/vote changes: