【containerd 1.0 源码分析】ctr containers list 源码分析

来源:互联网 发布:电表数据丢失 编辑:程序博客网 时间:2024/06/06 09:51

命令:

ctr containers -h
NAME:
   ctr containers - manage containers (metadata)


USAGE:
   ctr containers command [command options] [arguments...]


COMMANDS:
     list, ls         list all tasks or those that match a filter
     delete, del, rm  delete an existing container
     label            Set and clear labels for a container.


OPTIONS:
   --help, -h  show help

一. ctr containers list 命令


    
    1.1 服务端收到 GRPC 请求
func _Containers_List_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {       in := new(ListContainersRequest)       if err := dec(in); err != nil {              return nil, err       }       if interceptor == nil {              return srv.(ContainersServer).List(ctx, in)       }       info := &grpc.UnaryServerInfo{              Server:     srv,              FullMethod: "/containerd.services.containers.v1.Containers/List",       }       handler := func(ctx context.Context, req interface{}) (interface{}, error) {              return srv.(ContainersServer).List(ctx, req.(*ListContainersRequest))       }       return interceptor(ctx, in, info, handler)}

    1.2 services/containers/service.go 中 重要的函数 store.List 为实现的接口
func (s *Service) List(ctx context.Context, req *api.ListContainersRequest) (*api.ListContainersResponse, error) {       var resp api.ListContainersResponse       return &resp, errdefs.ToGRPC(s.withStoreView(ctx, func(ctx context.Context, store containers.Store) error {              containers, err := store.List(ctx, req.Filters...)              if err != nil {                     return err              }              resp.Containers = containersToProto(containers)              return nil       }))}

    1.3 根据 withStore 函数可以得到 store 为 metadata.NewContainerStore,路径 /metadata/containers.go 中,containerStore 结构体是包裹的是操作数据库
type containerStore struct {       tx *bolt.Tx}func NewContainerStore(tx *bolt.Tx) containers.Store {       return &containerStore{              tx: tx,       }}

    1.4 List 函数中 getContainerBucket 如果为空,证明没有container 在 1.4.1 中讲解,readContainer 将数据读入到 container 中。
func (s *containerStore) List(ctx context.Context, fs ...string) ([]containers.Container, error) {       namespace, err := namespaces.NamespaceRequired(ctx)              filter, err := filters.ParseAll(fs...)       bkt := getContainersBucket(s.tx, namespace)       if bkt == nil {              return nil, nil       }       var m []containers.Container       if err := bkt.ForEach(func(k, v []byte) error {              cbkt := bkt.Bucket(k)              if cbkt == nil {                     return nil              }              container := containers.Container{ID: string(k)}              if err := readContainer(&container, cbkt); err != nil {                     return errors.Wrap(err, "failed to read container")              }              if filter.Match(adaptContainer(container)) {                     m = append(m, container)              }              return nil       }); err != nil {              return nil, err       }       return m, nil}

    1.4.1 getContainersBucket 中 namespace 一般默认为 default,bucketKeyObjectContainers 为 contaiers,1.4.1.1 分析 bolt.Tx 结构体,数据库的有点乱,现在只知道是操作数据库就行了。尴尬!!!tx.Bucket 在 1.4.1.2 讲解
func getContainersBucket(tx *bolt.Tx, namespace string) *bolt.Bucket {       return getBucket(tx, bucketKeyVersion, []byte(namespace), bucketKeyObjectContainers)}
func getBucket(tx *bolt.Tx, keys ...[]byte) *bolt.Bucket {       bkt := tx.Bucket(keys[0])       for _, key := range keys[1:] {              if bkt == nil {                     break              }              bkt = bkt.Bucket(key)       }       return bkt}

    1.4.1.1 结构体
type Tx struct {       writable       bool       managed        bool       db             *DB       meta           *meta       root           Bucket       pages          map[pgid]*page       stats          TxStats       commitHandlers []func()       WriteFlag int
    Bucket 表示 key / value 对存在数据库中
// Bucket represents a collection of key/value pairs inside the database.type Bucket struct {       *bucket       tx       *Tx                // the associated transaction       buckets  map[string]*Bucket // subbucket cache       page     *page              // inline page reference       rootNode *node              // materialized node for the root page.       nodes    map[pgid]*node     // node cache       // Sets the threshold for filling nodes when they split. By default,       // the bucket will fill to 50% but it can be useful to increase this       // amount if you know that your write workloads are mostly append-only.       //       // This is non-persisted across transactions so it must be set in every Tx.       FillPercent float64}

     1.4.1.2 Bucket 函数根据名字检索,返回 Bucket 结构体
func (tx *Tx) Bucket(name []byte) *Bucket {       return tx.root.Bucket(name)}



阅读全文
0 0
原创粉丝点击