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
=== modified file '.bzrignore'
--- .bzrignore 2013-08-27 15:27:47 +0000
+++ .bzrignore 2014-02-27 18:08:22 +0000
@@ -8,3 +8,5 @@
8.emacs.desktop8.emacs.desktop
9.emacs.desktop.lock9.emacs.desktop.lock
10*.test10*.test
11.idea
12add-joyent-provider.iml
1113
=== modified file 'dependencies.tsv'
--- dependencies.tsv 2014-02-25 22:19:30 +0000
+++ dependencies.tsv 2014-02-27 18:08:22 +0000
@@ -6,6 +6,7 @@
6launchpad.net/gnuflag bzr roger.peppe@canonical.com-20121003093437-zcyyw0lpvj2nifpk 126launchpad.net/gnuflag bzr roger.peppe@canonical.com-20121003093437-zcyyw0lpvj2nifpk 12
7launchpad.net/goamz bzr roger.peppe@canonical.com-20131218155244-hbnkvlkkzy3vmlh9 447launchpad.net/goamz bzr roger.peppe@canonical.com-20131218155244-hbnkvlkkzy3vmlh9 44
8launchpad.net/gocheck bzr gustavo@niemeyer.net-20130302024745-6ikofwq2c03h7giu 858launchpad.net/gocheck bzr gustavo@niemeyer.net-20130302024745-6ikofwq2c03h7giu 85
9launchpad.net/gojoyent bzr daniele.stroppa@joyent.com-20140225172734-ltce6n3vrhj3cngg 61
9launchpad.net/golxc bzr ian.booth@canonical.com-20140116225718-lvoikrb0me6zugin 610launchpad.net/golxc bzr ian.booth@canonical.com-20140116225718-lvoikrb0me6zugin 6
10launchpad.net/gomaasapi bzr ian.booth@canonical.com-20131017011445-m1hmr0ap14osd7li 4711launchpad.net/gomaasapi bzr ian.booth@canonical.com-20131017011445-m1hmr0ap14osd7li 47
11launchpad.net/goose bzr tarmac-20140124165235-h9rloooc531udms5 11612launchpad.net/goose bzr tarmac-20140124165235-h9rloooc531udms5 116
1213
=== modified file 'provider/joyent/config.go'
--- provider/joyent/config.go 2013-11-21 17:53:05 +0000
+++ provider/joyent/config.go 2014-02-27 18:08:22 +0000
@@ -22,16 +22,21 @@
22 # sdc-user: <secret>22 # sdc-user: <secret>
23 # Can be set via env variables, or specified here23 # Can be set via env variables, or specified here
24 # sdc-key-id: <secret>24 # sdc-key-id: <secret>
25 # region defaults to us-west-1, override if required25 # url defaults to us-west-1 DC, override if required
26 # sdc-region: us-west-126 # sdc-url: https://us-west-1.api.joyentcloud.com
2727
28 # Manta config28 # Manta config
29 # Can be set via env variables, or specified here29 # Can be set via env variables, or specified here
30 # manta-user: <secret>30 # manta-user: <secret>
31 # Can be set via env variables, or specified here31 # Can be set via env variables, or specified here
32 # manta-key-id: <secret>32 # manta-key-id: <secret>
33 # region defaults to us-east, override if required33 # url defaults to us-east DC, override if required
34 # manta-region: us-east34 # manta-url: https://us-east.manta.joyent.com
35
36 # Auth config
37 # key-file: <secret>
38 # algorithm defaults to rsa-sha256, override if required
39 # algorithm: rsa-sha256
35`40`
3641
37const (42const (
@@ -41,6 +46,7 @@
41 MantaUser = "MANTA_USER"46 MantaUser = "MANTA_USER"
42 MantaKeyId = "MANTA_KEY_ID"47 MantaKeyId = "MANTA_KEY_ID"
43 MantaUrl = "MANTA_URL"48 MantaUrl = "MANTA_URL"
49 Home = "HOME"
44)50)
4551
46var environmentVariables = map[string]string{52var environmentVariables = map[string]string{
@@ -48,21 +54,25 @@
48 "sdc-key-id": SdcKeyId,54 "sdc-key-id": SdcKeyId,
49 "manta-user": MantaUser,55 "manta-user": MantaUser,
50 "manta-key-id": MantaKeyId,56 "manta-key-id": MantaKeyId,
57 "key-file": Home,
51}58}
5259
53var configFields = schema.Fields{60var configFields = schema.Fields{
54 "sdc-user": schema.String(),61 "sdc-user": schema.String(),
55 "sdc-key-id": schema.String(),62 "sdc-key-id": schema.String(),
56 "sdc-region": schema.String(),63 "sdc-url": schema.String(),
57 "manta-user": schema.String(),64 "manta-user": schema.String(),
58 "manta-key-id": schema.String(),65 "manta-key-id": schema.String(),
59 "manta-region": schema.String(),66 "manta-url": schema.String(),
67 "key-file": schema.String(),
68 "algorithm": schema.String(),
60 "control-dir": schema.String(),69 "control-dir": schema.String(),
61}70}
6271
63var configDefaultFields = schema.Defaults{72var configDefaultFields = schema.Defaults{
64 "sdc-region": "us-west-1",73 "sdc-url": "https://us-west-1.api.joyentcloud.com",
65 "manta-region": "us-east",74 "manta-url": "https://us-east.manta.joyent.com",
75 "algorithm": "rsa-sha256",
66}76}
6777
68var configSecretFields = []string{78var configSecretFields = []string{
@@ -70,11 +80,14 @@
70 "sdc-key-id",80 "sdc-key-id",
71 "manta-user",81 "manta-user",
72 "manta-key-id",82 "manta-key-id",
83 "key-file",
73}84}
7485
75var configImmutableFields = []string{86var configImmutableFields = []string{
76 "sdc-region",87 "sdc-url",
77 "manta-region",88 "manta-url",
89 "key-file",
90 "algorithm",
78}91}
7992
80func prepareConfig(cfg *config.Config) (*config.Config, error) {93func prepareConfig(cfg *config.Config) (*config.Config, error) {
@@ -86,7 +99,12 @@
86 if err != nil {99 if err != nil {
87 return nil, err100 return nil, err
88 }101 }
89 attrs["control-bucket"] = fmt.Sprintf("%x", uuid.Raw())102 attrs["control-dir"] = fmt.Sprintf("%x", uuid.Raw())
103 }
104
105 if _, ok := attrs["key-file"]; !ok {
106 localEnvVariableHome := os.Getenv(environmentVariables["key-file"])
107 attrs["key-file"] = fmt.Sprintf("%s/.ssh/id_rsa", localEnvVariableHome)
90 }108 }
91109
92 // Read env variables110 // Read env variables
@@ -165,8 +183,8 @@
165 attrs map[string]interface{}183 attrs map[string]interface{}
166}184}
167185
168func (ecfg *environConfig) sdcRegion() string {186func (ecfg *environConfig) sdcUrl() string {
169 return ecfg.attrs["sdc-region"].(string)187 return ecfg.attrs["sdc-url"].(string)
170}188}
171189
172func (ecfg *environConfig) sdcUser() string {190func (ecfg *environConfig) sdcUser() string {
@@ -177,8 +195,8 @@
177 return ecfg.attrs["sdc-key-id"].(string)195 return ecfg.attrs["sdc-key-id"].(string)
178}196}
179197
180func (ecfg *environConfig) mantaRegion() string {198func (ecfg *environConfig) mantaUrl() string {
181 return ecfg.attrs["manta-region"].(string)199 return ecfg.attrs["manta-url"].(string)
182}200}
183201
184func (ecfg *environConfig) mantaUser() string {202func (ecfg *environConfig) mantaUser() string {
@@ -189,6 +207,14 @@
189 return ecfg.attrs["manta-key-id"].(string)207 return ecfg.attrs["manta-key-id"].(string)
190}208}
191209
210func (ecfg *environConfig) keyFile() string {
211 return ecfg.attrs["key-file"].(string)
212}
213
214func (ecfg *environConfig) algorithm() string {
215 return ecfg.attrs["algorithm"].(string)
216}
217
192func (c *environConfig) controlDir() string {218func (c *environConfig) controlDir() string {
193 return c.attrs["control-dir"].(string)219 return c.attrs["control-dir"].(string)
194}220}
195221
=== modified file 'provider/joyent/config_test.go'
--- provider/joyent/config_test.go 2014-02-13 02:46:58 +0000
+++ provider/joyent/config_test.go 2014-02-27 18:08:22 +0000
@@ -8,7 +8,7 @@
88
9 "launchpad.net/juju-core/environs"9 "launchpad.net/juju-core/environs"
10 "launchpad.net/juju-core/environs/config"10 "launchpad.net/juju-core/environs/config"
11 "launchpad.net/juju-core/provider/joyent"11 jp "launchpad.net/juju-core/provider/joyent"
12 "launchpad.net/juju-core/testing"12 "launchpad.net/juju-core/testing"
13 "launchpad.net/juju-core/testing/testbase"13 "launchpad.net/juju-core/testing/testbase"
14)14)
@@ -23,12 +23,14 @@
23func validAttrs() testing.Attrs {23func validAttrs() testing.Attrs {
24 return testing.FakeConfig().Merge(testing.Attrs{24 return testing.FakeConfig().Merge(testing.Attrs{
25 "type": "joyent",25 "type": "joyent",
26 "sdc-user": "dstroppa",26 "sdc-user": "juju-test",
27 "sdc-key-id": "12:c3:a7:cb:a2:29:e2:90:88:3f:04:53:3b:4e:75:40",27 "sdc-key-id": "00:11:22:33:44:55:66:77:88:99:aa:bb:cc:dd:ee:ff",
28 "sdc-region": "us-west-1",28 "sdc-url": "https://test.api.joyentcloud.com",
29 "manta-user": "dstroppa",29 "manta-user": "juju-test",
30 "manta-key-id": "12:c3:a7:cb:a2:29:e2:90:88:3f:04:53:3b:4e:75:40",30 "manta-key-id": "00:11:22:33:44:55:66:77:88:99:aa:bb:cc:dd:ee:ff",
31 "manta-region": "us-east",31 "manta-url": "https://test.manta.joyent.com",
32 "key-file": "~/.ssh/id_rsa",
33 "algorithm": "rsa-sha256",
32 "control-dir": "juju-test",34 "control-dir": "juju-test",
33 })35 })
34}36}
@@ -41,10 +43,10 @@
41var _ = gc.Suite(&ConfigSuite{})43var _ = gc.Suite(&ConfigSuite{})
4244
43func (s *ConfigSuite) SetUpSuite(c *gc.C) {45func (s *ConfigSuite) SetUpSuite(c *gc.C) {
44 s.PatchEnvironment(joyent.SdcAccount, "tester")46 s.PatchEnvironment(jp.SdcAccount, "tester")
45 s.PatchEnvironment(joyent.SdcKeyId, "11:c4:b6:c0:a3:24:22:96:a8:1f:07:53:3f:8e:14:7a")47 s.PatchEnvironment(jp.SdcKeyId, "ff:ee:dd:cc:bb:aa:99:88:77:66:55:44:33:22:11:00")
46 s.PatchEnvironment(joyent.MantaUser, "tester")48 s.PatchEnvironment(jp.MantaUser, "tester")
47 s.PatchEnvironment(joyent.MantaKeyId, "11:c4:b6:c0:a3:24:22:96:a8:1f:07:53:3f:8e:14:7a")49 s.PatchEnvironment(jp.MantaKeyId, "ff:ee:dd:cc:bb:aa:99:88:77:66:55:44:33:22:11:00")
48}50}
4951
50var newConfigTests = []struct {52var newConfigTests = []struct {
@@ -70,16 +72,16 @@
70 insert: testing.Attrs{"sdc-key-id": ""},72 insert: testing.Attrs{"sdc-key-id": ""},
71 err: "sdc-key-id: must not be empty",73 err: "sdc-key-id: must not be empty",
72}, {74}, {
73 info: "sdc-region is inserted if missing",75 info: "sdc-url is inserted if missing",
74 expect: testing.Attrs{"sdc-region": "us-west-1"},76 expect: testing.Attrs{"sdc-url": "https://test.api.joyentcloud.com"},
75}, {77}, {
76 info: "sdc-region cannot be empty",78 info: "sdc-url cannot be empty",
77 insert: testing.Attrs{"sdc-region": ""},79 insert: testing.Attrs{"sdc-url": ""},
78 err: "sdc-region: must not be empty",80 err: "sdc-url: must not be empty",
79}, {81}, {
80 info: "sdc-region is untouched if present",82 info: "sdc-url is untouched if present",
81 insert: testing.Attrs{"sdc-region": "us-west-1"},83 insert: testing.Attrs{"sdc-url": "https://test.api.joyentcloud.com"},
82 expect: testing.Attrs{"sdc-region": "us-west-1"},84 expect: testing.Attrs{"sdc-url": "https://test.api.joyentcloud.com"},
83}, {85}, {
84 info: "manta-user is required",86 info: "manta-user is required",
85 remove: []string{"manta-user"},87 remove: []string{"manta-user"},
@@ -97,16 +99,30 @@
97 insert: testing.Attrs{"manta-key-id": ""},99 insert: testing.Attrs{"manta-key-id": ""},
98 err: "manta-key-id: must not be empty",100 err: "manta-key-id: must not be empty",
99}, {101}, {
100 info: "manta-region is inserted if missing",102 info: "manta-url is inserted if missing",
101 expect: testing.Attrs{"manta-region": "us-east"},103 expect: testing.Attrs{"manta-url": "https://test.manta.joyent.com"},
102}, {104}, {
103 info: "manta-region cannot be empty",105 info: "manta-url cannot be empty",
104 insert: testing.Attrs{"manta-region": ""},106 insert: testing.Attrs{"manta-url": ""},
105 err: "manta-region: must not be empty",107 err: "manta-url: must not be empty",
106}, {108}, {
107 info: "manta-region is untouched if present",109 info: "manta-url is untouched if present",
108 insert: testing.Attrs{"manta-region": "us-east"},110 insert: testing.Attrs{"manta-url": "https://test.manta.joyent.com"},
109 expect: testing.Attrs{"manta-region": "us-east"},111 expect: testing.Attrs{"manta-url": "https://test.manta.joyent.com"},
112}, {
113 info: "key-file is inserted if missing",
114 expect: testing.Attrs{"key-file": "~/.ssh/id_rsa"},
115}, {
116 info: "key-file cannot be empty",
117 insert: testing.Attrs{"key-file": ""},
118 err: "key-file: must not be empty",
119}, {
120 info: "algorithm is inserted if missing",
121 expect: testing.Attrs{"algorithm": "rsa-sha256"},
122}, {
123 info: "algorithm cannot be empty",
124 insert: testing.Attrs{"algorithm": ""},
125 err: "algorithm: must not be empty",
110}, {126}, {
111 info: "unknown field is not touched",127 info: "unknown field is not touched",
112 insert: testing.Attrs{"unknown-field": 12345},128 insert: testing.Attrs{"unknown-field": 12345},
@@ -137,7 +153,7 @@
137 c.Logf("test %d: %s", i, test.info)153 c.Logf("test %d: %s", i, test.info)
138 attrs := validAttrs().Merge(test.insert).Delete(test.remove...)154 attrs := validAttrs().Merge(test.insert).Delete(test.remove...)
139 testConfig := newConfig(c, attrs)155 testConfig := newConfig(c, attrs)
140 validatedConfig, err := joyent.Provider.Validate(testConfig, nil)156 validatedConfig, err := Provider.Validate(testConfig, nil)
141 if test.err == "" {157 if test.err == "" {
142 c.Assert(err, gc.IsNil)158 c.Assert(err, gc.IsNil)
143 attrs := validatedConfig.AllAttrs()159 attrs := validatedConfig.AllAttrs()
@@ -157,7 +173,7 @@
157 c.Logf("test %d: %s", i, test.info)173 c.Logf("test %d: %s", i, test.info)
158 attrs := validAttrs().Merge(test.insert).Delete(test.remove...)174 attrs := validAttrs().Merge(test.insert).Delete(test.remove...)
159 testConfig := newConfig(c, attrs)175 testConfig := newConfig(c, attrs)
160 validatedConfig, err := joyent.Provider.Validate(knownGoodConfig, testConfig)176 validatedConfig, err := Provider.Validate(knownGoodConfig, testConfig)
161 if test.err == "" {177 if test.err == "" {
162 c.Assert(err, gc.IsNil)178 c.Assert(err, gc.IsNil)
163 attrs := validatedConfig.AllAttrs()179 attrs := validatedConfig.AllAttrs()
@@ -186,24 +202,24 @@
186 expect: testing.Attrs{"sdc-user": "joyent_user"},202 expect: testing.Attrs{"sdc-user": "joyent_user"},
187}, {203}, {
188 info: "can change sdc-key-id",204 info: "can change sdc-key-id",
189 insert: testing.Attrs{"sdc-key-id": "11:c4:b6:c0:a3:24:22:96:a8:1f:07:53:3f:8e:14:7a"},205 insert: testing.Attrs{"sdc-key-id": "ff:ee:dd:cc:bb:aa:99:88:77:66:55:44:33:22:11:00"},
190 expect: testing.Attrs{"sdc-key-id": "11:c4:b6:c0:a3:24:22:96:a8:1f:07:53:3f:8e:14:7a"},206 expect: testing.Attrs{"sdc-key-id": "ff:ee:dd:cc:bb:aa:99:88:77:66:55:44:33:22:11:00"},
191}, {207}, {
192 info: "can change sdc-region",208 info: "can change sdc-url",
193 insert: testing.Attrs{"sdc-region": "us-west-1"},209 insert: testing.Attrs{"sdc-url": "https://test.api.joyentcloud.com"},
194 expect: testing.Attrs{"sdc-region": "us-west-1"},210 expect: testing.Attrs{"sdc-url": "https://test.api.joyentcloud.com"},
195}, {211}, {
196 info: "can change manta-user",212 info: "can change manta-user",
197 insert: testing.Attrs{"manta-user": "manta_user"},213 insert: testing.Attrs{"manta-user": "manta_user"},
198 expect: testing.Attrs{"manta-user": "manta_user"},214 expect: testing.Attrs{"manta-user": "manta_user"},
199}, {215}, {
200 info: "can change manta-key-id",216 info: "can change manta-key-id",
201 insert: testing.Attrs{"manta-key-id": "11:c4:b6:c0:a3:24:22:96:a8:1f:07:53:3f:8e:14:7a"},217 insert: testing.Attrs{"manta-key-id": "ff:ee:dd:cc:bb:aa:99:88:77:66:55:44:33:22:11:00"},
202 expect: testing.Attrs{"manta-key-id": "11:c4:b6:c0:a3:24:22:96:a8:1f:07:53:3f:8e:14:7a"},218 expect: testing.Attrs{"manta-key-id": "ff:ee:dd:cc:bb:aa:99:88:77:66:55:44:33:22:11:00"},
203}, {219}, {
204 info: "can change manta-region",220 info: "can change manta-url",
205 insert: testing.Attrs{"manta-region": "us-east"},221 insert: testing.Attrs{"manta-url": "https://test.manta.joyent.com"},
206 expect: testing.Attrs{"manta-region": "us-east"},222 expect: testing.Attrs{"manta-url": "https://test.manta.joyent.com"},
207}, {223}, {
208 info: "can insert unknown field",224 info: "can insert unknown field",
209 insert: testing.Attrs{"unknown": "ignoti"},225 insert: testing.Attrs{"unknown": "ignoti"},
@@ -216,7 +232,7 @@
216 c.Logf("test %d: %s", i, test.info)232 c.Logf("test %d: %s", i, test.info)
217 attrs := validAttrs().Merge(test.insert).Delete(test.remove...)233 attrs := validAttrs().Merge(test.insert).Delete(test.remove...)
218 testConfig := newConfig(c, attrs)234 testConfig := newConfig(c, attrs)
219 validatedConfig, err := joyent.Provider.Validate(testConfig, baseConfig)235 validatedConfig, err := Provider.Validate(testConfig, baseConfig)
220 if test.err == "" {236 if test.err == "" {
221 c.Assert(err, gc.IsNil)237 c.Assert(err, gc.IsNil)
222 attrs := validatedConfig.AllAttrs()238 attrs := validatedConfig.AllAttrs()
@@ -270,7 +286,7 @@
270}, {286}, {
271 info: "can get sdc-key-id from env variable",287 info: "can get sdc-key-id from env variable",
272 insert: testing.Attrs{"sdc-key-id": ""},288 insert: testing.Attrs{"sdc-key-id": ""},
273 expect: testing.Attrs{"sdc-key-id": "11:c4:b6:c0:a3:24:22:96:a8:1f:07:53:3f:8e:14:7a"},289 expect: testing.Attrs{"sdc-key-id": "ff:ee:dd:cc:bb:aa:99:88:77:66:55:44:33:22:11:00"},
274}, {290}, {
275 info: "can get manta-user from env variable",291 info: "can get manta-user from env variable",
276 insert: testing.Attrs{"manta-user": ""},292 insert: testing.Attrs{"manta-user": ""},
@@ -278,7 +294,7 @@
278}, {294}, {
279 info: "can get manta-key-id from env variable",295 info: "can get manta-key-id from env variable",
280 insert: testing.Attrs{"manta-key-id": ""},296 insert: testing.Attrs{"manta-key-id": ""},
281 expect: testing.Attrs{"manta-key-id": "11:c4:b6:c0:a3:24:22:96:a8:1f:07:53:3f:8e:14:7a"},297 expect: testing.Attrs{"manta-key-id": "ff:ee:dd:cc:bb:aa:99:88:77:66:55:44:33:22:11:00"},
282}}298}}
283299
284func (s *ConfigSuite) TestPrepare(c *gc.C) {300func (s *ConfigSuite) TestPrepare(c *gc.C) {
@@ -286,7 +302,7 @@
286 c.Logf("test %d: %s", i, test.info)302 c.Logf("test %d: %s", i, test.info)
287 attrs := validAttrs().Merge(test.insert).Delete(test.remove...)303 attrs := validAttrs().Merge(test.insert).Delete(test.remove...)
288 testConfig := newConfig(c, attrs)304 testConfig := newConfig(c, attrs)
289 preparedConfig, err := joyent.Provider.Prepare(testing.Context(c), testConfig)305 preparedConfig, err := Provider.Prepare(testing.Context(c), testConfig)
290 if test.err == "" {306 if test.err == "" {
291 c.Assert(err, gc.IsNil)307 c.Assert(err, gc.IsNil)
292 attrs := preparedConfig.Config().AllAttrs()308 attrs := preparedConfig.Config().AllAttrs()
293309
=== modified file 'provider/joyent/environ.go'
--- provider/joyent/environ.go 2013-12-19 08:40:11 +0000
+++ provider/joyent/environ.go 2014-02-27 18:08:22 +0000
@@ -23,7 +23,7 @@
23// must be implemented ) and environ_firewall.go (which can be safely23// must be implemented ) and environ_firewall.go (which can be safely
24// ignored until you've got an environment bootstrapping successfully).24// ignored until you've got an environment bootstrapping successfully).
2525
26type environ struct {26type JoyentEnviron struct {
27 name string27 name string
28 // All mutating operations should lock the mutex. Non-mutating operations28 // All mutating operations should lock the mutex. Non-mutating operations
29 // should read all fields (other than name, which is immutable) from a29 // should read all fields (other than name, which is immutable) from a
@@ -35,17 +35,32 @@
35 storage storage.Storage35 storage storage.Storage
36}36}
3737
38var _ environs.Environ = (*environ)(nil)38var _ environs.Environ = (*JoyentEnviron)(nil)
3939
40func (env *environ) Name() string {40func NewEnviron(cfg *config.Config) (*JoyentEnviron, error) {
41 env := new(JoyentEnviron)
42 err := env.SetConfig(cfg)
43 if err != nil {
44 return nil, err
45 }
46 env.name = cfg.Name()
47 env.storage = NewStorage(env)
48 return env, nil
49}
50
51func (env *JoyentEnviron) SetName(envName string) {
52 env.name = envName
53}
54
55func (env *JoyentEnviron) Name() string {
41 return env.name56 return env.name
42}57}
4358
44func (*environ) Provider() environs.EnvironProvider {59func (*JoyentEnviron) Provider() environs.EnvironProvider {
45 return providerInstance60 return providerInstance
46}61}
4762
48func (env *environ) SetConfig(cfg *config.Config) error {63func (env *JoyentEnviron) SetConfig(cfg *config.Config) error {
49 env.lock.Lock()64 env.lock.Lock()
50 defer env.lock.Unlock()65 defer env.lock.Unlock()
51 ecfg, err := validateConfig(cfg, env.ecfg)66 ecfg, err := validateConfig(cfg, env.ecfg)
@@ -61,7 +76,7 @@
61 return nil76 return nil
62}77}
6378
64func (env *environ) getSnapshot() *environ {79func (env *JoyentEnviron) getSnapshot() *JoyentEnviron {
65 env.lock.Lock()80 env.lock.Lock()
66 clone := *env81 clone := *env
67 env.lock.Unlock()82 env.lock.Unlock()
@@ -69,26 +84,26 @@
69 return &clone84 return &clone
70}85}
7186
72func (env *environ) Config() *config.Config {87func (env *JoyentEnviron) Config() *config.Config {
73 return env.getSnapshot().ecfg.Config88 return env.getSnapshot().ecfg.Config
74}89}
7590
76func (env *environ) Storage() storage.Storage {91func (env *JoyentEnviron) Storage() storage.Storage {
77 return env.getSnapshot().storage92 return env.getSnapshot().storage
78}93}
7994
80func (env *environ) PublicStorage() storage.StorageReader {95func (env *JoyentEnviron) PublicStorage() storage.StorageReader {
81 return environs.EmptyStorage96 return environs.EmptyStorage
82}97}
8398
84func (env *environ) Bootstrap(ctx environs.BootstrapContext, cons constraints.Value) error {99func (env *JoyentEnviron) Bootstrap(ctx environs.BootstrapContext, cons constraints.Value) error {
85 return common.Bootstrap(ctx, env, cons)100 return common.Bootstrap(ctx, env, cons)
86}101}
87102
88func (env *environ) StateInfo() (*state.Info, *api.Info, error) {103func (env *JoyentEnviron) StateInfo() (*state.Info, *api.Info, error) {
89 return common.StateInfo(env)104 return common.StateInfo(env)
90}105}
91106
92func (env *environ) Destroy() error {107func (env *JoyentEnviron) Destroy() error {
93 return common.Destroy(env)108 return common.Destroy(env)
94}109}
95110
=== modified file 'provider/joyent/environ_firewall.go'
--- provider/joyent/environ_firewall.go 2013-10-07 10:57:04 +0000
+++ provider/joyent/environ_firewall.go 2014-02-27 18:08:22 +0000
@@ -11,19 +11,19 @@
11// cause `juju expose` to work when the firewall-mode is "global". If you11// cause `juju expose` to work when the firewall-mode is "global". If you
12// implement one of them, you should implement them all.12// implement one of them, you should implement them all.
1313
14func (env *environ) OpenPorts(ports []instance.Port) error {14func (env *JoyentEnviron) OpenPorts(ports []instance.Port) error {
15 logger.Warningf("pretending to open ports %v for all instances", ports)15 logger.Warningf("pretending to open ports %v for all instances", ports)
16 _ = env.getSnapshot()16 _ = env.getSnapshot()
17 return nil17 return nil
18}18}
1919
20func (env *environ) ClosePorts(ports []instance.Port) error {20func (env *JoyentEnviron) ClosePorts(ports []instance.Port) error {
21 logger.Warningf("pretending to close ports %v for all instances", ports)21 logger.Warningf("pretending to close ports %v for all instances", ports)
22 _ = env.getSnapshot()22 _ = env.getSnapshot()
23 return nil23 return nil
24}24}
2525
26func (env *environ) Ports() ([]instance.Port, error) {26func (env *JoyentEnviron) Ports() ([]instance.Port, error) {
27 _ = env.getSnapshot()27 _ = env.getSnapshot()
28 return nil, nil28 return nil, nil
29}29}
3030
=== modified file 'provider/joyent/environ_instance.go'
--- provider/joyent/environ_instance.go 2013-10-07 10:57:04 +0000
+++ provider/joyent/environ_instance.go 2014-02-27 18:08:22 +0000
@@ -10,7 +10,7 @@
10 "launchpad.net/juju-core/tools"10 "launchpad.net/juju-core/tools"
11)11)
1212
13func (env *environ) StartInstance(13func (env *JoyentEnviron) StartInstance(
14 cons constraints.Value, possibleTools tools.List, machineConf *cloudinit.MachineConfig,14 cons constraints.Value, possibleTools tools.List, machineConf *cloudinit.MachineConfig,
15) (15) (
16 instance.Instance, *instance.HardwareCharacteristics, error,16 instance.Instance, *instance.HardwareCharacteristics, error,
@@ -22,7 +22,7 @@
22 return nil, nil, errNotImplemented22 return nil, nil, errNotImplemented
23}23}
2424
25func (env *environ) AllInstances() ([]instance.Instance, error) {25func (env *JoyentEnviron) AllInstances() ([]instance.Instance, error) {
26 // Please note that this must *not* return instances that have not been26 // Please note that this must *not* return instances that have not been
27 // allocated as part of this environment -- if it does, juju will see they27 // allocated as part of this environment -- if it does, juju will see they
28 // are not tracked in state, assume they're stale/rogue, and shut them down.28 // are not tracked in state, assume they're stale/rogue, and shut them down.
@@ -30,7 +30,7 @@
30 return nil, errNotImplemented30 return nil, errNotImplemented
31}31}
3232
33func (env *environ) Instances(ids []instance.Id) ([]instance.Instance, error) {33func (env *JoyentEnviron) Instances(ids []instance.Id) ([]instance.Instance, error) {
34 // Please note that this must *not* return instances that have not been34 // Please note that this must *not* return instances that have not been
35 // allocated as part of this environment -- if it does, juju will see they35 // allocated as part of this environment -- if it does, juju will see they
36 // are not tracked in state, assume they're stale/rogue, and shut them down.36 // are not tracked in state, assume they're stale/rogue, and shut them down.
@@ -41,7 +41,7 @@
41 return nil, errNotImplemented41 return nil, errNotImplemented
42}42}
4343
44func (env *environ) StopInstances(instances []instance.Instance) error {44func (env *JoyentEnviron) StopInstances(instances []instance.Instance) error {
45 _ = env.getSnapshot()45 _ = env.getSnapshot()
46 return errNotImplemented46 return errNotImplemented
47}47}
4848
=== modified file 'provider/joyent/export_test.go'
--- provider/joyent/export_test.go 2013-10-07 10:57:04 +0000
+++ provider/joyent/export_test.go 2014-02-27 18:08:22 +0000
@@ -1,10 +1,11 @@
1// Copyright 2013 Joyent Inc.1// Copyright 2013 Joyent Inc.
2// Licensed under the AGPLv3, see LICENCE file for details.2// Licensed under the AGPLv3, see LICENCE file for details.
33
4package joyent4package joyent_test
55
6import (6import (
7 "launchpad.net/juju-core/environs"7 "launchpad.net/juju-core/environs"
8 jp "launchpad.net/juju-core/provider/joyent"
8)9)
910
10var Provider environs.EnvironProvider = providerInstance11var Provider environs.EnvironProvider = jp.GetProviderInstance()
1112
=== modified file 'provider/joyent/instance.go'
--- provider/joyent/instance.go 2013-12-16 09:53:26 +0000
+++ provider/joyent/instance.go 2014-02-27 18:08:22 +0000
@@ -10,7 +10,7 @@
1010
11type environInstance struct {11type environInstance struct {
12 id instance.Id12 id instance.Id
13 env *environ13 env *JoyentEnviron
14}14}
1515
16var _ instance.Instance = (*environInstance)(nil)16var _ instance.Instance = (*environInstance)(nil)
1717
=== modified file 'provider/joyent/joyent_test.go'
--- provider/joyent/joyent_test.go 2013-10-10 09:24:18 +0000
+++ provider/joyent/joyent_test.go 2014-02-27 18:08:22 +0000
@@ -4,24 +4,177 @@
4package joyent_test4package joyent_test
55
6import (6import (
7 "testing"7 "fmt"
8 "io/ioutil"
9 "net/http"
10 "net/http/httptest"
11 "os"
12 stdtesting "testing"
813
9 gc "launchpad.net/gocheck"14 gc "launchpad.net/gocheck"
1015
11 "launchpad.net/juju-core/environs"16 "launchpad.net/juju-core/environs/config"
12 "launchpad.net/juju-core/provider/joyent"17 envtesting "launchpad.net/juju-core/environs/testing"
13)18 jp "launchpad.net/juju-core/provider/joyent"
1419 coretesting "launchpad.net/juju-core/testing"
15func TestPackage(t *testing.T) {20 "launchpad.net/juju-core/testing/testbase"
21
22 "launchpad.net/gojoyent/jpc"
23 localmanta "launchpad.net/gojoyent/localservices/manta"
24)
25
26const (
27 testUser = "test"
28 testKeyFileName = "provider_id_rsa"
29 testPrivateKey = `-----BEGIN RSA PRIVATE KEY-----
30MIIEpAIBAAKCAQEAza+KvczCrcpQGRq9e347VHx9oEvuhseJt0ydR+UMAveyQprU
314JHvzwUUhGnG147GJQYyfQ4nzaSG62az/YThoZJzw8gtxGkVHv0wlAlRkYhxbKbq
328WQIh73xDQkHLw2lXLvf7Tt0Mhow0qGEmkOjTb5fPsj2evphrV3jJ15QlhL4cv33
33t8jVadIrL0iIpwdqWiPqUKpsrSfKJghkoXS6quPy78P820TnuoBG+/Ppr8Kkvn6m
34A7j4xnOQ12QE6jPK4zkikj5ZczSC4fTG0d3BwwX4VYu+4y/T/BX0L9VNUmQU22Y+
35/MRXAUZxsa8VhNB+xXF5XSubyb2n6loMWWaYGwIDAQABAoIBAQDCJt9JxYxGS+BL
36sigF9+O9Hj3fH42p/5QJR/J2uMgbzP+hS1GCIX9B5MO3MbmWI5j5vd3OmZwMyy7n
376Wwg9FufDgTkW4KIEcD0HX7LXfh27VpTe0PuU8SRjUOKUGlNiw36eQUog6Rs3rgT
38Oo9Wpl3xtq9lLoErGEk3QpZ2xNpArTfsN9N3pdmD4sv7wmJq0PZQyej482g9R0g/
395k2ni6JpcEifzBQ6Bzx3EV2l9UipEIqbqDpMOtYFCpnLQhEaDfUribqXINGIsjiq
40VyFa3Mbg/eayqG3UX3rVTCif2NnW2ojl4mMgWCyxgWfb4Jg1trc3v7X4SXfbgPWD
41WcfrOhOhAoGBAP7ZC8KHAnjujwvXf3PxVNm6CTs5evbByQVyxNciGxRuOomJIR4D
42euqepQ4PuNAabnrbMyQWXpibIKpmLnBVoj1q0IMXYvi2MZF5e2tH/Gx01UvxamHh
43bKhHmp9ImHhVl6kObXOdNvLVTt/BI5FZBblvm7qOoiVwImPbqqVHP7Q5AoGBAM6d
44mNsrW0iV/nP1m7d8mcFw74PI0FNlNdfUoePUgokO0t5OU0Ri/lPBDCRGlvVF3pj1
45HnmwroNtdWr9oPVB6km8193fb2zIWe53tj+6yRFQpz5elrSPfeZaZXlJZAGCCCdN
46gBggWQFPeQiT54aPywPpcTZHIs72XBqQ6QsIPrbzAoGAdW2hg5MeSobyFuzHZ69N
47/70/P7DuvgDxFbeah97JR5K7GmC7h87mtnE/cMlByXJEcgvK9tfv4rWoSZwnzc9H
48oLE1PxJpolyhXnzxp69V2svC9OlasZtjq+7Cip6y0s/twBJL0Lgid6ZeX6/pKbIx
49dw68XSwX/tQ6pHS1ns7DxdECgYBJbBWapNCefbbbjEcWsC+PX0uuABmP2SKGHSie
50ZrEwdVUX7KuIXMlWB/8BkRgp9vdAUbLPuap6R9Z2+8RMA213YKUxUiotdREIPgBE
51q2KyRX/5GPHjHi62Qh9XN25TXtr45ICFklEutwgitTSMS+Lv8+/oQuUquL9ILYCz
52C+4FYwKBgQDE9yZTUpJjG2424z6bl/MHzwl5RB4pMronp0BbeVqPwhCBfj0W5I42
531ZL4+8eniHfUs4GXzf5tb9YwVt3EltIF2JybaBvFsv2o356yJUQmqQ+jyYRoEpT5
542SwilFo/XCotCXxi5n8sm9V94a0oix4ehZrohTA/FZLsggwFCPmXfw==
55-----END RSA PRIVATE KEY-----`
56 testKeyFingerprint = "66:ca:1c:09:75:99:35:69:be:91:08:25:03:c0:17:c0"
57)
58
59func TestJoyentProvider(t *stdtesting.T) {
16 gc.TestingT(t)60 gc.TestingT(t)
17}61}
1862
19type JoyentSuite struct{}63type localMantaService struct {
2064 creds *jpc.Credentials
21var _ = gc.Suite(&JoyentSuite{})65 Server *httptest.Server
2266 Mux *http.ServeMux
23func (*JoyentSuite) TestRegistered(c *gc.C) {67 oldHandler http.Handler
24 provider, err := environs.Provider("joyent")68 manta *localmanta.Manta
25 c.Assert(err, gc.IsNil)69}
26 c.Assert(provider, gc.Equals, joyent.Provider)70
71func (s *localMantaService) Start(c *gc.C) {
72 // Set up the HTTP server.
73 s.Server = httptest.NewServer(nil)
74 c.Assert(s.Server, gc.NotNil)
75 s.oldHandler = s.Server.Config.Handler
76 s.Mux = http.NewServeMux()
77 s.Server.Config.Handler = s.Mux
78
79 // Set up a Joyent Manta service.
80 auth := jpc.Auth{User: testUser, KeyFile: testKeyFileName, Algorithm: "rsa-sha256"}
81
82 s.creds = &jpc.Credentials{
83 UserAuthentication: auth,
84 MantaKeyId: testKeyFingerprint,
85 MantaEndpoint: jpc.Endpoint{URL: s.Server.URL},
86 }
87 s.manta = localmanta.New(s.creds.MantaEndpoint.URL, s.creds.UserAuthentication.User)
88 s.manta.SetupHTTP(s.Mux)
89 c.Logf("Started local Manta service at: %v", s.Server.URL)
90}
91
92func (s *localMantaService) Stop() {
93 s.Mux = nil
94 s.Server.Config.Handler = s.oldHandler
95 s.Server.Close()
96}
97
98type providerSuite struct {
99 testbase.LoggingSuite
100 envtesting.ToolsFixture
101 restoreTimeouts func()
102}
103
104var _ = gc.Suite(&providerSuite{})
105
106func (s *providerSuite) SetUpSuite(c *gc.C) {
107 s.restoreTimeouts = envtesting.PatchAttemptStrategies()
108 s.LoggingSuite.SetUpSuite(c)
109 createTestKey()
110}
111
112func (s *providerSuite) TearDownSuite(c *gc.C) {
113 removeTestKey()
114 s.restoreTimeouts()
115 s.LoggingSuite.TearDownSuite(c)
116}
117
118func (s *providerSuite) SetUpTest(c *gc.C) {
119 s.LoggingSuite.SetUpTest(c)
120 s.ToolsFixture.SetUpTest(c)
121}
122
123func (s *providerSuite) TearDownTest(c *gc.C) {
124 s.ToolsFixture.TearDownTest(c)
125 s.LoggingSuite.TearDownTest(c)
126}
127
128func GetFakeConfig(sdcUrl, mantaUrl string) coretesting.Attrs {
129 return coretesting.FakeConfig().Merge(coretesting.Attrs{
130 "name": "joyent test environment",
131 "type": "joyent",
132 "sdc-user": testUser,
133 "sdc-key-id": testKeyFingerprint,
134 "sdc-url": sdcUrl,
135 "manta-user": testUser,
136 "manta-key-id": testKeyFingerprint,
137 "manta-url": mantaUrl,
138 "key-file": fmt.Sprintf("%s/.ssh/%s", os.Getenv("HOME"), testKeyFileName),
139 "algorithm": "rsa-sha256",
140 "control-dir": "juju-test",
141 })
142}
143
144// makeEnviron creates a functional Joyent environ for a test.
145func (suite *providerSuite) makeEnviron(sdcUrl, mantaUrl string) *jp.JoyentEnviron {
146 /*attrs := coretesting.FakeConfig().Merge(coretesting.Attrs{
147 "name": "joyent test environment",
148 "type": "joyent",
149 "sdc-user": "dstroppa",
150 "sdc-key-id": "12:c3:a7:cb:a2:29:e2:90:88:3f:04:53:3b:4e:75:40",
151 "sdc-url": "https://us-west-1.api.joyentcloud.com",
152 "manta-user": "dstroppa",
153 "manta-key-id": "12:c3:a7:cb:a2:29:e2:90:88:3f:04:53:3b:4e:75:40",
154 "manta-url": "https://us-east.manta.joyent.com",
155 "key-file": fmt.Sprintf("%s/.ssh/id_rsa", os.Getenv("HOME")),
156 "algorithm": "rsa-sha256",
157 "control-dir": "juju-test",
158 })*/
159
160 attrs := GetFakeConfig(sdcUrl, mantaUrl)
161 cfg, err := config.New(config.NoDefaults, attrs)
162 if err != nil {
163 panic(err)
164 }
165 env, err := jp.NewEnviron(cfg)
166 if err != nil {
167 panic(err)
168 }
169 return env
170}
171
172func createTestKey() error {
173 keyFile := fmt.Sprintf("%s/.ssh/%s", os.Getenv("HOME"), testKeyFileName)
174 return ioutil.WriteFile(keyFile, []byte(testPrivateKey), 400)
175}
176
177func removeTestKey() error {
178 keyFile := fmt.Sprintf("%s/.ssh/%s", os.Getenv("HOME"), testKeyFileName)
179 return os.Remove(keyFile)
27}180}
28181
=== modified file 'provider/joyent/provider.go'
--- provider/joyent/provider.go 2014-02-13 02:46:58 +0000
+++ provider/joyent/provider.go 2014-02-27 18:08:22 +0000
@@ -45,7 +45,7 @@
45}45}
4646
47func (environProvider) Open(cfg *config.Config) (environs.Environ, error) {47func (environProvider) Open(cfg *config.Config) (environs.Environ, error) {
48 env := &environ{name: cfg.Name()}48 env := &JoyentEnviron{name: cfg.Name()}
49 if err := env.SetConfig(cfg); err != nil {49 if err := env.SetConfig(cfg); err != nil {
50 return nil, err50 return nil, err
51 }51 }
@@ -118,3 +118,7 @@
118 // provider; and it needs to return the address of *that* instance.118 // provider; and it needs to return the address of *that* instance.
119 return "", errNotImplemented119 return "", errNotImplemented
120}120}
121
122func GetProviderInstance() environs.EnvironProvider {
123 return providerInstance
124}
121125
=== modified file 'provider/joyent/storage.go'
--- provider/joyent/storage.go 2013-11-21 17:37:18 +0000
+++ provider/joyent/storage.go 2014-02-27 18:08:22 +0000
@@ -4,50 +4,194 @@
4package joyent4package joyent
55
6import (6import (
7 "bytes"
8 "fmt"
7 "io"9 "io"
10 "sync"
11 "time"
812
9 "launchpad.net/juju-core/environs/storage"13 "launchpad.net/juju-core/environs/storage"
10 "launchpad.net/juju-core/utils"14 "launchpad.net/juju-core/utils"
15
16 "launchpad.net/gojoyent/client"
17 "launchpad.net/gojoyent/jpc"
18 "launchpad.net/gojoyent/manta"
11)19)
1220
13type environStorage struct {21type JoyentStorage struct {
14 ecfg *environConfig22 sync.Mutex
15}23 ecfg *environConfig
1624 madeContainer bool
17var _ storage.Storage = (*environStorage)(nil)25 containerName string
26 manta *manta.Client
27}
28
29type byteCloser struct {
30 io.Reader
31}
32
33func (byteCloser) Close() error {
34 return nil
35}
36
37var _ storage.Storage = (*JoyentStorage)(nil)
38
39func NewStorage(env *JoyentEnviron) storage.Storage {
40 if stor, err := newStorage(env.ecfg); err == nil {
41 return stor
42 }
43 return nil
44}
45
46func getCredentials(ecfg *environConfig) *jpc.Credentials {
47 auth := jpc.Auth{User: ecfg.mantaUser(), KeyFile: ecfg.keyFile(), Algorithm: ecfg.algorithm()}
48
49 return &jpc.Credentials{
50 UserAuthentication: auth,
51 MantaKeyId: ecfg.mantaKeyId(),
52 MantaEndpoint: jpc.Endpoint{URL: ecfg.mantaUrl()},
53 }
54}
1855
19func newStorage(ecfg *environConfig) (storage.Storage, error) {56func newStorage(ecfg *environConfig) (storage.Storage, error) {
20 return &environStorage{ecfg}, nil57 client := client.NewClient(ecfg.mantaUrl(), "", getCredentials(ecfg), &logger)
21}58
2259 return &JoyentStorage{
23func (s *environStorage) List(prefix string) ([]string, error) {60 ecfg: ecfg,
24 return nil, errNotImplemented61 containerName: ecfg.controlDir(),
25}62 manta: manta.New(client)}, nil
2663}
27func (s *environStorage) URL(name string) (string, error) {64
28 return "", errNotImplemented65func (s *JoyentStorage) GetContainerName() string {
29}66 return s.containerName
3067}
31func (s *environStorage) Get(name string) (io.ReadCloser, error) {68
32 return nil, errNotImplemented69func (s *JoyentStorage) GetMantaUrl() string {
33}70 return s.ecfg.mantaUrl()
3471}
35func (s *environStorage) Put(name string, r io.Reader, length int64) error {72
36 return errNotImplemented73func (s *JoyentStorage) GetMantaUser() string {
37}74 return s.ecfg.mantaUser()
3875}
39func (s *environStorage) Remove(name string) error {76
40 return errNotImplemented77// CreateContainer makes the environment's control container, the
41}78// place where bootstrap information and deployed charms
4279// are stored. To avoid two round trips on every PUT operation,
43func (s *environStorage) RemoveAll() error {80// we do this only once for each environ.
44 return errNotImplemented81func (s *JoyentStorage) CreateContainer() error {
45}82 s.Lock()
4683 defer s.Unlock()
47func (s *environStorage) DefaultConsistencyStrategy() utils.AttemptStrategy {84 if s.madeContainer {
85 return nil
86 }
87 // try to make the container
88 err := s.manta.PutDirectory(s.containerName)
89 if err == nil {
90 s.madeContainer = true
91 }
92 return err
93}
94
95// deleteContainer deletes the named container from the storage account.
96func (s *JoyentStorage) DeleteContainer(containerName string) error {
97 err := s.manta.DeleteDirectory(containerName)
98 if err == nil {
99 s.madeContainer = false
100 }
101 return err
102}
103
104func (s *JoyentStorage) List(prefix string) ([]string, error) {
105 // use empty opts, i.e. default values
106 // -- might be added in the provider config?
107 contents, err := s.manta.ListDirectory(s.containerName, manta.ListDirectoryOpts{})
108 if err != nil {
109 return nil, err
110 }
111 var names []string
112 for _, item := range contents {
113 names = append(names, item.Name)
114 }
115 return names, nil
116}
117
118//return something that a random wget can retrieve the object at, without any credentials
119func (s *JoyentStorage) URL(name string) (string, error) {
120 path := fmt.Sprintf("/%s/stor/%s/%s", s.ecfg.mantaUser(), s.containerName, name)
121 return s.manta.SignURL(path, time.Now().AddDate(10, 0, 0))
122}
123
124func (s *JoyentStorage) Get(name string) (io.ReadCloser, error) {
125 b, err := s.manta.GetObject(s.containerName, name)
126 if err != nil {
127 return nil, err
128 }
129 r := byteCloser{bytes.NewReader(b)}
130 return r, nil
131}
132
133func (s *JoyentStorage) Put(name string, r io.Reader, length int64) error {
134 if err := s.CreateContainer(); err != nil {
135 return fmt.Errorf("cannot make Manta control container: %v", err)
136 }
137 err := s.manta.PutObject(s.containerName, name, r)
138 if err != nil {
139 return fmt.Errorf("cannot write file %q to control container %q: %v", name, s.containerName, err)
140 }
141 return nil
142}
143
144func (s *JoyentStorage) Remove(name string) error {
145 err := s.manta.DeleteObject(s.containerName, name)
146 if err != nil {
147 return err
148 }
149 return nil
150}
151
152func (s *JoyentStorage) RemoveAll() error {
153 names, err := storage.List(s, "")
154 if err != nil {
155 return err
156 }
157 // Remove all the objects in parallel so that we incur less round-trips.
158 // If we're in danger of having hundreds of objects,
159 // we'll want to change this to limit the number
160 // of concurrent operations.
161 var wg sync.WaitGroup
162 wg.Add(len(names))
163 errc := make(chan error, len(names))
164 for _, name := range names {
165 name := name
166 go func() {
167 defer wg.Done()
168 if err := s.Remove(name); err != nil {
169 errc <- err
170 }
171 }()
172 }
173 wg.Wait()
174 select {
175 case err := <-errc:
176 return fmt.Errorf("cannot delete all provider state: %v", err)
177 default:
178 }
179
180 s.Lock()
181 defer s.Unlock()
182 // Even DeleteContainer fails, it won't harm if we try again - the
183 // operation might have succeeded even if we get an error.
184 s.madeContainer = false
185 if err = s.manta.DeleteDirectory(s.containerName); err != nil {
186 return err
187 }
188 return nil
189}
190
191func (s *JoyentStorage) DefaultConsistencyStrategy() utils.AttemptStrategy {
48 return utils.AttemptStrategy{}192 return utils.AttemptStrategy{}
49}193}
50194
51func (s *environStorage) ShouldRetry(err error) bool {195func (s *JoyentStorage) ShouldRetry(err error) bool {
52 return false196 return false
53}197}
54198
=== added file 'provider/joyent/storage_test.go'
--- provider/joyent/storage_test.go 1970-01-01 00:00:00 +0000
+++ provider/joyent/storage_test.go 2014-02-27 18:08:22 +0000
@@ -0,0 +1,189 @@
1// Copyright 2013 Joyent Inc.
2// Licensed under the AGPLv3, see LICENCE file for details.
3
4package joyent_test
5
6import (
7 "fmt"
8 "io/ioutil"
9 "math/rand"
10 "net/http"
11 "net/url"
12 "strings"
13
14 gc "launchpad.net/gocheck"
15 jp "launchpad.net/juju-core/provider/joyent"
16 jc "launchpad.net/juju-core/testing/checkers"
17
18 "launchpad.net/gojoyent/errors"
19)
20
21type storageSuite struct {
22 providerSuite
23 localMantaService
24}
25
26const (
27 storageName = "testStorage"
28 fileName = "testFile"
29 fileBlobContent = "Juju Joyent Provider Storage - Test"
30)
31
32var _ = gc.Suite(&storageSuite{})
33
34func (s *storageSuite) SetUpSuite(c *gc.C) {
35 s.providerSuite.SetUpSuite(c)
36 s.localMantaService.Start(c)
37}
38
39func (s *storageSuite) TearDownSuite(c *gc.C) {
40 s.localMantaService.Stop()
41 s.providerSuite.TearDownSuite(c)
42}
43
44// s.makeStorage creates a Manta storage object for the running test.
45func (s *storageSuite) assertStorage(name string, c *gc.C) *jp.JoyentStorage {
46 env := s.makeEnviron("localhost", s.localMantaService.Server.URL)
47 env.SetName(name)
48 storage := jp.NewStorage(env).(*jp.JoyentStorage)
49 c.Assert(storage, gc.NotNil)
50 return storage
51}
52
53func (s *storageSuite) assertContainer(storage *jp.JoyentStorage, c *gc.C) {
54 err := storage.CreateContainer()
55 c.Assert(err, gc.IsNil)
56}
57
58func (s *storageSuite) assertFile(storage *jp.JoyentStorage, c *gc.C) {
59 err := storage.Put(fileName, strings.NewReader(fileBlobContent), int64(len(fileBlobContent)))
60 c.Assert(err, gc.IsNil)
61}
62
63// makeRandomBytes returns an array of arbitrary byte values.
64func makeRandomBytes(length int) []byte {
65 data := make([]byte, length)
66 for index := range data {
67 data[index] = byte(rand.Intn(256))
68 }
69 return data
70}
71
72func makeResponse(content string, status int) *http.Response {
73 return &http.Response{
74 Status: fmt.Sprintf("%d", status),
75 StatusCode: status,
76 Body: ioutil.NopCloser(strings.NewReader(content)),
77 }
78}
79
80func (s *storageSuite) TestList(c *gc.C) {
81 mantaStorage := s.assertStorage(storageName, c)
82 s.assertContainer(mantaStorage, c)
83 s.assertFile(mantaStorage, c)
84
85 names, err := mantaStorage.List("prefix")
86 c.Assert(err, gc.IsNil)
87 c.Check(names, gc.DeepEquals, []string{fileName})
88}
89
90func (s *storageSuite) TestGet(c *gc.C) {
91 mantaStorage := s.assertStorage(storageName, c)
92 s.assertFile(mantaStorage, c)
93
94 reader, err := mantaStorage.Get(fileName)
95 c.Assert(err, gc.IsNil)
96 c.Assert(reader, gc.NotNil)
97 defer reader.Close()
98
99 data, err := ioutil.ReadAll(reader)
100 c.Assert(err, gc.IsNil)
101 c.Check(string(data), gc.Equals, fileBlobContent)
102}
103
104func (s *storageSuite) TestGetFileNotExists(c *gc.C) {
105 mantaStorage := s.assertStorage(storageName, c)
106
107 _, err := mantaStorage.Get("noFile")
108 c.Assert(err, gc.NotNil)
109 c.Assert(err, jc.Satisfies, errors.IsResourceNotFound)
110}
111
112func (s *storageSuite) TestPut(c *gc.C) {
113 mantaStorage := s.assertStorage(storageName, c)
114
115 s.assertFile(mantaStorage, c)
116}
117
118func (s *storageSuite) TestRemove(c *gc.C) {
119 mantaStorage := s.assertStorage(storageName, c)
120 s.assertFile(mantaStorage, c)
121
122 err := mantaStorage.Remove(fileName)
123 c.Assert(err, gc.IsNil)
124}
125
126func (s *storageSuite) TestRemoveFileNotExists(c *gc.C) {
127 mantaStorage := s.assertStorage(storageName, c)
128
129 err := mantaStorage.Remove("nofile")
130 c.Assert(err, gc.NotNil)
131 c.Assert(err, jc.Satisfies, errors.IsResourceNotFound)
132}
133
134func (s *storageSuite) TestRemoveAll(c *gc.C) {
135 mantaStorage := s.assertStorage(storageName, c)
136
137 err := mantaStorage.RemoveAll()
138 c.Assert(err, gc.IsNil)
139}
140
141func (s *storageSuite) TestURL(c *gc.C) {
142 mantaStorage := s.assertStorage(storageName, c)
143
144 URL, err := mantaStorage.URL(fileName)
145 c.Assert(err, gc.IsNil)
146 parsedURL, err := url.Parse(URL)
147 c.Assert(err, gc.IsNil)
148 c.Check(parsedURL.Host, gc.Matches, mantaStorage.GetMantaUrl()[strings.LastIndex(mantaStorage.GetMantaUrl(), "/")+1:])
149 c.Check(parsedURL.Path, gc.Matches, fmt.Sprintf("/%s/stor/%s/%s", mantaStorage.GetMantaUser(), mantaStorage.GetContainerName(), fileName))
150}
151
152func (s *storageSuite) TestCreateContainer(c *gc.C) {
153 mantaStorage := s.assertStorage(storageName, c)
154
155 s.assertContainer(mantaStorage, c)
156}
157
158func (s *storageSuite) TestCreateContainerAlreadyExists(c *gc.C) {
159 mantaStorage := s.assertStorage(storageName, c)
160
161 s.assertContainer(mantaStorage, c)
162 s.assertContainer(mantaStorage, c)
163}
164
165func (s *storageSuite) TestDeleteContainer(c *gc.C) {
166 mantaStorage := s.assertStorage(storageName, c)
167 s.assertContainer(mantaStorage, c)
168
169 err := mantaStorage.DeleteContainer(mantaStorage.GetContainerName())
170 c.Assert(err, gc.IsNil)
171}
172
173func (s *storageSuite) TestDeleteContainerNotEmpty(c *gc.C) {
174 mantaStorage := s.assertStorage(storageName, c)
175 s.assertContainer(mantaStorage, c)
176 s.assertFile(mantaStorage, c)
177
178 err := mantaStorage.DeleteContainer(mantaStorage.GetContainerName())
179 c.Assert(err, gc.NotNil)
180 c.Assert(err, jc.Satisfies, errors.IsBadRequest)
181}
182
183func (s *storageSuite) TestDeleteContainerNotExists(c *gc.C) {
184 mantaStorage := s.assertStorage(storageName, c)
185
186 err := mantaStorage.DeleteContainer("noContainer")
187 c.Assert(err, gc.NotNil)
188 c.Assert(err, jc.Satisfies, errors.IsResourceNotFound)
189}

Subscribers

People subscribed via source and target branches

to status/vote changes: