Move cri server packages under pkg/cri
Organizes the cri related server packages under pkg/cri Signed-off-by: Derek McGowan <derek@mcg.dev>
This commit is contained in:
120
pkg/cri/server/snapshots.go
Normal file
120
pkg/cri/server/snapshots.go
Normal file
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
Copyright The containerd Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package server
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/containerd/containerd/errdefs"
|
||||
snapshot "github.com/containerd/containerd/snapshots"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
|
||||
ctrdutil "github.com/containerd/containerd/pkg/containerd/util"
|
||||
snapshotstore "github.com/containerd/containerd/pkg/cri/store/snapshot"
|
||||
)
|
||||
|
||||
// snapshotsSyncer syncs snapshot stats periodically. imagefs info and container stats
|
||||
// should both use cached result here.
|
||||
// TODO(random-liu): Benchmark with high workload. We may need a statsSyncer instead if
|
||||
// benchmark result shows that container cpu/memory stats also need to be cached.
|
||||
type snapshotsSyncer struct {
|
||||
store *snapshotstore.Store
|
||||
snapshotter snapshot.Snapshotter
|
||||
syncPeriod time.Duration
|
||||
}
|
||||
|
||||
// newSnapshotsSyncer creates a snapshot syncer.
|
||||
func newSnapshotsSyncer(store *snapshotstore.Store, snapshotter snapshot.Snapshotter,
|
||||
period time.Duration) *snapshotsSyncer {
|
||||
return &snapshotsSyncer{
|
||||
store: store,
|
||||
snapshotter: snapshotter,
|
||||
syncPeriod: period,
|
||||
}
|
||||
}
|
||||
|
||||
// start starts the snapshots syncer. No stop function is needed because
|
||||
// the syncer doesn't update any persistent states, it's fine to let it
|
||||
// exit with the process.
|
||||
func (s *snapshotsSyncer) start() {
|
||||
tick := time.NewTicker(s.syncPeriod)
|
||||
go func() {
|
||||
defer tick.Stop()
|
||||
// TODO(random-liu): This is expensive. We should do benchmark to
|
||||
// check the resource usage and optimize this.
|
||||
for {
|
||||
if err := s.sync(); err != nil {
|
||||
logrus.WithError(err).Error("Failed to sync snapshot stats")
|
||||
}
|
||||
<-tick.C
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
// sync updates all snapshots stats.
|
||||
func (s *snapshotsSyncer) sync() error {
|
||||
ctx := ctrdutil.NamespacedContext()
|
||||
start := time.Now().UnixNano()
|
||||
var snapshots []snapshot.Info
|
||||
// Do not call `Usage` directly in collect function, because
|
||||
// `Usage` takes time, we don't want `Walk` to hold read lock
|
||||
// of snapshot metadata store for too long time.
|
||||
// TODO(random-liu): Set timeout for the following 2 contexts.
|
||||
if err := s.snapshotter.Walk(ctx, func(ctx context.Context, info snapshot.Info) error {
|
||||
snapshots = append(snapshots, info)
|
||||
return nil
|
||||
}); err != nil {
|
||||
return errors.Wrap(err, "walk all snapshots failed")
|
||||
}
|
||||
for _, info := range snapshots {
|
||||
sn, err := s.store.Get(info.Name)
|
||||
if err == nil {
|
||||
// Only update timestamp for non-active snapshot.
|
||||
if sn.Kind == info.Kind && sn.Kind != snapshot.KindActive {
|
||||
sn.Timestamp = time.Now().UnixNano()
|
||||
s.store.Add(sn)
|
||||
continue
|
||||
}
|
||||
}
|
||||
// Get newest stats if the snapshot is new or active.
|
||||
sn = snapshotstore.Snapshot{
|
||||
Key: info.Name,
|
||||
Kind: info.Kind,
|
||||
Timestamp: time.Now().UnixNano(),
|
||||
}
|
||||
usage, err := s.snapshotter.Usage(ctx, info.Name)
|
||||
if err != nil {
|
||||
if !errdefs.IsNotFound(err) {
|
||||
logrus.WithError(err).Errorf("Failed to get usage for snapshot %q", info.Name)
|
||||
}
|
||||
continue
|
||||
}
|
||||
sn.Size = uint64(usage.Size)
|
||||
sn.Inodes = uint64(usage.Inodes)
|
||||
s.store.Add(sn)
|
||||
}
|
||||
for _, sn := range s.store.List() {
|
||||
if sn.Timestamp >= start {
|
||||
continue
|
||||
}
|
||||
// Delete the snapshot stats if it's not updated this time.
|
||||
s.store.Delete(sn.Key)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user