func LoadFromStore(bundleStore *bundle.BundleStore, key string) (*GenericBundleType, error) { bundleTemplate, err := bundleStore.GetBundleTemplate(key) if err != nil { return nil, err } return NewGenericBundleType(key, bundleTemplate) }
func NewHuddle(system *System, bundleStore *bundle.BundleStore, jujuApi *juju.Client, privateUrl string) (*Huddle, error) { key := "shared" huddle := &Huddle{} environmentInfo, err := jujuApi.EnvironmentInfo() if err != nil { log.Warn("Error reading juju environment info", err) return nil, err } if environmentInfo == nil { return nil, fmt.Errorf("No juju environment info found") } huddle.environmentProviderType = environmentInfo.ProviderType if huddle.environmentProviderType == "" { return nil, fmt.Errorf("Juju environment info invalid: no ProviderType") } log.Info("Juju environment ProviderType is '%v'", huddle.environmentProviderType) systemBundle, err := bundleStore.GetSystemBundle(key) if err != nil { log.Warn("Error loading system bundle: %v", key, err) return nil, err } if systemBundle == nil { log.Warn("Cannot load system bundle: %v", key, err) return nil, nil } info, err := systemBundle.Deploy("jx-", jujuApi) if err != nil { log.Warn("Error deploying system bundle", err) return nil, err } huddle.PrivateUrl = privateUrl huddle.SystemServices = map[string]*SystemService{} huddle.assignedPublicPorts = map[string]int{} for key, service := range info.Services { systemService := &SystemService{} systemService.JujuName = "jx-" + key systemService.Key = key status := service.Status if status != nil { for _, unit := range status.Units { if unit.PublicAddress != "" { systemService.PublicAddress = unit.PublicAddress } externalAddress := "" if unit.Machine != "" { externalAddress, err = jujuApi.PublicAddress(unit.Machine) if err != nil { log.Warn("Error getting public address for machine", err) return nil, err } else { if huddle.IsAmazon() { // Work around a problem where we sometimes get an address that is ip-X-X-X-X.ece2.internal // I think this is a Juju bug (?) if strings.HasSuffix(externalAddress, ".ec2.internal") { log.Warn("Juju gave invalid PublicAddress: %v", externalAddress) externalAddress = systemService.PublicAddress } // Amazon has a special DNS name: ec2-54-172-123-123.compute-1.amazonaws.com // Externally that resolves to 54.172.123.123 (i.e. the value embedded in the name) // Internally (inside EC2) that resolves to the internal IP (172.16.x.x) // We don't want that internal resolution to happen here (this is an _external_ IP) // But we may be within EC2, so we can't simply resolve the name if strings.HasPrefix(externalAddress, "ec2-") && strings.HasSuffix(externalAddress, ".compute-1.amazonaws.com") { ipString := externalAddress[4:] firstDot := strings.IndexRune(ipString, '.') ipString = ipString[:firstDot] ipString = strings.Replace(ipString, "-", ".", -1) log.Info("Replaced EC2 switching-address '%v' with IP '%v'", externalAddress, ipString) externalAddress = ipString } } if externalAddress != "" { log.Info("Chose public address for machine: '%v'", externalAddress) } else { log.Warn("Got empty public address for machine: %v", unit.Machine) } } } if externalAddress == "" { log.Warn("Unable to get external address for machine %v, falling back to public address %v", unit.Machine, systemService.PublicAddress) externalAddress = systemService.PublicAddress } systemService.ExternalAddress = externalAddress } } huddle.SystemServices[key] = systemService } huddle.JujuClient = jujuApi huddle.System = system // TODO: Wait until initialized or offer a separate 'bootstrap' command { check := &HealthCheckAllInstances{} check.huddle = huddle check.repair = true system.Scheduler.AddTask(check, time.Minute*1) } { scaling := &AutoScaleAllInstances{} scaling.huddle = huddle system.Scheduler.AddTask(scaling, time.Minute*1) } { task := &CleanupOldMachines{} task.huddle = huddle system.Scheduler.AddTask(task, time.Minute*5) } return huddle, nil }