(configFile, withSecretsPath string)
| 555 | } |
| 556 | |
| 557 | func applyOneFileDirectPatchMode(configFile, withSecretsPath string) error { |
| 558 | opts := buildApplyPatchOptions(withSecretsPath) |
| 559 | patches := []string{"@" + configFile} |
| 560 | |
| 561 | configBundle, machineType, err := engine.FullConfigProcess(opts, patches) |
| 562 | if err != nil { |
| 563 | //nolint:wrapcheck // already wrapped via errors.Wrap, WithHint adds operator-facing guidance |
| 564 | return errors.WithHint( |
| 565 | errors.Wrap(err, "full config processing"), |
| 566 | "the chart did not render or could not be combined with the supplied patches; check that the chart in scope and the patches reference fields that exist", |
| 567 | ) |
| 568 | } |
| 569 | |
| 570 | result, err := engine.SerializeConfiguration(configBundle, machineType) |
| 571 | if err != nil { |
| 572 | //nolint:wrapcheck // already wrapped via errors.Wrap, WithHint adds operator-facing guidance |
| 573 | return errors.WithHint( |
| 574 | errors.Wrap(err, "serializing configuration"), |
| 575 | "the merged config bundle could not be encoded back to YAML; this is internal — file an issue if reproducible", |
| 576 | ) |
| 577 | } |
| 578 | |
| 579 | return withApplyClient(func(ctx context.Context, c *client.Client) error { |
| 580 | targetNodes, err := resolveDirectPatchTargetNodes(c, configFile) |
| 581 | if err != nil { |
| 582 | return err |
| 583 | } |
| 584 | |
| 585 | // Progress line goes to stderr; stdout is reserved for rendered output. |
| 586 | fmt.Fprintf(os.Stderr, "- talm: file=%s, nodes=[%s], endpoints=[%s]\n", configFile, strings.Join(targetNodes, ","), strings.Join(GlobalArgs.Endpoints, ",")) |
| 587 | |
| 588 | read := cosiVersionReader(c) |
| 589 | |
| 590 | for _, node := range targetNodes { |
| 591 | nodeCtx := client.WithNode(ctx, node) |
| 592 | preflightCheckTalosVersion(nodeCtx, read, applyCmdFlags.talosVersion, os.Stderr) |
| 593 | |
| 594 | if err := runPreApplyGates(nodeCtx, c, result, node, os.Stderr, false); err != nil { |
| 595 | return err |
| 596 | } |
| 597 | } |
| 598 | |
| 599 | resp, err := c.ApplyConfiguration(ctx, &machineapi.ApplyConfigurationRequest{ |
| 600 | Data: result, |
| 601 | Mode: applyCmdFlags.Mode.Mode, |
| 602 | DryRun: applyCmdFlags.dryRun, |
| 603 | TryModeTimeout: durationpb.New(applyCmdFlags.configTryTimeout), |
| 604 | }) |
| 605 | if err != nil { |
| 606 | // Post-apply verify intentionally not run on this path: |
| 607 | // Talos's ApplyConfiguration is multi-node aware, so an |
| 608 | // error here doesn't pinpoint which nodes succeeded and |
| 609 | // which didn't. Surface the wrapped error so the operator |
| 610 | // can re-run apply (which will re-trigger the pre-apply |
| 611 | // gate too) — running verify on possibly-partially-applied |
| 612 | // state would produce confusing per-node divergence noise |
| 613 | // on top of the actual failure. |
| 614 | return errors.Wrap(annotateApplyConfigError(err), "applying new configuration") |
no test coverage detected