github.com/rogpeppe/juju@v0.0.0-20140613142852-6337964b789e/cmd/juju/common.go (about) 1 // Copyright 2014 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package main 5 6 import ( 7 "fmt" 8 9 "github.com/juju/charm" 10 "github.com/juju/cmd" 11 "github.com/juju/errors" 12 13 "github.com/juju/juju/environs" 14 "github.com/juju/juju/environs/config" 15 "github.com/juju/juju/environs/configstore" 16 "github.com/juju/juju/state/api" 17 ) 18 19 // destroyPreparedEnviron destroys the environment and logs an error if it fails. 20 func destroyPreparedEnviron(ctx *cmd.Context, env environs.Environ, store configstore.Storage, err *error, action string) { 21 if *err == nil { 22 return 23 } 24 ctx.Infof("%s failed, destroying environment", action) 25 if err := environs.Destroy(env, store); err != nil { 26 logger.Errorf("%s failed, and the environment could not be destroyed: %v", action, err) 27 } 28 } 29 30 // environFromName loads an existing environment or prepares a new one. 31 func environFromName( 32 ctx *cmd.Context, envName string, resultErr *error, action string) (environs.Environ, func(), error) { 33 34 store, err := configstore.Default() 35 if err != nil { 36 return nil, nil, err 37 } 38 var existing bool 39 if environInfo, err := store.ReadInfo(envName); !errors.IsNotFound(err) { 40 existing = true 41 logger.Warningf("ignoring environments.yaml: using bootstrap config in %s", environInfo.Location()) 42 } 43 environ, err := environs.PrepareFromName(envName, ctx, store) 44 if err != nil { 45 return nil, nil, err 46 } 47 cleanup := func() { 48 if !existing { 49 destroyPreparedEnviron(ctx, environ, store, resultErr, action) 50 } 51 } 52 return environ, cleanup, nil 53 } 54 55 // resolveCharmURL returns a resolved charm URL, given a charm location string. 56 // If the series is not resolved, the environment default-series is used, or if 57 // not set, the series is resolved with the state server. 58 func resolveCharmURL(url string, client *api.Client, conf *config.Config) (*charm.URL, error) { 59 ref, series, err := charm.ParseReference(url) 60 if err != nil { 61 return nil, err 62 } 63 // If series is not set, use configured default series 64 if series == "" { 65 if defaultSeries, ok := conf.DefaultSeries(); ok { 66 series = defaultSeries 67 } 68 } 69 // Otherwise, look up the best supported series for this charm 70 if series == "" { 71 if ref.Schema == "local" { 72 possibleUrl := &charm.URL{Reference: ref, Series: "precise"} 73 logger.Errorf(`The series is not specified in the environment (default-series) or with the charm. Did you mean: 74 %s`, possibleUrl.String()) 75 return nil, fmt.Errorf("cannot resolve series for charm: %q", ref) 76 } 77 return client.ResolveCharm(ref) 78 } 79 return &charm.URL{Reference: ref, Series: series}, nil 80 }