// match returns true if itype can satisfy the supplied constraints. If so, // it also returns a copy of itype with any arches that do not match the // constraints filtered out. func (itype InstanceType) match(cons constraints.Value) (InstanceType, bool) { nothing := InstanceType{} if cons.Arch != nil { itype.Arches = filterArches(itype.Arches, []string{*cons.Arch}) } if itype.Deprecated && !cons.HasInstanceType() { return nothing, false } if cons.HasInstanceType() && itype.Name != *cons.InstanceType { return nothing, false } if len(itype.Arches) == 0 { return nothing, false } if cons.CpuCores != nil && itype.CpuCores < *cons.CpuCores { return nothing, false } if cons.CpuPower != nil && itype.CpuPower != nil && *itype.CpuPower < *cons.CpuPower { return nothing, false } if cons.Mem != nil && itype.Mem < *cons.Mem { return nothing, false } if cons.RootDisk != nil && itype.RootDisk > 0 && itype.RootDisk < *cons.RootDisk { return nothing, false } if cons.Tags != nil && len(*cons.Tags) > 0 && !tagsMatch(*cons.Tags, itype.Tags) { return nothing, false } if cons.HasVirtType() && (itype.VirtType == nil || *itype.VirtType != *cons.VirtType) { return nothing, false } return itype, true }
// MatchingInstanceTypes returns all instance types matching constraints and available // in region, sorted by increasing region-specific cost (if known). func MatchingInstanceTypes(allInstanceTypes []InstanceType, region string, cons constraints.Value) ([]InstanceType, error) { var itypes []InstanceType // Rules used to select instance types: // - non memory constraints like cpu-cores etc are always honoured // - if no mem constraint specified and instance-type not specified, // try opinionated default with enough mem to run a server. // - if no matches and no mem constraint specified, try again and // return any matching instance with the largest memory origCons := cons if !cons.HasInstanceType() && cons.Mem == nil { minMem := uint64(minMemoryHeuristic) cons.Mem = &minMem } itypes = matchingTypesForConstraint(allInstanceTypes, cons) // No matches using opinionated default, so if no mem constraint specified, // look for matching instance with largest memory. if len(itypes) == 0 && cons.Mem != origCons.Mem { itypes = matchingTypesForConstraint(allInstanceTypes, origCons) if len(itypes) > 0 { sort.Sort(byMemory(itypes)) itypes = []InstanceType{itypes[len(itypes)-1]} } } // If we have matching instance types, we can return those, sorted by cost. if len(itypes) > 0 { sort.Sort(byCost(itypes)) return itypes, nil } // No luck, so report the error. return nil, fmt.Errorf("no instance types in %s matching constraints %q", region, origCons) }
// PrecheckInstance verifies that the provided series and constraints // are valid for use in creating an instance in this environment. func (env *environ) PrecheckInstance(series string, cons constraints.Value, placement string) error { if _, err := env.parsePlacement(placement); err != nil { return errors.Trace(err) } if cons.HasInstanceType() { return errors.Errorf("LXD does not support instance types (got %q)", *cons.InstanceType) } return nil }
// PrecheckInstance verifies that the provided series and constraints // are valid for use in creating an instance in this environment. func (env *environ) PrecheckInstance(series string, cons constraints.Value, placement string) error { if _, err := env.parsePlacement(placement); err != nil { return errors.Trace(err) } if cons.HasInstanceType() { if !checkInstanceType(cons) { return errors.Errorf("invalid GCE instance type %q", *cons.InstanceType) } } return nil }
// PrecheckInstance is defined on the state.Prechecker interface. func (env *joyentEnviron) PrecheckInstance(series string, cons constraints.Value, placement string) error { if placement != "" { return fmt.Errorf("unknown placement directive: %s", placement) } if !cons.HasInstanceType() { return nil } // Constraint has an instance-type constraint so let's see if it is valid. instanceTypes, err := env.listInstanceTypes() if err != nil { return err } for _, instanceType := range instanceTypes { if instanceType.Name == *cons.InstanceType { return nil } } return fmt.Errorf("invalid Joyent instance %q specified", *cons.InstanceType) }
// PrecheckInstance is defined on the state.Prechecker interface. func (e *Environ) PrecheckInstance(series string, cons constraints.Value, placement string) error { if placement != "" { if _, err := e.parsePlacement(placement); err != nil { return err } } if !cons.HasInstanceType() { return nil } // Constraint has an instance-type constraint so let's see if it is valid. novaClient := e.nova() flavors, err := novaClient.ListFlavorsDetail() if err != nil { return err } for _, flavor := range flavors { if flavor.Name == *cons.InstanceType { return nil } } return errors.Errorf("invalid Openstack flavour %q specified", *cons.InstanceType) }