...

Source file src/github.com/Microsoft/hcsshim/internal/ncproxy/store/store.go

Documentation: github.com/Microsoft/hcsshim/internal/ncproxy/store

     1  package store
     2  
     3  import (
     4  	"context"
     5  	"encoding/json"
     6  
     7  	ncproxynetworking "github.com/Microsoft/hcsshim/internal/ncproxy/networking"
     8  	"github.com/pkg/errors"
     9  	bolt "go.etcd.io/bbolt"
    10  )
    11  
    12  var (
    13  	ErrBucketNotFound = errors.New("bucket not found")
    14  	ErrKeyNotFound    = errors.New("key does not exist")
    15  )
    16  
    17  type NetworkingStore struct {
    18  	db *bolt.DB
    19  }
    20  
    21  func NewNetworkingStore(database *bolt.DB) *NetworkingStore {
    22  	return &NetworkingStore{
    23  		db: database,
    24  	}
    25  }
    26  
    27  func (n *NetworkingStore) Close() error {
    28  	return n.db.Close()
    29  }
    30  
    31  func (n *NetworkingStore) GetNetworkByName(ctx context.Context, networkName string) (*ncproxynetworking.Network, error) {
    32  	internalData := &ncproxynetworking.Network{}
    33  	if err := n.db.View(func(tx *bolt.Tx) error {
    34  		bkt := getNetworkBucket(tx)
    35  		if bkt == nil {
    36  			return errors.Wrapf(ErrBucketNotFound, "network bucket %v", bucketKeyNetwork)
    37  		}
    38  		data := bkt.Get([]byte(networkName))
    39  		if data == nil {
    40  			return errors.Wrapf(ErrKeyNotFound, "network %v", networkName)
    41  		}
    42  		if err := json.Unmarshal(data, internalData); err != nil {
    43  			return errors.Wrapf(err, "data is %v", string(data))
    44  		}
    45  		return nil
    46  	}); err != nil {
    47  		return nil, err
    48  	}
    49  	return internalData, nil
    50  }
    51  
    52  func (n *NetworkingStore) CreateNetwork(ctx context.Context, network *ncproxynetworking.Network) error {
    53  	if err := n.db.Update(func(tx *bolt.Tx) error {
    54  		bkt, err := createNetworkBucket(tx)
    55  		if err != nil {
    56  			return err
    57  		}
    58  		internalData, err := json.Marshal(network)
    59  		if err != nil {
    60  			return err
    61  		}
    62  		return bkt.Put([]byte(network.NetworkName), internalData)
    63  	}); err != nil {
    64  		return err
    65  	}
    66  	return nil
    67  }
    68  
    69  func (n *NetworkingStore) DeleteNetwork(ctx context.Context, networkName string) error {
    70  	if err := n.db.Update(func(tx *bolt.Tx) error {
    71  		bkt := getNetworkBucket(tx)
    72  		if bkt == nil {
    73  			return errors.Wrapf(ErrBucketNotFound, "bucket %v", bucketKeyNetwork)
    74  		}
    75  		return bkt.Delete([]byte(networkName))
    76  	}); err != nil {
    77  		return err
    78  	}
    79  	return nil
    80  }
    81  
    82  func (n *NetworkingStore) ListNetworks(ctx context.Context) (results []*ncproxynetworking.Network, err error) {
    83  	if err := n.db.View(func(tx *bolt.Tx) error {
    84  		bkt := getNetworkBucket(tx)
    85  		if bkt == nil {
    86  			return errors.Wrapf(ErrBucketNotFound, "network bucket %v", bucketKeyNetwork)
    87  		}
    88  		err := bkt.ForEach(func(k, v []byte) error {
    89  			internalData := &ncproxynetworking.Network{}
    90  			if err := json.Unmarshal(v, internalData); err != nil {
    91  				return errors.Wrapf(err, "data is %v", string(v))
    92  			}
    93  			results = append(results, internalData)
    94  			return nil
    95  		})
    96  		return err
    97  	}); err != nil {
    98  		return nil, err
    99  	}
   100  
   101  	return results, nil
   102  }
   103  
   104  func (n *NetworkingStore) GetEndpointByName(ctx context.Context, endpointName string) (*ncproxynetworking.Endpoint, error) {
   105  	endpt := &ncproxynetworking.Endpoint{}
   106  	if err := n.db.View(func(tx *bolt.Tx) error {
   107  		bkt := getEndpointBucket(tx)
   108  		if bkt == nil {
   109  			return errors.Wrapf(ErrBucketNotFound, "endpoint bucket %v", bucketKeyEndpoint)
   110  		}
   111  		jsonData := bkt.Get([]byte(endpointName))
   112  		if jsonData == nil {
   113  			return errors.Wrapf(ErrKeyNotFound, "endpoint %v", endpointName)
   114  		}
   115  		if err := json.Unmarshal(jsonData, endpt); err != nil {
   116  			return err
   117  		}
   118  		return nil
   119  	}); err != nil {
   120  		return nil, err
   121  	}
   122  
   123  	return endpt, nil
   124  }
   125  
   126  func (n *NetworkingStore) CreatEndpoint(ctx context.Context, endpt *ncproxynetworking.Endpoint) error {
   127  	return n.updateEndpoint(ctx, endpt)
   128  }
   129  
   130  func (n *NetworkingStore) UpdateEndpoint(ctx context.Context, endpt *ncproxynetworking.Endpoint) error {
   131  	return n.updateEndpoint(ctx, endpt)
   132  }
   133  
   134  func (n *NetworkingStore) updateEndpoint(ctx context.Context, endpt *ncproxynetworking.Endpoint) error {
   135  	if err := n.db.Update(func(tx *bolt.Tx) error {
   136  		bkt, err := createEndpointBucket(tx)
   137  		if err != nil {
   138  			return err
   139  		}
   140  		jsonEndptData, err := json.Marshal(endpt)
   141  		if err != nil {
   142  			return err
   143  		}
   144  		return bkt.Put([]byte(endpt.EndpointName), jsonEndptData)
   145  	}); err != nil {
   146  		return err
   147  	}
   148  	return nil
   149  }
   150  
   151  func (n *NetworkingStore) DeleteEndpoint(ctx context.Context, endpointName string) error {
   152  	if err := n.db.Update(func(tx *bolt.Tx) error {
   153  		bkt := getEndpointBucket(tx)
   154  		if bkt == nil {
   155  			return errors.Wrapf(ErrBucketNotFound, "bucket %v", bucketKeyEndpoint)
   156  		}
   157  		return bkt.Delete([]byte(endpointName))
   158  	}); err != nil {
   159  		return err
   160  	}
   161  	return nil
   162  }
   163  
   164  func (n *NetworkingStore) ListEndpoints(ctx context.Context) (results []*ncproxynetworking.Endpoint, err error) {
   165  	if err := n.db.View(func(tx *bolt.Tx) error {
   166  		bkt := getEndpointBucket(tx)
   167  		if bkt == nil {
   168  			return errors.Wrapf(ErrBucketNotFound, "endpoint bucket %v", bucketKeyEndpoint)
   169  		}
   170  		err := bkt.ForEach(func(k, v []byte) error {
   171  			endptInternal := &ncproxynetworking.Endpoint{}
   172  			if err := json.Unmarshal(v, endptInternal); err != nil {
   173  				return err
   174  			}
   175  			results = append(results, endptInternal)
   176  			return nil
   177  		})
   178  		return err
   179  	}); err != nil {
   180  		return nil, err
   181  	}
   182  
   183  	return results, nil
   184  }
   185  
   186  // ComputeAgentStore is a database that stores a key value pair of container id
   187  // to compute agent server address
   188  type ComputeAgentStore struct {
   189  	db *bolt.DB
   190  }
   191  
   192  func NewComputeAgentStore(db *bolt.DB) *ComputeAgentStore {
   193  	return &ComputeAgentStore{db: db}
   194  }
   195  
   196  func (c *ComputeAgentStore) Close() error {
   197  	return c.db.Close()
   198  }
   199  
   200  // GetComputeAgent returns the compute agent address of a single entry in the database for key `containerID`
   201  // or returns an error if the key does not exist
   202  func (c *ComputeAgentStore) GetComputeAgent(ctx context.Context, containerID string) (result string, err error) {
   203  	if err := c.db.View(func(tx *bolt.Tx) error {
   204  		bkt := getComputeAgentBucket(tx)
   205  		if bkt == nil {
   206  			return errors.Wrapf(ErrBucketNotFound, "bucket %v", bucketKeyComputeAgent)
   207  		}
   208  		data := bkt.Get([]byte(containerID))
   209  		if data == nil {
   210  			return errors.Wrapf(ErrKeyNotFound, "key %v", containerID)
   211  		}
   212  		result = string(data)
   213  		return nil
   214  	}); err != nil {
   215  		return "", err
   216  	}
   217  
   218  	return result, nil
   219  }
   220  
   221  // GetComputeAgents returns a map of the key value pairs stored in the database
   222  // where the keys are the containerIDs and the values are the corresponding compute agent
   223  // server addresses
   224  func (c *ComputeAgentStore) GetComputeAgents(ctx context.Context) (map[string]string, error) {
   225  	content := map[string]string{}
   226  	if err := c.db.View(func(tx *bolt.Tx) error {
   227  		bkt := getComputeAgentBucket(tx)
   228  		if bkt == nil {
   229  			return errors.Wrapf(ErrBucketNotFound, "bucket %v", bucketKeyComputeAgent)
   230  		}
   231  		err := bkt.ForEach(func(k, v []byte) error {
   232  			content[string(k)] = string(v)
   233  			return nil
   234  		})
   235  		return err
   236  	}); err != nil {
   237  		return nil, err
   238  	}
   239  	return content, nil
   240  }
   241  
   242  // UpdateComputeAgent updates or adds an entry (if none already exists) to the database
   243  // `address` corresponds to the address of the compute agent server for the `containerID`
   244  func (c *ComputeAgentStore) UpdateComputeAgent(ctx context.Context, containerID string, address string) error {
   245  	if err := c.db.Update(func(tx *bolt.Tx) error {
   246  		bkt, err := createComputeAgentBucket(tx)
   247  		if err != nil {
   248  			return err
   249  		}
   250  		return bkt.Put([]byte(containerID), []byte(address))
   251  	}); err != nil {
   252  		return err
   253  	}
   254  	return nil
   255  }
   256  
   257  // DeleteComputeAgent deletes an entry in the database or returns an error if none exists
   258  // `containerID` corresponds to the target key that the entry should be deleted for
   259  func (c *ComputeAgentStore) DeleteComputeAgent(ctx context.Context, containerID string) error {
   260  	if err := c.db.Update(func(tx *bolt.Tx) error {
   261  		bkt := getComputeAgentBucket(tx)
   262  		if bkt == nil {
   263  			return errors.Wrapf(ErrBucketNotFound, "bucket %v", bucketKeyComputeAgent)
   264  		}
   265  		return bkt.Delete([]byte(containerID))
   266  	}); err != nil {
   267  		return err
   268  	}
   269  	return nil
   270  }
   271  

View as plain text