// validateUploadAllowed returns an error if an attempt to upload tools should // not be allowed. func validateUploadAllowed(env environs.Environ, toolsArch, toolsSeries *string, validator constraints.Validator) error { // Now check that the architecture and series for which we are setting up an // environment matches that from which we are bootstrapping. hostArch := arch.HostArch() // We can't build tools for a different architecture if one is specified. if toolsArch != nil && *toolsArch != hostArch { return fmt.Errorf("cannot use agent built for %q using a machine running on %q", *toolsArch, hostArch) } hostOS := jujuos.HostOS() if toolsSeries != nil { toolsSeriesOS, err := series.GetOSFromSeries(*toolsSeries) if err != nil { return errors.Trace(err) } if !toolsSeriesOS.EquivalentTo(hostOS) { return errors.Errorf("cannot use agent built for %q using a machine running %q", *toolsSeries, hostOS) } } // If no architecture is specified, ensure the target provider supports instances matching our architecture. if _, err := validator.Validate(constraints.Value{Arch: &hostArch}); err != nil { return errors.Errorf( "model %q of type %s does not support instances running on %q", env.Config().Name(), env.Config().Type(), hostArch, ) } return nil }
func (st *State) constraintsValidator() (constraints.Validator, error) { // Default behaviour is to simply use a standard validator with // no model specific behaviour built in. var validator constraints.Validator if st.policy != nil { var err error validator, err = st.policy.ConstraintsValidator() if errors.IsNotImplemented(err) { validator = constraints.NewValidator() } else if err != nil { return nil, err } else if validator == nil { return nil, errors.New("policy returned nil constraints validator without an error") } } else { validator = constraints.NewValidator() } // Add supported architectures gleaned from cloud image // metadata to the validator's vocabulary. model, err := st.Model() if err != nil { return nil, errors.Annotate(err, "getting model") } if region := model.CloudRegion(); region != "" { cfg, err := st.ModelConfig() if err != nil { return nil, errors.Trace(err) } arches, err := st.CloudImageMetadataStorage.SupportedArchitectures( cloudimagemetadata.MetadataFilter{ Stream: cfg.AgentStream(), Region: region, }, ) if err != nil { return nil, errors.Annotate(err, "querying supported architectures") } if len(arches) != 0 { validator.UpdateVocabulary(constraints.Arch, arches) } } return validator, nil }