func (t *tcShaper) nextClassID() (int, error) { data, err := t.e.Command("tc", "class", "show", "dev", t.iface).CombinedOutput() if err != nil { return -1, err } scanner := bufio.NewScanner(bytes.NewBuffer(data)) classes := sets.String{} for scanner.Scan() { line := strings.TrimSpace(scanner.Text()) // skip empty lines if len(line) == 0 { continue } parts := strings.Split(line, " ") // expected tc line: // class htb 1:1 root prio 0 rate 1000Kbit ceil 1000Kbit burst 1600b cburst 1600b if len(parts) != 14 { return -1, fmt.Errorf("unexpected output from tc: %s (%v)", scanner.Text(), parts) } classes.Insert(parts[2]) } // Make sure it doesn't go forever for nextClass := 1; nextClass < 10000; nextClass++ { if !classes.Has(fmt.Sprintf("1:%d", nextClass)) { return nextClass, nil } } // This should really never happen return -1, fmt.Errorf("exhausted class space, please try again") }
func (m *DefaultRESTMapper) KindFor(resource unversioned.GroupVersionResource) (unversioned.GroupVersionKind, error) { kinds, err := m.KindsFor(resource) if err != nil { return unversioned.GroupVersionKind{}, err } // TODO for each group, choose the most preferred (first) version. This keeps us consistent with code today. // eventually, we'll need a RESTMapper that is aware of what's available server-side and deconflicts that with // user preferences oneKindPerGroup := []unversioned.GroupVersionKind{} groupsAdded := sets.String{} for _, kind := range kinds { if groupsAdded.Has(kind.Group) { continue } oneKindPerGroup = append(oneKindPerGroup, kind) groupsAdded.Insert(kind.Group) } if len(oneKindPerGroup) == 1 { return oneKindPerGroup[0], nil } return unversioned.GroupVersionKind{}, fmt.Errorf("%v is ambiguous, got: %v", resource, kinds) }
func (r *Requirement) Values() sets.String { ret := sets.String{} for k := range r.strValues { ret.Insert(k) } return ret }
func (g *conversionGenerator) RepackImports(exclude sets.String) { var packages []string for key := range g.imports { packages = append(packages, key) } sort.Strings(packages) g.imports = make(map[string]string) g.shortImports = make(map[string]string) g.targetPackage(g.targetPkg) for _, pkg := range packages { if !exclude.Has(pkg) { g.addImportByPath(pkg) } } }
func ValidateThirdPartyResource(obj *extensions.ThirdPartyResource) field.ErrorList { allErrs := field.ErrorList{} allErrs = append(allErrs, apivalidation.ValidateObjectMeta(&obj.ObjectMeta, true, ValidateThirdPartyResourceName, field.NewPath("metadata"))...) versions := sets.String{} for ix := range obj.Versions { version := &obj.Versions[ix] if len(version.Name) == 0 { allErrs = append(allErrs, field.Invalid(field.NewPath("versions").Index(ix).Child("name"), version, "must not be empty")) } if versions.Has(version.Name) { allErrs = append(allErrs, field.Duplicate(field.NewPath("versions").Index(ix).Child("name"), version)) } versions.Insert(version.Name) } return allErrs }
func (t *ThirdPartyController) syncResourceList(list runtime.Object) error { existing := sets.String{} switch list := list.(type) { case *expapi.ThirdPartyResourceList: // Loop across all schema objects for third party resources for ix := range list.Items { item := &list.Items[ix] // extract the api group and resource kind from the schema _, group, err := thirdpartyresourcedata.ExtractApiGroupAndKind(item) if err != nil { return err } // place it in the set of resources that we expect, so that we don't delete it in the delete pass existing.Insert(makeThirdPartyPath(group)) // ensure a RESTful resource for this schema exists on the master if err := t.SyncOneResource(item); err != nil { return err } } default: return fmt.Errorf("expected a *ThirdPartyResourceList, got %#v", list) } // deletion phase, get all installed RESTful resources installed := t.master.ListThirdPartyResources() for _, installedAPI := range installed { found := false // search across the expected restful resources to see if this resource belongs to one of the expected ones for _, apiPath := range existing.List() { if installedAPI == apiPath || strings.HasPrefix(installedAPI, apiPath+"/") { found = true break } } // not expected, delete the resource if !found { if err := t.master.RemoveThirdPartyResource(installedAPI); err != nil { return err } } } return nil }
func NewDefaultRESTMapper(defaultGroupVersions []unversioned.GroupVersion, interfacesFunc meta.VersionInterfacesFunc, importPathPrefix string, ignoredKinds, rootScoped sets.String) *meta.DefaultRESTMapper { mapper := meta.NewDefaultRESTMapper(defaultGroupVersions, interfacesFunc) // enumerate all supported versions, get the kinds, and register with the mapper how to address // our resources. for _, gv := range defaultGroupVersions { for kind, oType := range Scheme.KnownTypes(gv) { gvk := gv.WithKind(kind) // TODO: Remove import path prefix check. // We check the import path prefix because we currently stuff both "api" and "extensions" objects // into the same group within Scheme since Scheme has no notion of groups yet. if !strings.HasPrefix(oType.PkgPath(), importPathPrefix) || ignoredKinds.Has(kind) { continue } scope := meta.RESTScopeNamespace if rootScoped.Has(kind) { scope = meta.RESTScopeRoot } mapper.Add(gvk, scope, false) } } return mapper }
// NegotiateVersion queries the server's supported api versions to find // a version that both client and server support. // - If no version is provided, try registered client versions in order of // preference. // - If version is provided, but not default config (explicitly requested via // commandline flag), and is unsupported by the server, print a warning to // stderr and try client's registered versions in order of preference. // - If version is config default, and the server does not support it, // return an error. func NegotiateVersion(client *Client, c *Config, requestedGV *unversioned.GroupVersion, clientRegisteredGVs []unversioned.GroupVersion) (*unversioned.GroupVersion, error) { var err error if client == nil { client, err = New(c) if err != nil { return nil, err } } clientVersions := sets.String{} for _, gv := range clientRegisteredGVs { clientVersions.Insert(gv.String()) } groups, err := client.ServerGroups() if err != nil { // This is almost always a connection error, and higher level code should treat this as a generic error, // not a negotiation specific error. return nil, err } versions := ExtractGroupVersions(groups) serverVersions := sets.String{} for _, v := range versions { serverVersions.Insert(v) } // If no version requested, use config version (may also be empty). // make a copy of the original so we don't risk mutating input here or in the returned value var preferredGV *unversioned.GroupVersion switch { case requestedGV != nil: t := *requestedGV preferredGV = &t case c.GroupVersion != nil: t := *c.GroupVersion preferredGV = &t } // If version explicitly requested verify that both client and server support it. // If server does not support warn, but try to negotiate a lower version. if preferredGV != nil { if !clientVersions.Has(preferredGV.String()) { return nil, fmt.Errorf("client does not support API version %q; client supported API versions: %v", preferredGV, clientVersions) } if serverVersions.Has(preferredGV.String()) { return preferredGV, nil } // If we are using an explicit config version the server does not support, fail. if (c.GroupVersion != nil) && (*preferredGV == *c.GroupVersion) { return nil, fmt.Errorf("server does not support API version %q", preferredGV) } } for _, clientGV := range clientRegisteredGVs { if serverVersions.Has(clientGV.String()) { // Version was not explicitly requested in command config (--api-version). // Ok to fall back to a supported version with a warning. // TODO: caesarxuchao: enable the warning message when we have // proper fix. Please refer to issue #14895. // if len(version) != 0 { // glog.Warningf("Server does not support API version '%s'. Falling back to '%s'.", version, clientVersion) // } t := clientGV return &t, nil } } return nil, fmt.Errorf("failed to negotiate an api version; server supports: %v, client supports: %v", serverVersions, clientVersions) }