Ejemplo n.º 1
0
func LoadFromStore(bundleStore *bundle.BundleStore, key string) (*GenericBundleType, error) {
	bundleTemplate, err := bundleStore.GetBundleTemplate(key)
	if err != nil {
		return nil, err
	}
	return NewGenericBundleType(key, bundleTemplate)
}
Ejemplo n.º 2
0
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
}