Commit a77450ec authored by Lantao Liu's avatar Lantao Liu

Add mountpoint as CRI image filesystem storage identifier.

parent c37b5d75
......@@ -1103,18 +1103,18 @@ message UInt64Value {
uint64 value = 1;
}
// StorageIdentifier uniquely identify the storage..
message StorageIdentifier{
// UUID of the device.
string uuid = 1;
// FilesystemIdentifier uniquely identify the filesystem.
message FilesystemIdentifier{
// Mountpoint of a filesystem.
string mountpoint = 1;
}
// FilesystemUsage provides the filesystem usage information.
message FilesystemUsage {
// Timestamp in nanoseconds at which the information were collected. Must be > 0.
int64 timestamp = 1;
// The underlying storage of the filesystem.
StorageIdentifier storage_id = 2;
// The unique identifier of the filesystem.
FilesystemIdentifier fs_id = 2;
// UsedBytes represents the bytes used for images on the filesystem.
// This may differ from the total bytes used on the filesystem and may not
// equal CapacityBytes - AvailableBytes.
......
......@@ -77,6 +77,6 @@ func (cu *cadvisorUnsupported) WatchEvents(request *events.Request) (*events.Eve
return nil, unsupportedErr
}
func (c *cadvisorUnsupported) GetFsInfoByFsUUID(uuid string) (cadvisorapiv2.FsInfo, error) {
func (cu *cadvisorUnsupported) GetDirFsInfo(path string) (cadvisorapiv2.FsInfo, error) {
return cadvisorapiv2.FsInfo{}, nil
}
......@@ -77,6 +77,6 @@ func (cu *cadvisorClient) WatchEvents(request *events.Request) (*events.EventCha
return &events.EventChannel{}, nil
}
func (c *cadvisorClient) GetFsInfoByFsUUID(uuid string) (cadvisorapiv2.FsInfo, error) {
func (cu *cadvisorClient) GetDirFsInfo(path string) (cadvisorapiv2.FsInfo, error) {
return cadvisorapiv2.FsInfo{}, nil
}
......@@ -76,6 +76,6 @@ func (c *Fake) WatchEvents(request *events.Request) (*events.EventChannel, error
return new(events.EventChannel), nil
}
func (c *Fake) GetFsInfoByFsUUID(uuid string) (cadvisorapiv2.FsInfo, error) {
func (c *Fake) GetDirFsInfo(path string) (cadvisorapiv2.FsInfo, error) {
return cadvisorapiv2.FsInfo{}, nil
}
......@@ -84,7 +84,7 @@ func (c *Mock) WatchEvents(request *events.Request) (*events.EventChannel, error
return args.Get(0).(*events.EventChannel), args.Error(1)
}
func (c *Mock) GetFsInfoByFsUUID(uuid string) (cadvisorapiv2.FsInfo, error) {
args := c.Called(uuid)
func (c *Mock) GetDirFsInfo(path string) (cadvisorapiv2.FsInfo, error) {
args := c.Called(path)
return args.Get(0).(cadvisorapiv2.FsInfo), args.Error(1)
}
......@@ -42,9 +42,8 @@ type Interface interface {
// Get events streamed through passedChannel that fit the request.
WatchEvents(request *events.Request) (*events.EventChannel, error)
// GetFsInfoByFsUUID returns the stats of the filesystem with the specified
// uuid.
GetFsInfoByFsUUID(uuid string) (cadvisorapiv2.FsInfo, error)
// Get filesystem information for the filesystem that contains the given file.
GetDirFsInfo(path string) (cadvisorapiv2.FsInfo, error)
}
// ImageFsInfoProvider informs cAdvisor how to find imagefs for container images.
......
......@@ -95,10 +95,10 @@ func (p *criStatsProvider) ListPodStats() ([]statsapi.PodStats, error) {
podSandboxMap[s.Id] = s
}
// uuidToFsInfo is a map from filesystem UUID to its stats. This will be
// used as a cache to avoid querying cAdvisor for the filesystem stats with
// the same UUID many times.
uuidToFsInfo := make(map[runtimeapi.StorageIdentifier]*cadvisorapiv2.FsInfo)
// fsIDtoInfo is a map from filesystem id to its stats. This will be used
// as a cache to avoid querying cAdvisor for the filesystem stats with the
// same filesystem id many times.
fsIDtoInfo := make(map[runtimeapi.FilesystemIdentifier]*cadvisorapiv2.FsInfo)
// sandboxIDToPodStats is a temporary map from sandbox ID to its pod stats.
sandboxIDToPodStats := make(map[string]*statsapi.PodStats)
......@@ -149,7 +149,7 @@ func (p *criStatsProvider) ListPodStats() ([]statsapi.PodStats, error) {
}
sandboxIDToPodStats[podSandboxID] = ps
}
cs := p.makeContainerStats(stats, container, &rootFsInfo, uuidToFsInfo)
cs := p.makeContainerStats(stats, container, &rootFsInfo, fsIDtoInfo)
// If cadvisor stats is available for the container, use it to populate
// container stats
caStats, caFound := caInfos[containerID]
......@@ -186,11 +186,11 @@ func (p *criStatsProvider) ImageFsStats() (*statsapi.FsStats, error) {
UsedBytes: &fs.UsedBytes.Value,
InodesUsed: &fs.InodesUsed.Value,
}
imageFsInfo := p.getFsInfo(fs.StorageId)
imageFsInfo := p.getFsInfo(fs.GetFsId())
if imageFsInfo != nil {
// The image filesystem UUID is unknown to the local node or
// there's an error on retrieving the stats. In these cases, we
// omit those stats and return the best-effort partial result. See
// The image filesystem id is unknown to the local node or there's
// an error on retrieving the stats. In these cases, we omit those
// stats and return the best-effort partial result. See
// https://github.com/kubernetes/heapster/issues/1793.
s.AvailableBytes = &imageFsInfo.Available
s.CapacityBytes = &imageFsInfo.Capacity
......@@ -211,7 +211,7 @@ func (p *criStatsProvider) ImageFsDevice() (string, error) {
return "", err
}
for _, fs := range resp {
fsInfo := p.getFsInfo(fs.GetStorageId())
fsInfo := p.getFsInfo(fs.GetFsId())
if fsInfo != nil {
return fsInfo.Device, nil
}
......@@ -220,16 +220,17 @@ func (p *criStatsProvider) ImageFsDevice() (string, error) {
}
// getFsInfo returns the information of the filesystem with the specified
// storageID. If any error occurs, this function logs the error and returns
// fsID. If any error occurs, this function logs the error and returns
// nil.
func (p *criStatsProvider) getFsInfo(storageID *runtimeapi.StorageIdentifier) *cadvisorapiv2.FsInfo {
if storageID == nil {
glog.V(2).Infof("Failed to get filesystem info: storageID is nil.")
func (p *criStatsProvider) getFsInfo(fsID *runtimeapi.FilesystemIdentifier) *cadvisorapiv2.FsInfo {
if fsID == nil {
glog.V(2).Infof("Failed to get filesystem info: fsID is nil.")
return nil
}
fsInfo, err := p.cadvisor.GetFsInfoByFsUUID(storageID.Uuid)
mountpoint := fsID.GetMountpoint()
fsInfo, err := p.cadvisor.GetDirFsInfo(mountpoint)
if err != nil {
msg := fmt.Sprintf("Failed to get the info of the filesystem with id %q: %v.", storageID.Uuid, err)
msg := fmt.Sprintf("Failed to get the info of the filesystem with mountpoint %q: %v.", mountpoint, err)
if err == cadvisorfs.ErrNoSuchDevice {
glog.V(2).Info(msg)
} else {
......@@ -275,7 +276,7 @@ func (p *criStatsProvider) makeContainerStats(
stats *runtimeapi.ContainerStats,
container *runtimeapi.Container,
rootFsInfo *cadvisorapiv2.FsInfo,
uuidToFsInfo map[runtimeapi.StorageIdentifier]*cadvisorapiv2.FsInfo,
fsIDtoInfo map[runtimeapi.FilesystemIdentifier]*cadvisorapiv2.FsInfo,
) *statsapi.ContainerStats {
result := &statsapi.ContainerStats{
Name: stats.Attributes.Metadata.Name,
......@@ -324,16 +325,16 @@ func (p *criStatsProvider) makeContainerStats(
result.Rootfs.InodesUsed = &stats.WritableLayer.InodesUsed.Value
}
}
storageID := stats.GetWritableLayer().GetStorageId()
if storageID != nil {
imageFsInfo, found := uuidToFsInfo[*storageID]
fsID := stats.GetWritableLayer().GetFsId()
if fsID != nil {
imageFsInfo, found := fsIDtoInfo[*fsID]
if !found {
imageFsInfo = p.getFsInfo(storageID)
uuidToFsInfo[*storageID] = imageFsInfo
imageFsInfo = p.getFsInfo(fsID)
fsIDtoInfo[*fsID] = imageFsInfo
}
if imageFsInfo != nil {
// The image filesystem UUID is unknown to the local node or there's an
// error on retrieving the stats. In these cases, we omit those stats
// The image filesystem id is unknown to the local node or there's
// an error on retrieving the stats. In these cases, we omit those stats
// and return the best-effort partial result. See
// https://github.com/kubernetes/heapster/issues/1793.
result.Rootfs.AvailableBytes = &imageFsInfo.Available
......
......@@ -63,26 +63,26 @@ func TestCRIListPodStats(t *testing.T) {
)
var (
imageFsStorageUUID = "imagefs-storage-uuid"
unknownStorageUUID = "unknown-storage-uuid"
imageFsInfo = getTestFsInfo(2000)
rootFsInfo = getTestFsInfo(1000)
imageFsMountpoint = "/test/mount/point"
unknownMountpoint = "/unknown/mount/point"
imageFsInfo = getTestFsInfo(2000)
rootFsInfo = getTestFsInfo(1000)
sandbox0 = makeFakePodSandbox("sandbox0-name", "sandbox0-uid", "sandbox0-ns")
container0 = makeFakeContainer(sandbox0, cName0, 0, false)
containerStats0 = makeFakeContainerStats(container0, imageFsStorageUUID)
containerStats0 = makeFakeContainerStats(container0, imageFsMountpoint)
container1 = makeFakeContainer(sandbox0, cName1, 0, false)
containerStats1 = makeFakeContainerStats(container1, unknownStorageUUID)
containerStats1 = makeFakeContainerStats(container1, unknownMountpoint)
sandbox1 = makeFakePodSandbox("sandbox1-name", "sandbox1-uid", "sandbox1-ns")
container2 = makeFakeContainer(sandbox1, cName2, 0, false)
containerStats2 = makeFakeContainerStats(container2, imageFsStorageUUID)
containerStats2 = makeFakeContainerStats(container2, imageFsMountpoint)
sandbox2 = makeFakePodSandbox("sandbox2-name", "sandbox2-uid", "sandbox2-ns")
container3 = makeFakeContainer(sandbox2, cName3, 0, true)
containerStats3 = makeFakeContainerStats(container3, imageFsStorageUUID)
containerStats3 = makeFakeContainerStats(container3, imageFsMountpoint)
container4 = makeFakeContainer(sandbox2, cName3, 1, false)
containerStats4 = makeFakeContainerStats(container4, imageFsStorageUUID)
containerStats4 = makeFakeContainerStats(container4, imageFsMountpoint)
)
var (
......@@ -116,8 +116,8 @@ func TestCRIListPodStats(t *testing.T) {
mockCadvisor.
On("ContainerInfoV2", "/", options).Return(infos, nil).
On("RootFsInfo").Return(rootFsInfo, nil).
On("GetFsInfoByFsUUID", imageFsStorageUUID).Return(imageFsInfo, nil).
On("GetFsInfoByFsUUID", unknownStorageUUID).Return(cadvisorapiv2.FsInfo{}, cadvisorfs.ErrNoSuchDevice)
On("GetDirFsInfo", imageFsMountpoint).Return(imageFsInfo, nil).
On("GetDirFsInfo", unknownMountpoint).Return(cadvisorapiv2.FsInfo{}, cadvisorfs.ErrNoSuchDevice)
fakeRuntimeService.SetFakeSandboxes([]*critest.FakePodSandbox{
sandbox0, sandbox1, sandbox2,
})
......@@ -209,9 +209,9 @@ func TestCRIListPodStats(t *testing.T) {
func TestCRIImagesFsStats(t *testing.T) {
var (
imageFsStorageUUID = "imagefs-storage-uuid"
imageFsInfo = getTestFsInfo(2000)
imageFsUsage = makeFakeImageFsUsage(imageFsStorageUUID)
imageFsMountpoint = "/test/mount/point"
imageFsInfo = getTestFsInfo(2000)
imageFsUsage = makeFakeImageFsUsage(imageFsMountpoint)
)
var (
mockCadvisor = new(cadvisortest.Mock)
......@@ -222,7 +222,7 @@ func TestCRIImagesFsStats(t *testing.T) {
fakeImageService = critest.NewFakeImageService()
)
mockCadvisor.On("GetFsInfoByFsUUID", imageFsStorageUUID).Return(imageFsInfo, nil)
mockCadvisor.On("GetDirFsInfo", imageFsMountpoint).Return(imageFsInfo, nil)
fakeImageService.SetFakeFilesystemUsage([]*runtimeapi.FilesystemUsage{
imageFsUsage,
})
......@@ -292,7 +292,7 @@ func makeFakeContainer(sandbox *critest.FakePodSandbox, name string, attempt uin
return c
}
func makeFakeContainerStats(container *critest.FakeContainer, imageFsUUID string) *runtimeapi.ContainerStats {
func makeFakeContainerStats(container *critest.FakeContainer, imageFsMountpoint string) *runtimeapi.ContainerStats {
containerStats := &runtimeapi.ContainerStats{
Attributes: &runtimeapi.ContainerAttributes{
Id: container.ContainerStatus.Id,
......@@ -300,7 +300,7 @@ func makeFakeContainerStats(container *critest.FakeContainer, imageFsUUID string
},
WritableLayer: &runtimeapi.FilesystemUsage{
Timestamp: time.Now().UnixNano(),
StorageId: &runtimeapi.StorageIdentifier{Uuid: imageFsUUID},
FsId: &runtimeapi.FilesystemIdentifier{Mountpoint: imageFsMountpoint},
UsedBytes: &runtimeapi.UInt64Value{Value: rand.Uint64() / 100},
InodesUsed: &runtimeapi.UInt64Value{Value: rand.Uint64() / 100},
},
......@@ -321,10 +321,10 @@ func makeFakeContainerStats(container *critest.FakeContainer, imageFsUUID string
return containerStats
}
func makeFakeImageFsUsage(fsUUID string) *runtimeapi.FilesystemUsage {
func makeFakeImageFsUsage(fsMountpoint string) *runtimeapi.FilesystemUsage {
return &runtimeapi.FilesystemUsage{
Timestamp: time.Now().UnixNano(),
StorageId: &runtimeapi.StorageIdentifier{Uuid: fsUUID},
FsId: &runtimeapi.FilesystemIdentifier{Mountpoint: fsMountpoint},
UsedBytes: &runtimeapi.UInt64Value{Value: rand.Uint64()},
InodesUsed: &runtimeapi.UInt64Value{Value: rand.Uint64()},
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment