// deployBundle deploys the given bundle data using the given API client and // charm store client. The deployment is not transactional, and its progress is // notified using the given deployment logger. func deployBundle(data *charm.BundleData, client *api.Client, csclient *csClient, repoPath string, conf *config.Config, log deploymentLogger) error { if err := data.Verify(func(s string) error { _, err := constraints.Parse(s) return err }); err != nil { return errors.Annotate(err, "cannot deploy bundle") } // Retrieve bundle changes. changes := bundlechanges.FromData(data) numChanges := len(changes) // Initialize the unit status. status, err := client.Status(nil) if err != nil { return errors.Annotate(err, "cannot get environment status") } unitStatus := make(map[string]string, numChanges) for _, serviceData := range status.Services { for unit, unitData := range serviceData.Units { unitStatus[unit] = unitData.Machine } } // Instantiate a watcher used to follow the deployment progress. watcher, err := client.WatchAll() if err != nil { return errors.Annotate(err, "cannot watch environment") } defer watcher.Stop() // Instantiate the bundle handler. h := &bundleHandler{ changes: changes, results: make(map[string]string, numChanges), client: client, csclient: csclient, repoPath: repoPath, conf: conf, log: log, data: data, unitStatus: unitStatus, ignoredMachines: make(map[string]bool, len(data.Services)), ignoredUnits: make(map[string]bool, len(data.Services)), watcher: watcher, } // Deploy the bundle. for _, change := range changes { switch change := change.(type) { case *bundlechanges.AddCharmChange: err = h.addCharm(change.Id(), change.Params) case *bundlechanges.AddMachineChange: err = h.addMachine(change.Id(), change.Params) case *bundlechanges.AddRelationChange: err = h.addRelation(change.Id(), change.Params) case *bundlechanges.AddServiceChange: err = h.addService(change.Id(), change.Params) case *bundlechanges.AddUnitChange: err = h.addUnit(change.Id(), change.Params) case *bundlechanges.SetAnnotationsChange: err = h.setAnnotations(change.Id(), change.Params) default: return errors.Errorf("unknown change type: %T", change) } if err != nil { return errors.Annotate(err, "cannot deploy bundle") } } return nil }