github.com/kata-containers/runtime@v0.0.0-20210505125100-04f29832a923/virtcontainers/experimental/experimental.go (about)

     1  // Copyright (c) 2019 Huawei Corporation
     2  //
     3  // SPDX-License-Identifier: Apache-2.0
     4  //
     5  
     6  package experimental
     7  
     8  import (
     9  	"context"
    10  	"fmt"
    11  	"regexp"
    12  )
    13  
    14  const (
    15  	nameRegStr = "^[a-z][a-z0-9_]*$"
    16  )
    17  
    18  // Feature to be experimental
    19  type Feature struct {
    20  	Name        string
    21  	Description string
    22  	// the expected release version to move out from experimental
    23  	ExpRelease string
    24  }
    25  
    26  type contextKey struct{}
    27  
    28  var (
    29  	supportedFeatures = make(map[string]Feature)
    30  	expContextKey     = contextKey{}
    31  )
    32  
    33  // Register register a new experimental feature
    34  func Register(feature Feature) error {
    35  	if err := validateFeature(feature); err != nil {
    36  		return err
    37  	}
    38  
    39  	if _, ok := supportedFeatures[feature.Name]; ok {
    40  		return fmt.Errorf("Feature %q had been registered before", feature.Name)
    41  	}
    42  	supportedFeatures[feature.Name] = feature
    43  	return nil
    44  }
    45  
    46  // Get returns Feature with requested name
    47  func Get(name string) *Feature {
    48  	if f, ok := supportedFeatures[name]; ok {
    49  		return &f
    50  	}
    51  	return nil
    52  }
    53  
    54  func validateFeature(feature Feature) error {
    55  	if len(feature.Name) == 0 ||
    56  		len(feature.Description) == 0 ||
    57  		len(feature.ExpRelease) == 0 {
    58  		return fmt.Errorf("experimental feature must have valid name, description and expected release")
    59  	}
    60  
    61  	reg := regexp.MustCompile(nameRegStr)
    62  	if !reg.MatchString(feature.Name) {
    63  		return fmt.Errorf("feature name must in the format %q", nameRegStr)
    64  	}
    65  
    66  	return nil
    67  }
    68  
    69  func ContextWithExp(ctx context.Context, names []string) context.Context {
    70  	return context.WithValue(ctx, expContextKey, names)
    71  }
    72  
    73  func ExpFromContext(ctx context.Context) []string {
    74  	value := ctx.Value(expContextKey)
    75  	if value == nil {
    76  		return nil
    77  	}
    78  	names := value.([]string)
    79  	return names
    80  }