runtime: forward the stat and resize requests from shimv2 to kata agent

Translate the volume path from host-known path to guest-known path
and forward the request to kata agent.

Fixes: #3454

Signed-off-by: Feng Wang <feng.wang@databricks.com>
This commit is contained in:
Feng Wang 2022-01-14 13:23:55 -08:00
parent c39281ad65
commit ea51ef1c40
6 changed files with 88 additions and 0 deletions

View File

@ -190,4 +190,10 @@ type agent interface {
// getAgentMetrics get metrics of agent and guest through agent
getAgentMetrics(context.Context, *grpc.GetMetricsRequest) (*grpc.Metrics, error)
//getGuestVolumeStats get the filesystem stats of a volume specified by the volume mount path on the guest.
getGuestVolumeStats(ctx context.Context, volumeGuestPath string) ([]byte, error)
// resizeGuestVolume resizes a volume specified by the volume mount path on the guest.
resizeGuestVolume(ctx context.Context, volumeGuestPath string, size uint64) error
}

View File

@ -76,6 +76,9 @@ type VCSandbox interface {
UpdateRuntimeMetrics() error
GetAgentMetrics(ctx context.Context) (string, error)
GetAgentURL() (string, error)
GuestVolumeStats(ctx context.Context, volumePath string) ([]byte, error)
ResizeGuestVolume(ctx context.Context, volumePath string, size uint64) error
}
// VCContainer is the Container interface

View File

@ -138,6 +138,8 @@ const (
grpcGetOOMEventRequest = "grpc.GetOOMEventRequest"
grpcGetMetricsRequest = "grpc.GetMetricsRequest"
grpcAddSwapRequest = "grpc.AddSwapRequest"
grpcVolumeStatsRequest = "grpc.VolumeStatsRequest"
grpcResizeVolumeRequest = "grpc.ResizeVolumeRequest"
)
// newKataAgent returns an agent from an agent type.
@ -1952,6 +1954,12 @@ func (k *kataAgent) installReqFunc(c *kataclient.AgentClient) {
k.reqHandlers[grpcAddSwapRequest] = func(ctx context.Context, req interface{}) (interface{}, error) {
return k.client.AgentServiceClient.AddSwap(ctx, req.(*grpc.AddSwapRequest))
}
k.reqHandlers[grpcVolumeStatsRequest] = func(ctx context.Context, req interface{}) (interface{}, error) {
return k.client.AgentServiceClient.GetVolumeStats(ctx, req.(*grpc.VolumeStatsRequest))
}
k.reqHandlers[grpcResizeVolumeRequest] = func(ctx context.Context, req interface{}) (interface{}, error) {
return k.client.AgentServiceClient.ResizeVolume(ctx, req.(*grpc.ResizeVolumeRequest))
}
}
func (k *kataAgent) getReqContext(ctx context.Context, reqName string) (newCtx context.Context, cancel context.CancelFunc) {
@ -2169,3 +2177,22 @@ func (k *kataAgent) getAgentMetrics(ctx context.Context, req *grpc.GetMetricsReq
return resp.(*grpc.Metrics), nil
}
func (k *kataAgent) getGuestVolumeStats(ctx context.Context, volumeGuestPath string) ([]byte, error) {
result, err := k.sendReq(ctx, &grpc.VolumeStatsRequest{VolumeGuestPath: volumeGuestPath})
if err != nil {
return nil, err
}
buf, err := json.Marshal(result.(*grpc.VolumeStatsResponse))
if err != nil {
return nil, err
}
return buf, nil
}
func (k *kataAgent) resizeGuestVolume(ctx context.Context, volumeGuestPath string, size uint64) error {
_, err := k.sendReq(ctx, &grpc.ResizeVolumeRequest{VolumeGuestPath: volumeGuestPath, Size_: size})
return err
}

View File

@ -242,3 +242,11 @@ func (n *mockAgent) getOOMEvent(ctx context.Context) (string, error) {
func (n *mockAgent) getAgentMetrics(ctx context.Context, req *grpc.GetMetricsRequest) (*grpc.Metrics, error) {
return nil, nil
}
func (n *mockAgent) getGuestVolumeStats(ctx context.Context, volumeGuestPath string) ([]byte, error) {
return nil, nil
}
func (n *mockAgent) resizeGuestVolume(ctx context.Context, volumeGuestPath string, size uint64) error {
return nil
}

View File

@ -254,3 +254,10 @@ func (s *Sandbox) GetAgentURL() (string, error) {
func (s *Sandbox) GetHypervisorPid() (int, error) {
return 0, nil
}
func (s *Sandbox) GuestVolumeStats(ctx context.Context, path string) ([]byte, error) {
return nil, nil
}
func (s *Sandbox) ResizeGuestVolume(ctx context.Context, path string, size uint64) error {
return nil
}

View File

@ -2257,6 +2257,43 @@ func (s *Sandbox) GetAgentURL() (string, error) {
return s.agent.getAgentURL()
}
// GuestVolumeStats return the filesystem stat of a given volume in the guest.
func (s *Sandbox) GuestVolumeStats(ctx context.Context, volumePath string) ([]byte, error) {
guestMountPath, err := s.guestMountPath(volumePath)
if err != nil {
return nil, err
}
return s.agent.getGuestVolumeStats(ctx, guestMountPath)
}
// ResizeGuestVolume resizes a volume in the guest.
func (s *Sandbox) ResizeGuestVolume(ctx context.Context, volumePath string, size uint64) error {
// TODO: https://github.com/kata-containers/kata-containers/issues/3694.
guestMountPath, err := s.guestMountPath(volumePath)
if err != nil {
return err
}
return s.agent.resizeGuestVolume(ctx, guestMountPath, size)
}
func (s *Sandbox) guestMountPath(volumePath string) (string, error) {
// verify the device even exists
if _, err := os.Stat(volumePath); err != nil {
s.Logger().WithError(err).WithField("volume", volumePath).Error("Cannot get stats for volume that doesn't exist")
return "", err
}
// verify that we have a mount in this sandbox who's source maps to this
for _, c := range s.containers {
for _, m := range c.mounts {
if volumePath == m.Source {
return m.GuestDeviceMount, nil
}
}
}
return "", fmt.Errorf("mount %s not found in sandbox", volumePath)
}
// getSandboxCPUSet returns the union of each of the sandbox's containers' CPU sets'
// cpus and mems as a string in canonical linux CPU/mems list format
func (s *Sandbox) getSandboxCPUSet() (string, string, error) {