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

命令:

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)
}

 

 

 

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值