lxkns

package module
v0.18.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 21, 2021 License: Apache-2.0 Imports: 26 Imported by: 0

README

Linux kernel Namespaces

…and Containers.

view manual PkgGoDev GitHub build and test Go Report Card

lxkns is a Golang package for discovering Linux kernel namespaces as well as mount points in mount namespaces. It then relates them to containers, where possible. In every nook and cranny of your Linux hosts.

Discovery can be operated as a stand-alone REST service (both web UI and JSON discovery results) or integrated into system diagnosis tools that need an unobstructed view on Linux-kernel namespaces.

For mount namespaces, lxkns finds mount points even in process-less mount namespaces (for instance, as utilized in "snap" technology). Our discovery engine even determines the visibility of mount points, taking different forms of "overmounting" into consideration.

Take a look at the comprehensive user (and developer) manual.

Or, watch the short overview video how to find your way around discovery web frontend:

lxkns web app

lxkns is Copyright 2020‒21 Harald Albrecht, and licensed under the Apache License, Version 2.0.

Documentation

Overview

Let goreportcard check us. Code generated by gen_version; DO NOT EDIT.

Package lxkns discovers Linux kernel namespaces of types cgroup, ipc, mount, net, pid, time, user, and uts. This package discovers namespaces not only when processes have joined them, but also when namespaces have been bind-mounted or are only referenced anymore by process file descriptors or within a hierarchy (PID and user only).

In case of PID and user namespaces, lxkns additionally discovers their hierarchies, except when running on a really ancient kernel before 4.9. Furthermore, for user namespaces the owning user ID and the owned namespaces will be discovered too. Time namespaces require a kernel 5.6 or later.

And finally, lxkns relates namespaces to the "leading" (or "root") processes joined to them; this relationship is basically derived for convenience from the process tree hierarchy. The kernel itself doesn't define any special relationship between namespaces and processes except for the "attachment" of processes joining namespaces.

The namespace discovery process can be controlled in several aspects, according to the range of discovery of namespace types and places to search namespaces for, according to the needs of API users of the lxkns package.

Discovery

A namespace discovery is just a single call to function lxkns.Discover(). It accepts option setters, such as lxkns.StandardDiscovery(), lxkns.WithMounts(), et cetera.

Additionally, there's a one-time support function call to reexec.CheckAction() required as early as possible in main().

import (
    "github.com/thediveo/gons/reexec"
    "github.com/thediveo/lxkns"
)

func main() {
    reexec.CheckAction()
    ...
    allns := lxkns.Discover(lxkns.StandardDiscovery())
    ...
}

Technical note: in order to discover namespaces in some locations, such as bind-mounted namespaces, lxkns needs to fork the process it used from in, in order to switch the forked copy into other mount namespaces for further discovery. In order to implement this mechanism as painless as possible, process using lxkns need to call reexec.CheckAction() as early as possible from their main().

Basics of the lxkns Information Model

Not totally unexpectedly, the lxkns discovery information model at its most basic level comprises ... namespaces. In the previous code snippet, the information model returned is stored in the "allns" variable for further processing. The result organizes the namespaces found by type. For instance, the following code snippet prints all namespaces, sorted first by type and then by namespace identifier:

// Iterate over all 7 types of Linux-kernel namespaces, then over all
// namespaces of a given type...
for nsidx := range allns.Namespaces {
    for _, ns := range allns.SortedNamespaces(lxkns.NamespaceTypeIndex(nsidx)) {
        println(ns.Type().Name(), ns.ID().Ino)
    }
}

Because namespaces have no order defined, the discovery results "list" the namespaces in per-type maps, indexed by namespace identifiers. For convenience, SortedNamespaces() returns the namespaces of a specific type in a slice instead of a map, sorted numerically by the namespace identifiers (that is, sorting by inode numbers, ignoring dev IDs at this time).

Technically, these namespace identifiers are tuples consisting of 64bit unsigned inode numbers and (~64bit) device ID numbers, and come from the special "nsfs" namespace filesystem integrated with the Linux kernel. And before someone tries: nope, the nsfs cannot be mounted; and it even does not appear in the kernel's list of namespaces.

Unprivileged Discovery and How To Not Panic

While it is possible to discover namespaces without root privileges, this won't return the full set of namespaces in a Linux host. The reason is that while an unprivileged discovery is allowed to see some basic information about all processes in the system, it is not allowed to query the namespaces such privileged processes are joined too. In addition, an unprivileged discovery may turn up namespaces (for instance, when bind-mounted) for which the identifier is discovered, but further information, such as the parent or child namespaces for PID and user namespaces, is undiscoverable.

Users of the lxkns information model thus must be prepared to handle incomplete information yielded by unprivileged lxkns.Discover() calls. In particular, applications must be prepared to handle:

  • more than a single "initial" namespace per type of namespace,
  • PID and user namespaces without a parent namespace,
  • namespaces without owning user namespaces,
  • processes not related to any namespace.

In consequence, always check interface values and pointers for nil values like a pro. You can find many examples in the sources for the "lsuns", "lspidns", and "pidtree" CLI tools (inside the cmd sub-package).

In-Capabilities

It is possible to run full discoveries without being root, when given the discovery process the following effective capabilities:

  • CAP_SYS_PTRACE -- no joking here, that's what needed for reading namespace references from /proc/[PID]/ns/*
  • CAP_SYS_CHROOT -- for mount namespace switching
  • CAP_SYS_ADMIN -- for mount namespace switching
  • CAP_DAC_READ_SEARCH -- for reading details of bind-mounted namespaces

Considering that especially CAP_SYS_PTRACE being essential there's probably not much difference to "just be root" in the end, unless you want show off your "capabilities capabilities".

Namespace Hierarchies

PID and user namespaces form separate and independent namespaces hierarchies. This parent-child hierarchy is exposed through the lxkns.Hierarchy interface of the discovered namespaces.

Please note that lxkns represents namespaces often using the lxkns.Namespace interface when the specific type of namespace doesn't matter. In case of PID and user-type namespaces an lxkns.Namespace can be "converted" into an interface value of type lxkns.Hierarchy using a type assertion, in order to access the particular namespace hierarchy.

// If it's a PID or user namespace, then we can turn a "Namespace"
// into an "Hierarchy" in order to access hierarchy information.
if hns, ok := ns.(lxkns.Hierarchy); ok {
    if hns.Parent() != nil {
        ...
    }
    for _, childns := range hns.Children() {
        ...
    }
}

Ownership

User namespaces play the central role in controlling the access of processes to other namespaces as well as the capabilities process gain when allowed to join user namespaces. A comprehensive discussion of the rules and their ramifications is beyond this package documentation. For starters, please refer to the man page for user_namespaces(7), http://man7.org/linux/man-pages/man7/user_namespaces.7.html.

The controlling role of user namespaces show up in the discovery information model as owner-owneds relationships: user namespaces own non-user namespaces. And non-user namespaces are owned by user namespaces, the "ownings". In case you are now scratching your head "why the Gopher" the owned namespaces are referred to as "ownings": welcome to the wonderful Gopher world of "er"-ers, where interface method naming conventions create wonderful identifier art.

If a namespace interface value represents a user-type namespace, then it can be "converted" into an lxkns.Ownership interface value using a type assertion. This interface discloses which namespaces are owned by a particular user namespace. Please note that this does not include child user namespaces, use Hierarchy.Children() instead.

// Get the user namespace -owned-> namespaces relationships.
if owns, ok := ns.(lxkns.Ownership); ok {
    for _, ownedns := range owns.Ownings() {
        ...
    }
}

In the opposite direction, the owner of a namespace can be directly queried via the lxkns.Namespace interface (again, only for non-user namespaces):

// Get the namespace -owned by-> user namespace relationship.
ownerns := ns.Owner()

When asking a user namespace for its owner, the parent user namespace is returned in accordance with the Linux ioctl()s for discovering the ownership of namespaces.

Namespaces and Processes

The lxkns discovery information model also relates processes to namespaces, and vice versa. After all, processes are probably the main source for discovering namespaces.

For this reason, the discovery results (in "allns" in case of the above discovery code example) not only list the namespaces found, but also a snapshot of the process tree at discovery time (please relax now, as this is a snapshot of the "tree", not of all the processes themselves).

// Get the init(1) process representation.
initprocess := allns.Processes[lxkns.PIDType(1)]
for _, childprocess := range initprocess.Children() {
    ...
}

Please note that the process tree information is for convenience; it's not a replacement for the famous gopsutil package in many use cases. However, the process tree information show which namespaces are used by (or "joined by") which particular processes.

// Show all namespaces joined by a specific process, such as init(1).
for nsidx := lxkns.MountNS; nsidx < lxkns.NamespaceTypesCount; nsidx++ {
    println(initprocess.Namespaces[nsidx].String())
}

It's also possible, given a specific namespace, to find the processes joined to this namespace. However, the lxkns information model optimizes this relationship information on the assumption that in many situations not the list of all processes joined to a namespace is needed, but actually only the so-called "leader" process or processes.

A leader process of namespace X is the process topmost in the process tree hierarchy of processes joined to namespace X. It is perfectly valid for a namespace to have more than one leader process joined to it. An example is a container with its own processes joined to the container namespaces, and an additional "visiting" process also joined to one or several namespaces of this container. The lxkns information then is able to correctly handle and represent such system states.

// Show the leader processes joined to the initial user namespace.
for _, leaders := range initprocess.Namespaces[lxkns.UserNS].Leaders() {
    ...
}

Architecture

Please find more details about the lxkns information model in the architectural documents: https://github.com/TheDiveO/lxkns/blob/master/docs/architecture.md.

Index

Constants

View Source
const SemVersion = "0.18.1"

SemVersion is the semantic version string of the lxkns module.

Variables

This section is empty.

Functions

func MountEnterNamespaces added in v0.15.6

func MountEnterNamespaces(
	mntns model.Namespace, namespaces model.AllNamespaces) []model.Namespace

MountEnterNamespaces takes a mount namespace to be entered and returns the namespaces which need to be specified to ReexecIntoAction. It takes into account if first entering the correct user namespace might allow to enter the desired mount namespace even without having the necessary effective capabilities right now, but we could gain them by entering the user namespace first.

func NewPIDMap added in v0.9.0

func NewPIDMap(result *DiscoveryResult) model.PIDMapper

NewPIDMap returns a new PID map (PIDMapper) based on the specified discovery results and further information gathered from the /proc filesystem.

func ReexecIntoAction added in v0.9.0

func ReexecIntoAction(actionname string, namespaces []model.Namespace, result interface{}) (err error)

ReexecIntoAction forks and then re-executes this process in order to run a specific action (indicated by actionname) in a set of (different) Linux kernel namespaces. The stdout result of running the action is then deserialized as JSON into the specified result element.

func ReexecIntoActionEnv added in v0.9.0

func ReexecIntoActionEnv(actionname string, namespaces []model.Namespace, envvars []string, result interface{}) (err error)

ReexecIntoActionEnv forks and then re-executes this process in order to run a specific action (indicated by actionname) in a set of (different) Linux kernel namespaces. It also passes the additional environment variables specified in envvars. The stdout result of running the action is then deserialized as JSON into the specified result element.

func SortChildNamespaces added in v0.9.0

func SortChildNamespaces(nslist []model.Hierarchy) []model.Hierarchy

SortChildNamespaces returns a sorted copy of a list of hierarchical namespaces. The namespaces are sorted by their namespace ids in ascending order. Please note that the list itself is flat, but this function can only be used on hierarchical namespaces (PID, user).

func SortNamespaces added in v0.9.0

func SortNamespaces(nslist []model.Namespace) []model.Namespace

SortNamespaces returns a sorted copy of a list of namespaces. The namespaces are sorted by their namespace ids in ascending order.

func SortedNamespaces added in v0.9.0

func SortedNamespaces(nsmap model.NamespaceMap) []model.Namespace

SortedNamespaces returns the namespaces from a map sorted.

Types

type BindmountedNamespaceInfo added in v0.11.0

type BindmountedNamespaceInfo struct {
	ID        species.NamespaceID   `json:"id"`
	Type      species.NamespaceType `json:"type"`
	Path      string                `json:"path"`
	OwnernsID species.NamespaceID   `json:"ownernsid"`
	Log       []string              `json:"log"` // not strictly necessary, yet very helpful.
}

BindmountedNamespaceInfo describes a bind-mounted namespace in some (other) mount namespace, including the owning user namespace ID, so we can later correctly set up the ownership relations in the discovery results.

type DiscoverOpts added in v0.9.0

type DiscoverOpts struct {
	// The types of namespaces discovered: this is an OR'ed combination of Linux
	// kernel namespace constants, such as CLONE_NEWNS, CLONE_NEWNET, et cetera.
	// If zero, defaults to discovering all namespaces.
	NamespaceTypes species.NamespaceType `json:"-"`

	ScanProcs            bool `json:"from-procs"`      // Scan processes for attached namespaces.
	ScanFds              bool `json:"from-fds"`        // Scan open file descriptors for namespaces.
	ScanBindmounts       bool `json:"from-bindmounts"` // Scan bind-mounts for namespaces.
	DiscoverHierarchy    bool `json:"with-hierarchy"`  // Discover the hierarchy of PID and user namespaces.
	DiscoverOwnership    bool `json:"with-ownership"`  // Discover the ownership of non-user namespaces.
	DiscoverFreezerState bool `json:"with-freezer"`    // Discover the cgroup freezer state of processes.
	DiscoverMounts       bool `json:"with-mounts"`     // Discover mount point hierarchy with mount paths and visibility.

	Containerizer containerizer.Containerizer `json:"-"` // Discover containers using containerizer.
}

DiscoverOpts provides information about the extent of a Linux-kernel namespace discovery.

This information is JSON-marshallable, with the exception of the Containerizer interface.

type DiscoveryOption added in v0.18.0

type DiscoveryOption func(*DiscoverOpts)

DiscoveryOption represents a function able to set a particular discovery option state in DiscoverOpts.

func FromBindmounts added in v0.18.0

func FromBindmounts() DiscoveryOption

FromBindmounts opts to find bind-mounted namespaces.

func FromFds added in v0.18.0

func FromFds() DiscoveryOption

FromFds opts to find namespaces from the open file descriptors of processes.

func FromProcs added in v0.18.0

func FromProcs() DiscoveryOption

FromProcs opts to find namespaces attached to processes.

func NotFromBindmounts added in v0.18.0

func NotFromBindmounts() DiscoveryOption

NotFromBindmounts opts out from searching for bind-mounted namespaces.

func NotFromFds added in v0.18.0

func NotFromFds() DiscoveryOption

NotFromFds opts out looking at the open file descriptors of processes when searching for namespaces.

func NotFromProcs added in v0.18.0

func NotFromProcs() DiscoveryOption

NotFromProcs opts out of looking at processes when searching for namespaces.

func SameAs added in v0.18.0

SameAs reuses the discovery options used for a previous discovery.

func WithContainerizer added in v0.18.0

func WithContainerizer(c containerizer.Containerizer) DiscoveryOption

WithContainerizer opts for discovery of containers related to namespaces, using the specified Containerizer.

func WithFullDiscovery added in v0.18.0

func WithFullDiscovery() DiscoveryOption

WithFullDiscovery opts in to all discovery features that lxkns has to offer. Please note that API users still need to set an optional Containerizer explicitly.

func WithHierarchy added in v0.18.0

func WithHierarchy() DiscoveryOption

WithHierarchy opts to query the namespace hierarchy of PID and user namespaces.

func WithMounts added in v0.18.0

func WithMounts() DiscoveryOption

WithMounts opts to find mount points and determine their visibility.

func WithNamespaceTypes added in v0.18.0

func WithNamespaceTypes(t species.NamespaceType) DiscoveryOption

WithNamespaceTypes sets the types of namespaces to discover, where multiple types need to be OR'ed together. Setting 0 will discover all available types.

func WithOwnership added in v0.18.0

func WithOwnership() DiscoveryOption

WithOwnership opts to find the ownership relations between user namespaces and all other namespaces.

func WithStandardDiscovery added in v0.18.0

func WithStandardDiscovery() DiscoveryOption

WithStandardDiscovery opts for a "standard" discovery, scanning not only processes, but also open file descriptors and bind-mounts, as well as the namespace hierarchy and ownership, and freezer states. All types of namespaces will be discovered. Please note that time namespaces can only be discovered on newer kernels with support for them.

Please note that mount point discovery (including visibility calculation) it not opted in; it has to be opted in individually.

func WithoutHierarchy added in v0.18.0

func WithoutHierarchy() DiscoveryOption

WithoutHierarchy opts out of querying the namespace hierarchy of PID and user namespaces.

func WithoutMounts added in v0.18.0

func WithoutMounts() DiscoveryOption

WithoutMounts opts out of finding mount points and determining their visibility.

func WithoutOwnership added in v0.18.0

func WithoutOwnership() DiscoveryOption

WithoutOwnership opts out of looking for the ownership relations between user namespaces and all other namespaces.

type DiscoveryResult added in v0.9.0

type DiscoveryResult struct {
	Options           DiscoverOpts           // options used during discovery.
	Namespaces        model.AllNamespaces    // all discovered namespaces, subject to filtering according to Options.
	InitialNamespaces model.NamespacesSet    // the 7 initial namespaces.
	UserNSRoots       []model.Namespace      // the topmost user namespace(s) in the hierarchy.
	PIDNSRoots        []model.Namespace      // the topmost PID namespace(s) in the hierarchy.
	Processes         model.ProcessTable     // processes checked for namespaces.
	Mounts            NamespacedMountPathMap // per mount-namespace mount paths and mount points.
	Containers        []*model.Container     // all alive containers found
}

DiscoveryResult stores the results of a tour through Linux processes and kernel namespaces.

func Discover added in v0.9.0

func Discover(options ...DiscoveryOption) *DiscoveryResult

Discover returns the Linux kernel namespaces found, based on discovery options specified in the call. The discovery results also specify the initial namespaces, as well the process table/tree on which the discovery bases at least in part.

func (*DiscoveryResult) SortedNamespaces added in v0.9.0

func (dr *DiscoveryResult) SortedNamespaces(nsidx model.NamespaceTypeIndex) []model.Namespace

SortedNamespaces returns a sorted list of discovered namespaces of the specified type. The namespaces are sorted by their identifier, which is an inode number (on the special "nsfs" filesystem), ignoring a namespace's device ID.

type NamespacedMountPathMap added in v0.17.0

type NamespacedMountPathMap map[species.NamespaceID]mounts.MountPathMap

NamespacedMountPathMap maps mount namespaces identified by their namespace ID to their corresponding mount path maps.

type UidUsernameMap added in v0.15.6

type UidUsernameMap map[uint32]string

UidUsernameMap maps user identifiers (uids) to their corresponding user names, if any.

func DiscoverUserNames added in v0.15.6

func DiscoverUserNames(namespaces model.AllNamespaces) UidUsernameMap

DiscoverUserNames returns the mapping from user identifiers (uids, found as owners of user namespaces) to their corresponding user names, if any. The namespaces information is required so that the information can be discovered from the initial mount namespace of the host.

Directories

Path Synopsis
api
types
Package types defines the common types for (un)marshalling elements of the lxkns information model from/to JSON.
Package types defines the common types for (un)marshalling elements of the lxkns information model from/to JSON.
cmd
dumpns
dumpns runs a namespace (and process) discovery and then dumps the results as JSON.
dumpns runs a namespace (and process) discovery and then dumps the results as JSON.
internal/pkg/cli
Package cli handles registering CLI flags via a plug-in mechanism.
Package cli handles registering CLI flags via a plug-in mechanism.
internal/pkg/filter
Package filter provides CLI-controlled filtering of namespaces by type.
Package filter provides CLI-controlled filtering of namespaces by type.
internal/pkg/style
Package style styles text output of the CLI commands with foreground and background colors, as well as different text styles (bold, italics, ...).
Package style styles text output of the CLI commands with foreground and background colors, as well as different text styles (bold, italics, ...).
internal/test/getstdout
Package getstdout captures os.Stdout and os.Stderr while executing a specified function, returning the captured output afterwards.
Package getstdout captures os.Stdout and os.Stderr while executing a specified function, returning the captured output afterwards.
lspidns
lspidns lists the tree of PID namespaces, optionally with their owning user namespaces.
lspidns lists the tree of PID namespaces, optionally with their owning user namespaces.
lsuns
lsuns lists the tree of user namespaces, optionally with the other namespaces they own.
lsuns lists the tree of user namespaces, optionally with the other namespaces they own.
nscaps
nscaps determines a process' capabilities in some namespace.
nscaps determines a process' capabilities in some namespace.
pidtree
pidtree displays a tree (or only a single branch) of processes together with their PID namespaces, and additionally also shows the local PIDs of processes (where applicable).
pidtree displays a tree (or only a single branch) of processes together with their PID namespaces, and additionally also shows the local PIDs of processes (where applicable).
Package containerizer provides the implementations to store data about Containers and ContainerEngines.
Package containerizer provides the implementations to store data about Containers and ContainerEngines.
whalefriend
Package whalefriend implements a Containerizer that discovers containers from container engines supported by the github.com/thediveo/whalewatcher module, such as Docker and containerd (moby & friends).
Package whalefriend implements a Containerizer that discovers containers from container engines supported by the github.com/thediveo/whalewatcher module, such as Docker and containerd (moby & friends).
Package decorator defines the Decorator plug-in interface, where Decorators adorn the container information model with additional data, such as container grouping and unified pod-related container labels.
Package decorator defines the Decorator plug-in interface, where Decorators adorn the container information model with additional data, such as container grouping and unified pod-related container labels.
all
Package all imports and activates all lxkns (container) decorator plugins, activating them during discoveries.
Package all imports and activates all lxkns (container) decorator plugins, activating them during discoveries.
composer
Package composer decorates lxkns information models with (Docker) Composer project groups.
Package composer decorates lxkns information models with (Docker) Composer project groups.
industrialedge
Package industrialedge decorates the composer-project flavor of Siemens Industrial Edge apps when an IE App project is detected.
Package industrialedge decorates the composer-project flavor of Siemens Industrial Edge apps when an IE App project is detected.
kuhbernetes
Package kuhbernetes provides Decorators for "recovering" Kubernetes pods from the containers found.
Package kuhbernetes provides Decorators for "recovering" Kubernetes pods from the containers found.
kuhbernetes/cricontainerd
Package cricontainerd decorates Kubernetes pod groups discovered from CRI-managed containers, based on their CRI-related labels.
Package cricontainerd decorates Kubernetes pod groups discovered from CRI-managed containers, based on their CRI-related labels.
kuhbernetes/dockershim
Package dockershim decorates Kubernetes pod groups discovered from Docker container names managed by the (in)famous Docker shim.
Package dockershim decorates Kubernetes pod groups discovered from Docker container names managed by the (in)famous Docker shim.
examples
internal
log
Package log allows consumers of the lxkns module to forward logging originating in the lxkns module to whatever logger module they prefer.
Package log allows consumers of the lxkns module to forward logging originating in the lxkns module to whatever logger module they prefer.
logrus
Package logrus enables logging within the lxkns module and directs all logging output to the sirupsen/logrus logging module.
Package logrus enables logging within the lxkns module and directs all logging output to the sirupsen/logrus logging module.
Package model defines the core of lxkns information model: Linux kernel namespaces and processes, and how they relate to each other; with the additional missing link between processes and user-land containers.
Package model defines the core of lxkns information model: Linux kernel namespaces and processes, and how they relate to each other; with the additional missing link between processes and user-land containers.
Package mounts enhances the Linux kernel's mountinfo data model ("/proc/[PID]/mountinfo") with mount point visibility ("overmounts") and a hierarchical mount path tree.
Package mounts enhances the Linux kernel's mountinfo data model ("/proc/[PID]/mountinfo") with mount point visibility ("overmounts") and a hierarchical mount path tree.
Package nstest provides testing support in the context of Linux kernel namespaces.
Package nstest provides testing support in the context of Linux kernel namespaces.
gmodel
Package gmodel provides Gomega matches for lxkns model elements.
Package gmodel provides Gomega matches for lxkns model elements.
ops
Package ops provides a Golang-idiomatic API to the query and switching operations on Linux-kernel namespaces, hiding ioctl()s and syscalls.
Package ops provides a Golang-idiomatic API to the query and switching operations on Linux-kernel namespaces, hiding ioctl()s and syscalls.
internal/opener
Package opener provides access to the file descriptors of namespace references.
Package opener provides access to the file descriptors of namespace references.
portable
Package portable provides so-called "portable" namespace references with validation and "locking" (keeping the referenced namespace open and thus alive).
Package portable provides so-called "portable" namespace references with validation and "locking" (keeping the referenced namespace open and thus alive).
relations
Package relations gives access to properties of and relationships between Linux-kernel namespaces, such as type and ID of a namespace, its owning user namespace, parent namespace in case of hierarchical namespaces, et cetera.
Package relations gives access to properties of and relationships between Linux-kernel namespaces, such as type and ID of a namespace, its owning user namespace, parent namespace in case of hierarchical namespaces, et cetera.
Package plural supplies lxkns with (only) English-language plurals for common objects appearing in the lxkns information model.
Package plural supplies lxkns with (only) English-language plurals for common objects appearing in the lxkns information model.
Package species defines the type constants and type names of the 8 Linux kernel namespace types ("species").
Package species defines the type constants and type names of the 8 Linux kernel namespace types ("species").
test
containerdtest
Package containerdtest is a poor-man's dockertest.
Package containerdtest is a poor-man's dockertest.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL