Skip to content

Commit bdfbe27

Browse files
committed
Add support for drop-in config files in a container
This change adds support for drop-in files in a container. Here the user needs to set RUNTIME_DROP_IN_CONFIG_HOST_PATH in addition to RUNTIME_DROP_IN_CONFIG. In this case when updating the top-level containerd config, the imports will use the host path instead of the container path. Signed-off-by: Evan Lezar <[email protected]>
1 parent 96050da commit bdfbe27

File tree

6 files changed

+47
-7
lines changed

6 files changed

+47
-7
lines changed

cmd/nvidia-ctk-installer/container/container.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@ const (
3535

3636
// Options defines the shared options for the CLIs to configure containers runtimes.
3737
type Options struct {
38-
DropInConfig string
38+
DropInConfig string
39+
DropInConfigHostPath string
3940
// TODO: Rename to TopLevelConfig
4041
Config string
4142
Socket string

cmd/nvidia-ctk-installer/container/runtime/containerd/containerd.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ package containerd
1919
import (
2020
"encoding/json"
2121
"fmt"
22+
"path/filepath"
2223

2324
log "github.com/sirupsen/logrus"
2425
cli "github.com/urfave/cli/v3"
@@ -173,6 +174,7 @@ func GetLowlevelRuntimePaths(o *container.Options, co *Options) ([]string, error
173174
func getRuntimeConfig(o *container.Options, co *Options) (engine.Interface, error) {
174175
return containerd.New(
175176
containerd.WithTopLevelConfigPath(o.Config),
177+
containerd.WithContainerPathAsHostPath(filepath.Dir(o.DropInConfig), filepath.Dir(o.DropInConfigHostPath)),
176178
containerd.WithConfigSource(
177179
toml.LoadFirst(
178180
containerd.CommandLineSource(o.HostRootMount, o.ExecutablePath),

cmd/nvidia-ctk-installer/container/runtime/runtime.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,13 @@ func Flags(opts *Options) []cli.Flag {
6161
Destination: &opts.DropInConfig,
6262
Sources: cli.EnvVars("RUNTIME_DROP_IN_CONFIG"),
6363
},
64+
&cli.StringFlag{
65+
Name: "drop-in-config-host-path",
66+
Usage: "When running in a container, this is the path to the drop-in config (--drop-in-config) on the host. " +
67+
"This is required to correctly update the top-level config if required since paths there must be host-relative.",
68+
Destination: &opts.DropInConfigHostPath,
69+
Sources: cli.EnvVars("RUNTIME_DROP_IN_CONFIG_HOST_PATH"),
70+
},
6471
&cli.StringFlag{
6572
Name: "executable-path",
6673
Usage: "The path to the runtime executable. This is used to extract the current config",

pkg/config/engine/containerd/config_drop_in.go

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,12 @@ var _ engine.Interface = (*ConfigWithDropIn)(nil)
3737
// A topLevelConfig stores the original on-disk top-level config.
3838
// The path to the config is also stored to allow it to be modified if required.
3939
type topLevelConfig struct {
40-
path string
41-
config *Config
40+
path string
41+
containerToHostPathMap map[string]string
42+
config *Config
4243
}
4344

44-
func NewConfigWithDropIn(topLevelConfigPath string, tlConfig *Config, dropInConfig engine.Interface) *ConfigWithDropIn {
45+
func NewConfigWithDropIn(topLevelConfigPath string, containerToHostPathMap map[string]string, tlConfig *Config, dropInConfig engine.Interface) *ConfigWithDropIn {
4546
return &ConfigWithDropIn{
4647
topLevelConfig: &topLevelConfig{
4748
path: topLevelConfigPath,
@@ -117,13 +118,27 @@ func (c *topLevelConfig) removeImports(dropInFilename string) {
117118
return
118119
}
119120

120-
requiredImport := filepath.Dir(dropInFilename) + "/*.toml"
121+
requiredImport := c.importPattern(dropInFilename)
121122
if currentImports[0] != requiredImport {
122123
return
123124
}
124125
c.config.Delete("imports")
125126
}
126127

128+
func (c *topLevelConfig) importPattern(dropInFilename string) string {
129+
return c.asHostPath(filepath.Dir(dropInFilename)) + "/*.toml"
130+
}
131+
132+
func (c *topLevelConfig) asHostPath(path string) string {
133+
if c.containerToHostPathMap == nil {
134+
return path
135+
}
136+
if hostPath, ok := c.containerToHostPathMap[path]; ok {
137+
return hostPath
138+
}
139+
return path
140+
}
141+
127142
// removeVersion removes the version if it is the ONLY field in the file.
128143
func (c *topLevelConfig) removeVersion() {
129144
if len(c.config.Keys()) > 1 {
@@ -142,7 +157,7 @@ func (c *topLevelConfig) ensureImports(dropInFilename string) {
142157
currentImports = ci
143158
}
144159

145-
requiredImport := filepath.Dir(dropInFilename) + "/*.toml"
160+
requiredImport := c.importPattern(dropInFilename)
146161
for _, currentImport := range currentImports {
147162
// If the requiredImport is already present, then we need not update the config.
148163
if currentImport == requiredImport {

pkg/config/engine/containerd/containerd.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ func New(opts ...Option) (engine.Interface, error) {
141141
},
142142
}
143143

144-
cfg := NewConfigWithDropIn(b.topLevelConfigPath, topLevelConfig, dropInConfig)
144+
cfg := NewConfigWithDropIn(b.topLevelConfigPath, b.containerToHostPathMap, topLevelConfig, dropInConfig)
145145
return cfg, nil
146146
}
147147
}

pkg/config/engine/containerd/option.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,26 @@ type builder struct {
2929
topLevelConfigPath string
3030
runtimeType string
3131
containerAnnotations []string
32+
33+
containerToHostPathMap map[string]string
3234
}
3335

3436
// Option defines a function that can be used to configure the config builder
3537
type Option func(*builder)
3638

39+
// WithContainerPathAsHostPath maps a given container path to a host path.
40+
func WithContainerPathAsHostPath(containerPath string, hostPath string) Option {
41+
return func(b *builder) {
42+
if containerPath == "" || hostPath == "" || containerPath == hostPath {
43+
return
44+
}
45+
if b.containerToHostPathMap == nil {
46+
b.containerToHostPathMap = make(map[string]string)
47+
}
48+
b.containerToHostPathMap[containerPath] = hostPath
49+
}
50+
}
51+
3752
// WithLogger sets the logger for the config builder
3853
func WithLogger(logger logger.Interface) Option {
3954
return func(b *builder) {

0 commit comments

Comments
 (0)