Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion cmd/weaver/commands/block/node/install.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,12 @@ var installCmd = &cobra.Command{
Any("opts", opts).
Msg("Installing Hedera Block Node")

skipHardwareChecks, err := cmd.Flags().GetBool(common.FlagSkipHardwareChecks.Name)
if err != nil {
return errorx.IllegalArgument.Wrap(err, "failed to get %s flag", common.FlagSkipHardwareChecks.Name)
}
wb := workflows.WithWorkflowExecutionMode(
workflows.NewBlockNodeInstallWorkflow(flagProfile, validatedValuesFile), opts)
workflows.NewBlockNodeInstallWorkflow(flagProfile, validatedValuesFile, skipHardwareChecks), opts)

common.RunWorkflow(cmd.Context(), wb)

Expand Down
16 changes: 16 additions & 0 deletions cmd/weaver/commands/common/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,22 @@ var (
Description: "Install Metrics Server",
Default: true,
}

// FlagSkipHardwareChecks is a hidden persistent flag registered on the root command.
// When set, it skips CPU, memory, and storage validation in NewNodeSafetyCheckWorkflow
// (see internal/workflows/preflight.go). Privilege, user, and host profile checks
// still run. This flag is intentionally not supported by the "check" command since its
// purpose is to validate hardware requirements.
//
// Used by: block node install, kube cluster install.
// Registered in: cmd/weaver/commands/root.go (hidden).
// See docs/dev/hidden-flags.md for full documentation.
FlagSkipHardwareChecks = FlagDefinition[bool]{
Name: "skip-hardware-checks",
ShortName: "",
Description: "DANGEROUS: Skip hardware validation checks. May cause node instability or data loss.",
Default: false,
}
)

// FlagDefinition defines a command-line flag typed by T.
Expand Down
6 changes: 5 additions & 1 deletion cmd/weaver/commands/kube/cluster/install.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,11 @@ var installCmd = &cobra.Command{
Any("opts", opts).
Msg("Installing Kubernetes Cluster")

wb := workflows.WithWorkflowExecutionMode(workflows.InstallClusterWorkflow(flagNodeType, flagProfile), opts)
skipHardwareChecks, err := cmd.Flags().GetBool(common.FlagSkipHardwareChecks.Name)
if err != nil {
return errorx.IllegalArgument.Wrap(err, "failed to get %s flag", common.FlagSkipHardwareChecks.Name)
}
wb := workflows.WithWorkflowExecutionMode(workflows.InstallClusterWorkflow(flagNodeType, flagProfile, skipHardwareChecks), opts)
common.RunWorkflow(cmd.Context(), wb)

logx.As().Info().Msg("Successfully installed Kubernetes Cluster")
Expand Down
12 changes: 9 additions & 3 deletions cmd/weaver/commands/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,10 @@ import (
// rootCmd represents the base command when called without any subcommands
var (
// Used for flags.
flagConfig string
flagVersion bool
flagOutputFormat string
flagConfig string
flagVersion bool
flagOutputFormat string
flagSkipHardwareChecks bool

rootCmd = &cobra.Command{
Use: "solo-provisioner",
Expand Down Expand Up @@ -60,6 +61,11 @@ func init() {
rootCmd.PersistentFlags().BoolVarP(&flagVersion, "version", "v", false, "Show version")
rootCmd.PersistentFlags().StringVarP(&flagOutputFormat, "output", "o", "yaml", "Output format (yaml|json)")

// Hardware check override flag - hidden to discourage casual use
rootCmd.PersistentFlags().BoolVar(&flagSkipHardwareChecks, common.FlagSkipHardwareChecks.Name, false,
"DANGEROUS: Skip hardware validation checks. May cause node instability or data loss.")
_ = rootCmd.PersistentFlags().MarkHidden(common.FlagSkipHardwareChecks.Name)

// disable command sorting to keep the order of commands as added
cobra.EnableCommandSorting = false

Expand Down
33 changes: 33 additions & 0 deletions docs/dev/hidden-flags.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Hidden Flags

This document describes hidden CLI flags that are not shown in `--help` output. These flags exist for
support and debugging purposes and should not be used in normal operations.

## `--skip-hardware-checks`

**Scope:** `block node install`, `kube cluster install`

Skips OS, CPU, memory, and storage validation during installation workflows. The following preflight checks
still run even when this flag is set:

- Privilege validation (root user)
- Weaver user/group validation
- Host profile validation

**When to use:**

- Working around a false-positive hardware check failure.
- Development or testing on machines that don't meet production hardware requirements.

**Not supported by:** `block node check` — that command always runs all checks since its purpose
is to validate system requirements.

**Implementation:**

- Flag defined in `cmd/weaver/commands/common/flags.go` (`FlagSkipHardwareChecks`).
- Registered as a hidden persistent flag on the root command in `cmd/weaver/commands/root.go`.
- Read via `cmd.Flags().GetBool(common.FlagSkipHardwareChecks.Name)` in install commands.
- Passed as `skipHardwareChecks bool` through the workflow chain to `NewNodeSafetyCheckWorkflow`
in `internal/workflows/preflight.go`, which conditionally excludes hardware steps.


10 changes: 5 additions & 5 deletions internal/workflows/blocknode.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@ import (
"github.com/hashgraph/solo-weaver/internal/workflows/steps"
)

// NewBlockNodePreflightCheckWorkflow creates a safety check workflow for block node
// NewBlockNodePreflightCheckWorkflow creates a safety check workflow for block node.
func NewBlockNodePreflightCheckWorkflow(profile string) *automa.WorkflowBuilder {
return NewNodeSafetyCheckWorkflow(core.NodeTypeBlock, profile)
return NewNodeSafetyCheckWorkflow(core.NodeTypeBlock, profile, false)
}

// NewBlockNodeInstallWorkflow creates a comprehensive install workflow for block node
func NewBlockNodeInstallWorkflow(profile string, valuesFile string) *automa.WorkflowBuilder {
// NewBlockNodeInstallWorkflow creates a comprehensive install workflow for block node.
func NewBlockNodeInstallWorkflow(profile string, valuesFile string, skipHardwareChecks bool) *automa.WorkflowBuilder {
return automa.NewWorkflowBuilder().WithId("block-node-install").Steps(
InstallClusterWorkflow(core.NodeTypeBlock, profile),
InstallClusterWorkflow(core.NodeTypeBlock, profile, skipHardwareChecks),
steps.SetupBlockNode(profile, valuesFile),
)
}
Expand Down
6 changes: 3 additions & 3 deletions internal/workflows/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,11 @@ func DefaultWorkflowExecutionOptions() *WorkflowExecutionOptions {
}
}

// InstallClusterWorkflow creates a workflow to set up a kubernetes cluster
func InstallClusterWorkflow(nodeType string, profile string) *automa.WorkflowBuilder {
// InstallClusterWorkflow creates a workflow to set up a kubernetes cluster.
func InstallClusterWorkflow(nodeType string, profile string, skipHardwareChecks bool) *automa.WorkflowBuilder {
// Build the base steps that are common to all node types
baseSteps := []automa.Builder{
NodeSetupWorkflow(nodeType, profile),
NodeSetupWorkflow(nodeType, profile, skipHardwareChecks),

// setup env for k8s
steps.DisableSwap(),
Expand Down
2 changes: 1 addition & 1 deletion internal/workflows/cluster_it_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ import (
func Test_ClusterSetup(t *testing.T) {
testutil.Reset(t)

installWf, err := InstallClusterWorkflow(core.NodeTypeBlock, core.ProfileLocal).
installWf, err := InstallClusterWorkflow(core.NodeTypeBlock, core.ProfileLocal, false).
WithExecutionMode(automa.StopOnError).
Build()
require.NoError(t, err)
Expand Down
31 changes: 21 additions & 10 deletions internal/workflows/preflight.go
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,7 @@ func CheckMemoryStep(nodeType string, profile string) automa.Builder {
func CheckStorageStep(nodeType string, profile string) automa.Builder {
return automa.NewStepBuilder().WithId("validate-storage").
WithExecute(func(ctx context.Context, stp automa.Step) *automa.Report {

hostProfile := hardware.GetHostProfile()
nodeSpec, err := createNodeSpec(nodeType, profile, hostProfile)
if err != nil {
Expand All @@ -369,19 +370,29 @@ func CheckStorageStep(nodeType string, profile string) automa.Builder {
})
}

// NewNodeSafetyCheckWorkflow creates a safety check workflow for any node type
func NewNodeSafetyCheckWorkflow(nodeType string, profile string) *automa.WorkflowBuilder {
return automa.NewWorkflowBuilder().
WithId(nodeType+"-node-preflight").Steps(
// NewNodeSafetyCheckWorkflow creates a safety check workflow for any node type.
// If skipHardwareChecks is true, hardware validation steps (OS, CPU, memory, storage) are excluded.
func NewNodeSafetyCheckWorkflow(nodeType string, profile string, skipHardwareChecks bool) *automa.WorkflowBuilder {
preflightSteps := []automa.Builder{
CheckPrivilegesStep(),
CheckWeaverUserStep(),
CheckHostProfileStep(nodeType, profile),
CheckOSStep(nodeType, profile),
CheckCPUStep(nodeType, profile),
CheckMemoryStep(nodeType, profile),
CheckStorageStep(nodeType, profile),
//CheckDockerStep(),
).
}

if skipHardwareChecks {
logx.As().Warn().Msg("Hardware validation steps (OS, CPU, memory, storage) will be skipped due to --skip-hardware-checks flag")
} else {
preflightSteps = append(preflightSteps,
CheckOSStep(nodeType, profile),
CheckCPUStep(nodeType, profile),
CheckMemoryStep(nodeType, profile),
CheckStorageStep(nodeType, profile),
)
}

return automa.NewWorkflowBuilder().
WithId(nodeType + "-node-preflight").
Steps(preflightSteps...).
WithPrepare(func(ctx context.Context, stp automa.Step) (context.Context, error) {
notify.As().StepStart(ctx, stp, "Starting node preflight checks")
return ctx, nil
Expand Down
6 changes: 3 additions & 3 deletions internal/workflows/setup.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@ import (
)

// NodeSetupWorkflow creates a comprehensive setup workflow for any node type
// It runs preflight checks first, then performs the actual setup
func NodeSetupWorkflow(nodeType string, profile string) *automa.WorkflowBuilder {
// It runs preflight checks first, then performs the actual setup.
func NodeSetupWorkflow(nodeType string, profile string, skipHardwareChecks bool) *automa.WorkflowBuilder {
return automa.NewWorkflowBuilder().
WithId(nodeType+"-node-setup").
Steps(
// First run preflight checks to ensure system readiness
NewNodeSafetyCheckWorkflow(nodeType, profile),
NewNodeSafetyCheckWorkflow(nodeType, profile, skipHardwareChecks),
// Then perform the actual setup
steps.SetupHomeDirectoryStructure(core.Paths()),
steps.RefreshSystemPackageIndex(),
Expand Down
Loading