func (suite *StateSuite) TestLoadStateFromURLReadsStateFile(c *C) { storage, cleanup := makeDummyStorage(c) defer cleanup() state := suite.setupSavedState(c, storage) url, err := storage.URL(environs.StateFile) c.Assert(err, IsNil) storedState, err := environs.LoadStateFromURL(url) c.Assert(err, IsNil) c.Check(*storedState, DeepEquals, state) }
// Run initializes state for an environment. func (c *BootstrapCommand) Run(_ *cmd.Context) error { if err := c.Conf.read("bootstrap"); err != nil { return err } cfg, err := config.New(c.EnvConfig) if err != nil { return err } // There is no entity that's created at init time. c.Conf.StateInfo.Tag = "" st, err := state.Initialize(c.Conf.StateInfo, cfg, state.DefaultDialOpts()) if err != nil { return err } defer st.Close() if err := environs.BootstrapUsers(st, cfg, c.Conf.OldPassword); err != nil { return err } // TODO(fwereade): we need to be able to customize machine jobs, // not just hardcode these values; in particular, JobHostUnits // on a machine, like this one, that is running JobManageEnviron // (not to mention the actual state server itself...) will allow // a malicious or compromised unit to trivially access to the // user's environment credentials. However, given that this point // is currently moot (see Upgrader in this package), the pseudo- // local provider mode (in which everything is deployed with // `--to 0`) offers enough value to enough people that // JobHostUnits is currently always enabled. This will one day // have to change, but it's strictly less important than fixing // Upgrader, and it's a capability we'll always want to have // available for the aforementioned use case. jobs := []state.MachineJob{ state.JobManageEnviron, state.JobManageState, state.JobHostUnits, } data, err := ioutil.ReadFile(providerStateURLFile) if err != nil { return fmt.Errorf("cannot read provider-state-url file: %v", err) } stateInfoURL := strings.Split(string(data), "\n")[0] bsState, err := environs.LoadStateFromURL(stateInfoURL) if err != nil { return fmt.Errorf("cannot load state from URL %q (read from %q): %v", stateInfoURL, providerStateURLFile, err) } instId := bsState.StateInstances[0] var characteristics instance.HardwareCharacteristics if len(bsState.Characteristics) > 0 { characteristics = bsState.Characteristics[0] } return environs.ConfigureBootstrapMachine(st, c.Constraints, c.Conf.DataDir, jobs, instance.Id(instId), characteristics) }