Skip to content

Commit

Permalink
Initial refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
wallyworld committed Mar 21, 2014
1 parent 96f9172 commit 8050c20
Show file tree
Hide file tree
Showing 39 changed files with 220 additions and 169 deletions.
7 changes: 0 additions & 7 deletions cmd/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import (
"fmt"
"io"
"io/ioutil"
"net/http"
"os"
"os/signal"
"path/filepath"
Expand Down Expand Up @@ -38,12 +37,6 @@ func NewRcPassthroughError(code int) error {
return &rcPassthroughError{code}
}

func init() {
// Don't replace the default transport as other init blocks
// register protocols.
http.DefaultTransport.(*http.Transport).DisableKeepAlives = true
}

// ErrSilent can be returned from Run to signal that Main should exit with
// code 1 without producing error output.
var ErrSilent = errors.New("cmd: error out silently")
Expand Down
7 changes: 5 additions & 2 deletions cmd/cmd_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,18 @@ import (

"launchpad.net/juju-core/cmd"
"launchpad.net/juju-core/testing"
"launchpad.net/juju-core/utils"
)

type CmdSuite struct{}

var _ = gc.Suite(&CmdSuite{})

func (s *CmdSuite) TestHttpTransport(c *gc.C) {
transport := http.DefaultTransport.(*http.Transport)
c.Assert(transport.DisableKeepAlives, jc.IsTrue)
client := utils.GetValidatingHTTPClient()
c.Assert(client.Transport.(*http.Transport).DisableKeepAlives, jc.IsTrue)
client = utils.GetNonValidatingHTTPClient()
c.Assert(client.Transport.(*http.Transport).DisableKeepAlives, jc.IsTrue)
}

func (s *CmdSuite) TestContext(c *gc.C) {
Expand Down
7 changes: 6 additions & 1 deletion cmd/jujud/bootstrap.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"launchpad.net/juju-core/instance"
"launchpad.net/juju-core/state"
"launchpad.net/juju-core/state/api/params"
"launchpad.net/juju-core/utils"
)

// Cloud-init write the URL to be used to load the bootstrap state into this file.
Expand Down Expand Up @@ -68,7 +69,11 @@ func (c *BootstrapCommand) Run(_ *cmd.Context) error {
return err
}
stateInfoURL := strings.Split(string(data), "\n")[0]
bsState, err := bootstrap.LoadStateFromURL(stateInfoURL, !envCfg.SSLHostnameVerification())
verify := utils.VerifySSLHostnames
if !envCfg.SSLHostnameVerification() {
verify = utils.NoVerifySSLHostnames
}
bsState, err := bootstrap.LoadStateFromURL(stateInfoURL, verify)
if err != nil {
return fmt.Errorf("cannot load state from URL %q (read from %q): %v", stateInfoURL, providerStateURLFile, err)
}
Expand Down
3 changes: 2 additions & 1 deletion cmd/plugins/juju-metadata/toolsmetadata.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
envtools "launchpad.net/juju-core/environs/tools"
"launchpad.net/juju-core/juju/osenv"
coretools "launchpad.net/juju-core/tools"
"launchpad.net/juju-core/utils"
"launchpad.net/juju-core/version"
)

Expand Down Expand Up @@ -62,7 +63,7 @@ func (c *ToolsMetadataCommand) Run(context *cmd.Context) error {
if err != nil {
return err
}
sourceDataSource := simplestreams.NewURLDataSource("local source", source, simplestreams.VerifySSLHostnames)
sourceDataSource := simplestreams.NewURLDataSource("local source", source, utils.VerifySSLHostnames)
toolsList, err = envtools.FindToolsForCloud(
[]simplestreams.DataSource{sourceDataSource}, simplestreams.CloudSpec{},
version.Current.Major, minorVersion, coretools.Filter{})
Expand Down
3 changes: 2 additions & 1 deletion cmd/plugins/juju-metadata/validateimagemetadata.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
"launchpad.net/juju-core/environs/configstore"
"launchpad.net/juju-core/environs/imagemetadata"
"launchpad.net/juju-core/environs/simplestreams"
"launchpad.net/juju-core/utils"
)

// ValidateImageMetadataCommand
Expand Down Expand Up @@ -184,7 +185,7 @@ func (c *ValidateImageMetadataCommand) Run(context *cmd.Context) error {
}
params.Sources = []simplestreams.DataSource{
simplestreams.NewURLDataSource(
"local metadata directory", "file://"+dir, simplestreams.VerifySSLHostnames),
"local metadata directory", "file://"+dir, utils.VerifySSLHostnames),
}
}
params.Stream = c.stream
Expand Down
3 changes: 2 additions & 1 deletion cmd/plugins/juju-metadata/validatetoolsmetadata.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
"launchpad.net/juju-core/environs/simplestreams"
"launchpad.net/juju-core/environs/tools"
"launchpad.net/juju-core/juju/arch"
"launchpad.net/juju-core/utils"
"launchpad.net/juju-core/version"
)

Expand Down Expand Up @@ -199,7 +200,7 @@ func (c *ValidateToolsMetadataCommand) Run(context *cmd.Context) error {
return err
}
params.Sources = []simplestreams.DataSource{simplestreams.NewURLDataSource(
"local metadata directory", toolsURL, simplestreams.VerifySSLHostnames),
"local metadata directory", toolsURL, utils.VerifySSLHostnames),
}
}

Expand Down
21 changes: 9 additions & 12 deletions downloader/downloader.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,19 +26,19 @@ type Status struct {

// Download can download a file from the network.
type Download struct {
tomb tomb.Tomb
done chan Status
disableSSLHostnameVerification bool
tomb tomb.Tomb
done chan Status
hostnameVerification utils.SSLHostnameVerification
}

// New returns a new Download instance downloading from the given URL
// to the given directory. If dir is empty, it defaults to
// os.TempDir(). If disableSSLHostnameVerification is true then a non-
// validating http client will be used.
func New(url, dir string, disableSSLHostnameVerification bool) *Download {
func New(url, dir string, hostnameVerification utils.SSLHostnameVerification) *Download {
d := &Download{
done: make(chan Status),
disableSSLHostnameVerification: disableSSLHostnameVerification,
done: make(chan Status),
hostnameVerification: hostnameVerification,
}
go d.run(url, dir)
return d
Expand All @@ -62,7 +62,7 @@ func (d *Download) run(url, dir string) {
// TODO(dimitern) 2013-10-03 bug #1234715
// Add a testing HTTPS storage to verify the
// disableSSLHostnameVerification behavior here.
file, err := download(url, dir, d.disableSSLHostnameVerification)
file, err := download(url, dir, d.hostnameVerification)
if err != nil {
err = fmt.Errorf("cannot download %q: %v", url, err)
}
Expand All @@ -77,7 +77,7 @@ func (d *Download) run(url, dir string) {
}
}

func download(url, dir string, disableSSLHostnameVerification bool) (file *os.File, err error) {
func download(url, dir string, hostnameVerification utils.SSLHostnameVerification) (file *os.File, err error) {
if dir == "" {
dir = os.TempDir()
}
Expand All @@ -91,10 +91,7 @@ func download(url, dir string, disableSSLHostnameVerification bool) (file *os.Fi
}
}()
// TODO(rog) make the download operation interruptible.
client := http.DefaultClient
if disableSSLHostnameVerification {
client = utils.GetNonValidatingHTTPClient()
}
client := utils.GetHTTPClient(hostnameVerification)
resp, err := client.Get(url)
if err != nil {
return nil, err
Expand Down
13 changes: 7 additions & 6 deletions downloader/downloader_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"launchpad.net/juju-core/downloader"
"launchpad.net/juju-core/testing"
"launchpad.net/juju-core/testing/testbase"
"launchpad.net/juju-core/utils"
)

type suite struct {
Expand Down Expand Up @@ -48,10 +49,10 @@ func Test(t *stdtesting.T) {
gc.TestingT(t)
}

func (s *suite) testDownload(c *gc.C, disableSSLHostnameVerification bool) {
func (s *suite) testDownload(c *gc.C, hostnameVerification utils.SSLHostnameVerification) {
tmp := c.MkDir()
testing.Server.Response(200, nil, []byte("archive"))
d := downloader.New(s.URL("/archive.tgz"), tmp, disableSSLHostnameVerification)
d := downloader.New(s.URL("/archive.tgz"), tmp, hostnameVerification)
status := <-d.Done()
c.Assert(status.Err, gc.IsNil)
c.Assert(status.File, gc.NotNil)
Expand All @@ -64,24 +65,24 @@ func (s *suite) testDownload(c *gc.C, disableSSLHostnameVerification bool) {
}

func (s *suite) TestDownloadWithoutDisablingSSLHostnameVerification(c *gc.C) {
s.testDownload(c, false)
s.testDownload(c, utils.VerifySSLHostnames)
}

func (s *suite) TestDownloadWithDisablingSSLHostnameVerification(c *gc.C) {
s.testDownload(c, true)
s.testDownload(c, utils.NoVerifySSLHostnames)
}

func (s *suite) TestDownloadError(c *gc.C) {
testing.Server.Response(404, nil, nil)
d := downloader.New(s.URL("/archive.tgz"), c.MkDir(), false)
d := downloader.New(s.URL("/archive.tgz"), c.MkDir(), utils.VerifySSLHostnames)
status := <-d.Done()
c.Assert(status.File, gc.IsNil)
c.Assert(status.Err, gc.ErrorMatches, `cannot download ".*": bad http response: 404 Not Found`)
}

func (s *suite) TestStopDownload(c *gc.C) {
tmp := c.MkDir()
d := downloader.New(s.URL("/x.tgz"), tmp, false)
d := downloader.New(s.URL("/x.tgz"), tmp, utils.VerifySSLHostnames)
d.Stop()
select {
case status := <-d.Done():
Expand Down
24 changes: 10 additions & 14 deletions environs/bootstrap/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,24 +39,24 @@ type BootstrapState struct {

// putState writes the given data to the state file on the given storage.
// The file's name is as defined in StateFile.
func putState(storage storage.StorageWriter, data []byte) error {
logger.Debugf("putting %q to bootstrap storage %T", StateFile, storage)
return storage.Put(StateFile, bytes.NewBuffer(data), int64(len(data)))
func putState(stor storage.StorageWriter, data []byte) error {
logger.Debugf("putting %q to bootstrap storage %T", StateFile, stor)
return stor.Put(StateFile, bytes.NewBuffer(data), int64(len(data)))
}

// CreateStateFile creates an empty state file on the given storage, and
// returns its URL.
func CreateStateFile(storage storage.Storage) (string, error) {
err := putState(storage, []byte{})
func CreateStateFile(stor storage.Storage) (string, error) {
err := putState(stor, []byte{})
if err != nil {
return "", fmt.Errorf("cannot create initial state file: %v", err)
}
return storage.URL(StateFile)
return stor.URL(StateFile)
}

// DeleteStateFile deletes the state file on the given storage.
func DeleteStateFile(storage storage.Storage) error {
return storage.Remove(StateFile)
func DeleteStateFile(stor storage.Storage) error {
return stor.Remove(StateFile)
}

// SaveState writes the given state to the given storage.
Expand All @@ -69,13 +69,9 @@ func SaveState(storage storage.StorageWriter, state *BootstrapState) error {
}

// LoadStateFromURL reads state from the given URL.
func LoadStateFromURL(url string, disableSSLHostnameVerification bool) (*BootstrapState, error) {
func LoadStateFromURL(url string, hostnameVerification utils.SSLHostnameVerification) (*BootstrapState, error) {
logger.Debugf("loading %q from %q", StateFile, url)
client := http.DefaultClient
if disableSSLHostnameVerification {
logger.Infof("hostname SSL verification disabled")
client = utils.GetNonValidatingHTTPClient()
}
client := utils.GetHTTPClient(hostnameVerification)
resp, err := client.Get(url)
if err != nil {
return nil, err
Expand Down
9 changes: 5 additions & 4 deletions environs/bootstrap/state_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
envtesting "launchpad.net/juju-core/environs/testing"
"launchpad.net/juju-core/instance"
"launchpad.net/juju-core/testing/testbase"
"launchpad.net/juju-core/utils"
)

type StateSuite struct {
Expand Down Expand Up @@ -126,9 +127,9 @@ func (suite *StateSuite) TestLoadStateReadsStateFile(c *gc.C) {
}

func (suite *StateSuite) TestLoadStateFromURLReadsStateFile(c *gc.C) {
storage, dataDir := suite.newStorageWithDataDir(c)
stor, dataDir := suite.newStorageWithDataDir(c)
state := suite.setUpSavedState(c, dataDir)
url, err := storage.URL(bootstrap.StateFile)
url, err := stor.URL(bootstrap.StateFile)
c.Assert(err, gc.IsNil)
storedState, err := bootstrap.LoadStateFromURL(url, false)
c.Assert(err, gc.IsNil)
Expand All @@ -138,7 +139,7 @@ func (suite *StateSuite) TestLoadStateFromURLReadsStateFile(c *gc.C) {
func (suite *StateSuite) TestLoadStateFromURLBadCert(c *gc.C) {
baseURL, _ := suite.testingHTTPSServer(c)
url := baseURL + "/" + bootstrap.StateFile
storedState, err := bootstrap.LoadStateFromURL(url, false)
storedState, err := bootstrap.LoadStateFromURL(url, utils.VerifySSLHostnames)
c.Assert(err, gc.ErrorMatches, ".*/provider-state:.* certificate signed by unknown authority")
c.Assert(storedState, gc.IsNil)
}
Expand All @@ -147,7 +148,7 @@ func (suite *StateSuite) TestLoadStateFromURLBadCertPermitted(c *gc.C) {
baseURL, dataDir := suite.testingHTTPSServer(c)
state := suite.setUpSavedState(c, dataDir)
url := baseURL + "/" + bootstrap.StateFile
storedState, err := bootstrap.LoadStateFromURL(url, true)
storedState, err := bootstrap.LoadStateFromURL(url, utils.NoVerifySSLHostnames)
c.Assert(err, gc.IsNil)
c.Check(*storedState, gc.DeepEquals, state)
}
Expand Down
4 changes: 2 additions & 2 deletions environs/httpstorage/storage.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ type localStorage struct {
func Client(addr string) storage.Storage {
return &localStorage{
addr: addr,
client: http.DefaultClient,
client: utils.GetValidatingHTTPClient(),
}
}

Expand Down Expand Up @@ -146,7 +146,7 @@ func (s *localStorage) URL(name string) (string, error) {

// modURL returns a URL that can be used to modify the given storage file.
func (s *localStorage) modURL(name string) (string, error) {
if s.client == http.DefaultClient {
if s.authkey == "" {
return s.URL(name)
}
s.httpsBaseURLOnce.Do(func() {
Expand Down
13 changes: 7 additions & 6 deletions environs/imagemetadata/simplestreams_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"launchpad.net/juju-core/environs/jujutest"
"launchpad.net/juju-core/environs/simplestreams"
sstesting "launchpad.net/juju-core/environs/simplestreams/testing"
"launchpad.net/juju-core/utils"
)

var live = flag.Bool("live", false, "Include live simplestreams tests")
Expand Down Expand Up @@ -67,7 +68,7 @@ func registerSimpleStreamsTests() {
gc.Suite(&simplestreamsSuite{
LocalLiveSimplestreamsSuite: sstesting.LocalLiveSimplestreamsSuite{
Source: simplestreams.NewURLDataSource(
"test roundtripper", "test:", simplestreams.VerifySSLHostnames),
"test roundtripper", "test:", utils.VerifySSLHostnames),
RequireSigned: false,
DataType: imagemetadata.ImageIds,
ValidConstraint: imagemetadata.NewImageConstraint(simplestreams.LookupParams{
Expand All @@ -85,7 +86,7 @@ func registerSimpleStreamsTests() {

func registerLiveSimpleStreamsTests(baseURL string, validImageConstraint simplestreams.LookupConstraint, requireSigned bool) {
gc.Suite(&sstesting.LocalLiveSimplestreamsSuite{
Source: simplestreams.NewURLDataSource("test", baseURL, simplestreams.VerifySSLHostnames),
Source: simplestreams.NewURLDataSource("test", baseURL, utils.VerifySSLHostnames),
RequireSigned: requireSigned,
DataType: imagemetadata.ImageIds,
ValidConstraint: validImageConstraint,
Expand Down Expand Up @@ -267,7 +268,7 @@ func (s *simplestreamsSuite) TestFetch(c *gc.C) {
Arches: t.arches,
})
// Add invalid datasource and check later that resolveInfo is correct.
invalidSource := simplestreams.NewURLDataSource("invalid", "file://invalid", simplestreams.VerifySSLHostnames)
invalidSource := simplestreams.NewURLDataSource("invalid", "file://invalid", utils.VerifySSLHostnames)
images, resolveInfo, err := imagemetadata.Fetch(
[]simplestreams.DataSource{invalidSource, s.Source}, simplestreams.DefaultIndexPath,
imageConstraint, s.RequireSigned)
Expand Down Expand Up @@ -336,7 +337,7 @@ var testRoundTripper *jujutest.ProxyRoundTripper

func init() {
testRoundTripper = &jujutest.ProxyRoundTripper{}
simplestreams.RegisterProtocol("signedtest", testRoundTripper)
testRoundTripper.RegisterForScheme("signedtest")
}

func (s *signedSuite) SetUpSuite(c *gc.C) {
Expand Down Expand Up @@ -375,7 +376,7 @@ func (s *signedSuite) TearDownSuite(c *gc.C) {
}

func (s *signedSuite) TestSignedImageMetadata(c *gc.C) {
signedSource := simplestreams.NewURLDataSource("test", "signedtest://host/signed", simplestreams.VerifySSLHostnames)
signedSource := simplestreams.NewURLDataSource("test", "signedtest://host/signed", utils.VerifySSLHostnames)
imageConstraint := imagemetadata.NewImageConstraint(simplestreams.LookupParams{
CloudSpec: simplestreams.CloudSpec{"us-east-1", "https://ec2.us-east-1.amazonaws.com"},
Series: []string{"precise"},
Expand All @@ -395,7 +396,7 @@ func (s *signedSuite) TestSignedImageMetadata(c *gc.C) {
}

func (s *signedSuite) TestSignedImageMetadataInvalidSignature(c *gc.C) {
signedSource := simplestreams.NewURLDataSource("test", "signedtest://host/signed", simplestreams.VerifySSLHostnames)
signedSource := simplestreams.NewURLDataSource("test", "signedtest://host/signed", utils.VerifySSLHostnames)
imageConstraint := imagemetadata.NewImageConstraint(simplestreams.LookupParams{
CloudSpec: simplestreams.CloudSpec{"us-east-1", "https://ec2.us-east-1.amazonaws.com"},
Series: []string{"precise"},
Expand Down
Loading

0 comments on commit 8050c20

Please sign in to comment.