// Adds a bundletype to the system, by extracting the required template from the charm itself func (self *System) AddJxaasCharm(apiclient *juju.Client, key string, charmName string) error { charmInfo, err := apiclient.CharmInfo(charmName) if err != nil { log.Warn("Error reading charm: %v", charmName, err) return err } if charmInfo == nil { return fmt.Errorf("Unable to find charm: %v", charmName) } url := charmInfo.URL if url == "" { return fmt.Errorf("Unable to find charm url: %v", charmName) } contents, err := apiclient.DownloadCharm(charmName) if err != nil { log.Warn("Error reading charm", err) return err } charmFile := NewCharmReader(contents) config, err := charmFile.read("jxaas.yaml") if err != nil { log.Warn("Error reading jxaas.yaml from charm: %v", charmName, err) return err } if config == nil { return fmt.Errorf("Could not find jxaas.yaml in charm: %v", charmName) } // log.Info("Jxaas config: %v", string(config)) bundleTemplate, err := bundle.NewBundleTemplate(sources.NewArrayToByteSource(config)) if err != nil { return err } bundleType, err := bundletype.NewGenericBundleType(key, bundleTemplate) if err != nil { return err } self.BundleTypes[key] = bundleType return nil }
func (self *ServiceConfig) deploy(jujuServiceId string, apiclient *juju.Client) (*DeployServiceInfo, error) { serviceInfo := &DeployServiceInfo{} jujuService, err := apiclient.FindService(jujuServiceId) if err != nil { return nil, err } charmUrl := self.Charm charmInfo, err := apiclient.CharmInfo(charmUrl) if err != nil { log.Warn("Error reading charm: %v", charmUrl, err) } if charmInfo == nil { log.Warn("Unable to find charm: %v", charmUrl) } charmUrl = charmInfo.URL if jujuService == nil { // Create new service numUnits := self.NumberUnits if charmInfo.Meta.Subordinate { numUnits = -1 } configYaml, err := makeConfigYaml(jujuServiceId, self.Options) if err != nil { return nil, err } log.Debug("Deploying with YAML: %v", configYaml) err = apiclient.ServiceDeploy( charmUrl, jujuServiceId, numUnits, configYaml) if err != nil { return nil, err } // for retry := 0; retry < 5; retry++ { // status, err := apiclient.GetStatus(jujuServiceId) // if err != nil { // return err // } // if status != nil { // break // } // log.Info("Service was not yet visible; waiting") // time.Sleep(1 * time.Second) // } } else { existingInstance := model.MapToInstance(jujuServiceId, nil, jujuService) existingServiceOptions := existingInstance.Options mergedServiceOptions := map[string]string{} { for key, value := range existingServiceOptions { mergedServiceOptions[key] = value } for key, value := range self.Options { mergedServiceOptions[key] = value } } if !reflect.DeepEqual(existingServiceOptions, mergedServiceOptions) { err = apiclient.SetConfig(jujuServiceId, mergedServiceOptions) if err != nil { return nil, err } } else { log.Debug("Configuration unchanged; won't reconfigure") } } if !charmInfo.Meta.Subordinate { // && self.Exposed != nil { status, err := apiclient.GetServiceStatus(jujuServiceId) if err != nil { return nil, err } if status == nil { return nil, fmt.Errorf("Service not found: %v", jujuServiceId) } serviceInfo.Status = status if status.Exposed != self.Exposed { err = apiclient.SetExposed(jujuServiceId, self.Exposed) if err != nil { log.Warn("Error setting service to Exposed=%v", self.Exposed, err) return nil, err } } actualUnits := len(status.Units) wantUnits := self.NumberUnits if actualUnits != wantUnits { if actualUnits < wantUnits { _, err = apiclient.AddServiceUnits(jujuServiceId, wantUnits-actualUnits) if err != nil { log.Warn("Error adding units", err) } } else { keys := []string{} for key, _ := range status.Units { keys = append(keys, key) } sort.Strings(keys) // TODO: Be more intelligent about which unit to kill? victims := keys[wantUnits:len(keys)] for _, victim := range victims { slash := strings.Index(victim, "/") unitId, err := strconv.Atoi(victim[slash+1:]) if err != nil { log.Warn("Error parsing UnitId: %v", victim) return nil, err } err = apiclient.DestroyUnit(jujuServiceId, unitId) if err != nil { log.Warn("Error removing unit: %v/%v", jujuServiceId, unitId, err) return nil, err } } } } } // for _, openPort := range self.OpenPorts { // apiclient.Run(jujuServiceId, nil, ["open-port", openPort]) // //// err = apiclient.OpenPort(jujuServiceId, openPort) // if err != nil { // log.Warn("Error opening port: %v/%v", jujuServiceId, openPort, err) // return nil, err // } // } return serviceInfo, nil }