mirror of
https://github.com/gitpod-io/gitpod.git
synced 2025-12-08 17:36:30 +00:00
92 lines
2.1 KiB
Go
92 lines
2.1 KiB
Go
// Copyright (c) 2020 Gitpod GmbH. All rights reserved.
|
|
// Licensed under the GNU Affero General Public License (AGPL).
|
|
// See License.AGPL.txt in the project root for license information.
|
|
|
|
package container
|
|
|
|
import (
|
|
"bufio"
|
|
"os"
|
|
"strings"
|
|
|
|
"golang.org/x/xerrors"
|
|
)
|
|
|
|
// NewNodeMountsLookup produces a new node mounts lookup after validating the configuration
|
|
func NewNodeMountsLookup(cfg *NodeMountsLookupConfig) (*NodeMountsLookup, error) {
|
|
if cfg == nil {
|
|
return nil, xerrors.Errorf("config must not be nil")
|
|
}
|
|
|
|
return &NodeMountsLookup{cfg}, nil
|
|
}
|
|
|
|
// NodeMountsLookup interogates the node-level (root mount namespace) mount table and maps
|
|
// those paths to the container running this process.
|
|
type NodeMountsLookup struct {
|
|
Config *NodeMountsLookupConfig
|
|
}
|
|
|
|
// GetMountpoint scans the mount table for a mount point and returns one if found
|
|
func (n *NodeMountsLookup) GetMountpoint(matcher func(mountPoint string) bool) (mountPoint string, err error) {
|
|
entry, err := n.getEntry(matcher)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
return entry[1], nil
|
|
}
|
|
|
|
// GetUpperdir finds the upperdir of an overlayfs mount by matching the mountpoint.
|
|
// The returned path exists in the node's root mount namespace.
|
|
func (n *NodeMountsLookup) GetUpperdir(matcher func(mountPoint string) bool) (upperdir string, err error) {
|
|
entry, err := n.getEntry(matcher)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
var pth string
|
|
segs := strings.Split(entry[3], ",")
|
|
for _, seg := range segs {
|
|
if !strings.HasPrefix(seg, "upperdir=") {
|
|
continue
|
|
}
|
|
|
|
pth = strings.TrimSpace(strings.TrimPrefix(seg, "upperdir="))
|
|
break
|
|
}
|
|
if pth == "" {
|
|
return "", ErrNoUpperdir
|
|
}
|
|
|
|
return pth, nil
|
|
}
|
|
|
|
func (n *NodeMountsLookup) getEntry(matcher func(mountPoint string) bool) (entry []string, err error) {
|
|
f, err := os.Open(n.Config.ProcLoc)
|
|
if err != nil {
|
|
return nil, xerrors.Errorf("cannot load node mounts: %w", err)
|
|
}
|
|
defer f.Close()
|
|
|
|
scanner := bufio.NewScanner(f)
|
|
for scanner.Scan() {
|
|
line := scanner.Text()
|
|
fields := strings.Fields(line)
|
|
|
|
if len(fields) < 4 {
|
|
continue
|
|
}
|
|
if fields[0] != "overlay" {
|
|
continue
|
|
}
|
|
if !matcher(fields[1]) {
|
|
continue
|
|
}
|
|
|
|
return fields, nil
|
|
}
|
|
|
|
return nil, ErrNotFound
|
|
}
|