Skip to content

Commit 8562b14

Browse files
Merge pull request #17 from almaslennikov/config-during-discovery
Allow --user-config during discovery to supply base config
2 parents 644d2cb + b48d48d commit 8562b14

File tree

3 files changed

+47
-29
lines changed

3 files changed

+47
-29
lines changed

README.md

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,11 +90,11 @@ Flags:
9090
--network-operator-namespace string Override the network operator namespace from the config file
9191
--number-of-planes int Number of planes for Spectrum-X (requires --spectrum-x)
9292
--prompt string Path to file with a prompt to use for LLM-assisted profile generation
93-
--save-cluster-config string Save discovered cluster configuration to the specified path (default "/opt/nvidia/k8s-launch-kit/cluster-config.yaml")
93+
--save-cluster-config string Save discovered cluster configuration to the specified path (defaults to --user-config path if set, otherwise /opt/nvidia/k8s-launch-kit/cluster-config.yaml)
9494
--save-deployment-files string Save generated deployment files to the specified directory (default "/opt/nvidia/k8s-launch-kit/deployment")
9595
--spcx-version string Spectrum-X firmware version (requires --spectrum-x)
9696
--spectrum-x Enable Spectrum X deployment
97-
--user-config string Use provided cluster configuration file instead of auto-discovery (skips cluster discovery)
97+
--user-config string Use provided cluster configuration file (as base config for discovery or as full config without discovery)
9898
9999
Use "l8k [command] --help" for more information about a command.
100100
```
@@ -129,6 +129,23 @@ l8k --discover-cluster-config --save-cluster-config ./my-cluster-config.yaml \
129129
--kubeconfig ~/.kube/config
130130
```
131131

132+
### Discovery with User-Provided Base Config
133+
134+
Use your own config file (with custom network operator version, subnets, etc.) as the base for discovery. Without `--save-cluster-config`, the file is rewritten in place with discovery results:
135+
136+
```bash
137+
l8k --user-config ./my-config.yaml --discover-cluster-config \
138+
--kubeconfig ~/.kube/config
139+
```
140+
141+
Save discovery results to a separate file instead:
142+
143+
```bash
144+
l8k --user-config ./my-config.yaml --discover-cluster-config \
145+
--save-cluster-config ./discovered-config.yaml \
146+
--kubeconfig ~/.kube/config
147+
```
148+
132149
### Use Existing Configuration
133150

134151
Generate and deploy with pre-existing config:
@@ -169,7 +186,7 @@ l8k --user-config ./config.yaml \
169186

170187
## Configuration file
171188

172-
During cluster discovery stage, Kubernetes Launch Kit creates a configuration file, which it later uses to generate deployment manifests from the templates. This config file can be edited by the user to customize their deployment configuration. The user can provide the custom config file to the tool using the `--user-config` cli flag.
189+
During cluster discovery stage, Kubernetes Launch Kit creates a configuration file, which it later uses to generate deployment manifests from the templates. This config file can be edited by the user to customize their deployment configuration. The user can provide the custom config file to the tool using the `--user-config` cli flag — either as a standalone config (skipping discovery) or as a base config combined with `--discover-cluster-config` (discovery takes network operator parameters from the file and adds discovered cluster config).
173190

174191
Example of the configuration file discovered from the cluster:
175192

pkg/app/launcher.go

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -280,21 +280,18 @@ func (l *Launcher) executeWorkflow() error {
280280

281281
// discoverClusterConfig handles cluster configuration discovery
282282
func (l *Launcher) discoverClusterConfig() error {
283-
if l.options.UserConfig != "" {
284-
l.ui.Info("Using provided configuration: %s", l.options.UserConfig)
285-
l.logger.Info("Using provided user config", "path", l.options.UserConfig)
286-
// TODO: Validate and load user config file
287-
return nil
288-
}
289-
290283
l.ui.Info("Discovering cluster capabilities")
291284
l.logger.Info("Discovering cluster configuration")
292285

293-
// Load defaults from l8k-config.yaml (temporary default path)
286+
// Load base config: from --user-config if provided, otherwise from built-in defaults
294287
defaultsPath := "l8k-config.yaml"
288+
if l.options.UserConfig != "" {
289+
defaultsPath = l.options.UserConfig
290+
l.ui.Info("Using base configuration: %s", defaultsPath)
291+
}
295292
defaults, err := config.LoadFullConfig(defaultsPath, l.logger)
296293
if err != nil {
297-
return fmt.Errorf("failed to load default config from %s: %w", defaultsPath, err)
294+
return fmt.Errorf("failed to load base config from %s: %w", defaultsPath, err)
298295
}
299296

300297
// Override namespace from CLI flag if provided
@@ -317,26 +314,35 @@ func (l *Launcher) discoverClusterConfig() error {
317314

318315
discoveredConfig := *defaults
319316

320-
// Ensure output path provided
321-
if l.options.SaveClusterConfig == "" {
322-
return fmt.Errorf("no output path provided for discovered cluster config (use --discover-cluster-config)")
317+
// Compute effective save path:
318+
// 1. --save-cluster-config if explicitly provided
319+
// 2. --user-config path (rewrite in place) if provided
320+
// 3. Default path as fallback
321+
savePath := l.options.SaveClusterConfig
322+
if savePath == "" {
323+
if l.options.UserConfig != "" {
324+
savePath = l.options.UserConfig
325+
} else {
326+
savePath = "/opt/nvidia/k8s-launch-kit/cluster-config.yaml"
327+
}
323328
}
329+
l.options.SaveClusterConfig = savePath
324330

325331
// Marshal and save merged config to disk
326332
data, err := yaml.Marshal(discoveredConfig)
327333
if err != nil {
328334
return fmt.Errorf("failed to marshal discovered config: %w", err)
329335
}
330-
if err := os.MkdirAll(filepath.Dir(l.options.SaveClusterConfig), 0755); err != nil {
331-
return fmt.Errorf("failed to create output directory %s: %w", filepath.Dir(l.options.SaveClusterConfig), err)
336+
if err := os.MkdirAll(filepath.Dir(savePath), 0755); err != nil {
337+
return fmt.Errorf("failed to create output directory %s: %w", filepath.Dir(savePath), err)
332338
}
333-
if err := os.WriteFile(l.options.SaveClusterConfig, data, 0644); err != nil {
339+
if err := os.WriteFile(savePath, data, 0644); err != nil {
334340
l.ui.Error("Failed to save configuration: %v", err)
335-
return fmt.Errorf("failed to write discovered config to %s: %w", l.options.SaveClusterConfig, err)
341+
return fmt.Errorf("failed to write discovered config to %s: %w", savePath, err)
336342
}
337343

338-
l.ui.Success("Configuration saved: %s", l.options.SaveClusterConfig)
339-
l.logger.Info("Discovered cluster config saved", "path", l.options.SaveClusterConfig)
344+
l.ui.Success("Configuration saved: %s", savePath)
345+
l.logger.Info("Discovered cluster config saved", "path", savePath)
340346
return nil
341347
}
342348

pkg/cmd/root.go

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -156,8 +156,8 @@ func init() {
156156

157157
// Phase 1: Cluster discovery flags
158158
rootCmd.Flags().BoolVar(&discoverClusterConfig, "discover-cluster-config", false, "Deploy a thin Network Operator profile to discover cluster capabilities")
159-
rootCmd.Flags().StringVar(&saveClusterConfig, "save-cluster-config", "/opt/nvidia/k8s-launch-kit/cluster-config.yaml", "Save discovered cluster configuration to the specified path")
160-
rootCmd.Flags().StringVar(&userConfig, "user-config", "", "Use provided cluster configuration file instead of auto-discovery (skips cluster discovery)")
159+
rootCmd.Flags().StringVar(&saveClusterConfig, "save-cluster-config", "", "Save discovered cluster configuration to the specified path (defaults to --user-config path if set, otherwise /opt/nvidia/k8s-launch-kit/cluster-config.yaml)")
160+
rootCmd.Flags().StringVar(&userConfig, "user-config", "", "Use provided cluster configuration file (as base config for discovery or as full config without discovery)")
161161
rootCmd.Flags().StringVar(&networkOperatorNamespace, "network-operator-namespace", "", "Override the network operator namespace from the config file")
162162

163163
// Phase 2: Deployment generation flags
@@ -195,16 +195,11 @@ func validateConfig(options options.Options) error {
195195
return fmt.Errorf("no plugins enabled, use --enabled-plugins to enable plugins")
196196
}
197197

198-
// Either user-config or discover-cluster-config should be provided
198+
// At least one of user-config or discover-cluster-config should be provided
199199
if options.UserConfig == "" && !options.DiscoverClusterConfig {
200200
return fmt.Errorf("either --user-config or --discover-cluster-config must be provided")
201201
}
202202

203-
// Both user-config and discover-cluster-config cannot be provided together
204-
if options.UserConfig != "" && options.DiscoverClusterConfig {
205-
return fmt.Errorf("--user-config and --discover-cluster-config cannot be used together")
206-
}
207-
208203
// If discover-cluster-config is provided, kubeconfig should be too
209204
if options.DiscoverClusterConfig && options.Kubeconfig == "" {
210205
return fmt.Errorf("--discover-cluster-config requires --kubeconfig to be specified")

0 commit comments

Comments
 (0)