Skip to content
Open
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
40 changes: 40 additions & 0 deletions cmd/rcs/console/connect.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// SPDX-FileCopyrightText: © 2026 OpenCHAMI a Series of LF Projects, LLC
//
// SPDX-License-Identifier: MIT

package console

import (
"os"

"github.com/spf13/cobra"

"github.com/OpenCHAMI/ochami/internal/cli"
"github.com/OpenCHAMI/ochami/internal/cli/rcs"
"github.com/OpenCHAMI/ochami/internal/log"
)

func newConnectCmd() *cobra.Command {
return &cobra.Command{
Use: "connect [nodeID]",
Short: "Connects to a console",
Long: `Connects to an interactive console session on the specified node.

See ochami-rcs(1) for more details.`,
Example: ` # Connect to a node console
ochami rcs console connect x0c0s1b0n0`,
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
cli.HandleToken(cmd)

nodeID := args[0]
rcsClient := rcs.GetClient(cmd)
err := rcsClient.ConnectConsole(cmd.Context(), nodeID, cli.Token, os.Stdin, os.Stdout)
if err != nil {
log.Logger.Error().Err(err).Msg("failed to connect to console")
cli.LogHelpError(cmd)
os.Exit(1)
}
},
}
}
34 changes: 34 additions & 0 deletions cmd/rcs/console/console.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// SPDX-FileCopyrightText: © 2026 OpenCHAMI a Series of LF Projects, LLC
//
// SPDX-License-Identifier: MIT

package console

import (
"github.com/spf13/cobra"

"github.com/OpenCHAMI/ochami/internal/cli"
)

func NewCmd() *cobra.Command {
// consoleCmd represents the "rcs console" command
var consoleCmd = &cobra.Command{
Use: "console",
Short: "Console operations",
Long: `Console operations for remote-console.

See ochami-rcs(1) for more details.`,
Run: func(cmd *cobra.Command, args []string) {
cli.PrintUsageHandleError(cmd)
},
}

// Add subcommands
consoleCmd.AddCommand(
newListCmd(),
newShowCmd(),
newConnectCmd(),
)

return consoleCmd
}
52 changes: 52 additions & 0 deletions cmd/rcs/console/list.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// SPDX-FileCopyrightText: © 2026 OpenCHAMI a Series of LF Projects, LLC
//
// SPDX-License-Identifier: MIT

package console

import (
"fmt"
"os"

"github.com/spf13/cobra"

"github.com/OpenCHAMI/ochami/internal/cli"
"github.com/OpenCHAMI/ochami/internal/cli/rcs"
"github.com/OpenCHAMI/ochami/internal/log"
"github.com/OpenCHAMI/ochami/pkg/format"
)

func newListCmd() *cobra.Command {
listCmd := &cobra.Command{
Use: "list",
Short: "Returns a list of the available consoles",
Long: `Returns a list of the available consoles.

See ochami-rcs(1) for more details.`,
Example: ` # List available consoles
ochami rcs console list`,
Run: func(cmd *cobra.Command, args []string) {
cli.HandleToken(cmd)

rcsClient := rcs.GetClient(cmd)
consoles, err := rcsClient.ListConsoles(cli.Token)
if err != nil {
log.Logger.Error().Err(err).Msg("failed to list consoles")
cli.LogHelpError(cmd)
os.Exit(1)
}
if outBytes, err := format.MarshalData(consoles, cli.FormatOutput); err != nil {
log.Logger.Error().Err(err).Msg("failed to format output")
cli.LogHelpError(cmd)
os.Exit(1)
} else {
fmt.Println(string(outBytes))
}
},
}

listCmd.Flags().VarP(&cli.FormatOutput, "format-output", "F", "format of output printed to standard output (json,json-pretty,yaml)")
listCmd.RegisterFlagCompletionFunc("format-output", cli.CompletionFormatData)

return listCmd
}
63 changes: 63 additions & 0 deletions cmd/rcs/console/show.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
// SPDX-FileCopyrightText: © 2026 OpenCHAMI a Series of LF Projects, LLC
//
// SPDX-License-Identifier: MIT

package console

import (
"os"

"github.com/spf13/cobra"

"github.com/OpenCHAMI/ochami/internal/cli"
"github.com/OpenCHAMI/ochami/internal/cli/rcs"
"github.com/OpenCHAMI/ochami/internal/log"
)

func newShowCmd() *cobra.Command {
var follow bool
var lines int

var showCmd = &cobra.Command{
Use: "show [nodeID]",
Short: "Shows the console",
Long: `Shows console output for the specified node.

See ochami-rcs(1) for more details.`,
Example: ` # Show console output for a node
ochami rcs console show x0c0s1b0n0`,
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
cli.HandleToken(cmd)

follow, err := cmd.Flags().GetBool("follow")
if err != nil {
log.Logger.Error().Err(err).Msg("unable to get follow flag")
cli.LogHelpError(cmd)
os.Exit(1)
}

lines, err := cmd.Flags().GetInt("lines")
if err != nil {
log.Logger.Error().Err(err).Msg("unable to get lines flag")
cli.LogHelpError(cmd)
os.Exit(1)
}

nodeID := args[0]

rcsClient := rcs.GetClient(cmd)
err = rcsClient.ShowConsole(cmd.Context(), nodeID, follow, lines, cli.Token, os.Stdout)
if err != nil {
log.Logger.Error().Err(err).Msg("failed to show console")
cli.LogHelpError(cmd)
os.Exit(1)
}
},
}

showCmd.Flags().BoolVarP(&follow, "follow", "f", false, "follow the console output")
showCmd.Flags().IntVarP(&lines, "lines", "n", 100, "number of lines to show from history")

return showCmd
}
42 changes: 42 additions & 0 deletions cmd/rcs/rcs.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// SPDX-FileCopyrightText: © 2026 OpenCHAMI a Series of LF Projects, LLC
//
// SPDX-License-Identifier: MIT

package rcs

import (
"os"

"github.com/spf13/cobra"

console_cmd "github.com/OpenCHAMI/ochami/cmd/rcs/console"
service_cmd "github.com/OpenCHAMI/ochami/cmd/rcs/service"
"github.com/OpenCHAMI/ochami/internal/cli"
)

func NewCmd() *cobra.Command {
// rcsCmd represents the rcs command
var rcsCmd = &cobra.Command{
Use: "rcs",
Args: cobra.NoArgs,
Short: "Manage remote consoles",
Long: `Manage remote consoles via the remote-console service.

See ochami-rcs(1) for more details.`,
Run: func(cmd *cobra.Command, args []string) {
cli.PrintUsageHandleError(cmd)
os.Exit(0)
},
}

// Create flags
rcsCmd.PersistentFlags().String("uri", "", "absolute base URI or relative base path of remote-console")

// Add subcommands
rcsCmd.AddCommand(
console_cmd.NewCmd(),
service_cmd.NewCmd(),
)

return rcsCmd
}
30 changes: 30 additions & 0 deletions cmd/rcs/service/service.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// SPDX-FileCopyrightText: © 2026 OpenCHAMI a Series of LF Projects, LLC
//
// SPDX-License-Identifier: MIT

package service

import (
"github.com/spf13/cobra"

"github.com/OpenCHAMI/ochami/internal/cli"
)

func NewCmd() *cobra.Command {
var serviceCmd = &cobra.Command{
Use: "service",
Short: "Console service operations",
Long: `Console service operations for remote-console.

See ochami-rcs(1) for more details.`,
Run: func(cmd *cobra.Command, args []string) {
cli.PrintUsageHandleError(cmd)
},
}

serviceCmd.AddCommand(
newStatusCmd(),
)

return serviceCmd
}
54 changes: 54 additions & 0 deletions cmd/rcs/service/status.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// SPDX-FileCopyrightText: © 2026 OpenCHAMI a Series of LF Projects, LLC
//
// SPDX-License-Identifier: MIT

package service

import (
"fmt"
"os"

"github.com/spf13/cobra"

"github.com/OpenCHAMI/ochami/internal/cli"
"github.com/OpenCHAMI/ochami/internal/cli/rcs"
"github.com/OpenCHAMI/ochami/internal/log"
"github.com/OpenCHAMI/ochami/pkg/format"
)

func newStatusCmd() *cobra.Command {
statusCmd := &cobra.Command{
Use: "status",
Short: "Returns the status of the console service",
Long: `Returns the status of the console service.

See ochami-rcs(1) for more details.`,
Example: ` # Get console service status
ochami rcs service status`,
Run: func(cmd *cobra.Command, args []string) {
cli.HandleToken(cmd)

rcsClient := rcs.GetClient(cmd)

status, err := rcsClient.GetStatus(cli.Token)
if err != nil {
log.Logger.Error().Err(err).Msg("failed to get console service status")
cli.LogHelpError(cmd)
os.Exit(1)
}

if outBytes, err := format.MarshalData(status, cli.FormatOutput); err != nil {
log.Logger.Error().Err(err).Msg("failed to format output")
cli.LogHelpError(cmd)
os.Exit(1)
} else {
fmt.Println(string(outBytes))
}
},
}

statusCmd.Flags().VarP(&cli.FormatOutput, "format-output", "F", "format of output printed to standard output (json,json-pretty,yaml)")
statusCmd.RegisterFlagCompletionFunc("format-output", cli.CompletionFormatData)

return statusCmd
}
2 changes: 2 additions & 0 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
config_cmd "github.com/OpenCHAMI/ochami/cmd/config"
discover_cmd "github.com/OpenCHAMI/ochami/cmd/discover"
pcs_cmd "github.com/OpenCHAMI/ochami/cmd/pcs"
rcs_cmd "github.com/OpenCHAMI/ochami/cmd/rcs"
smd_cmd "github.com/OpenCHAMI/ochami/cmd/smd"
version_cmd "github.com/OpenCHAMI/ochami/cmd/version"
)
Expand Down Expand Up @@ -100,6 +101,7 @@ See ochami-config(5) for more details on configuring the ochami config file(s).`
bss_cmd.NewCmd(),
cloud_init_cmd.NewCmd(),
config_cmd.NewCmd(),
rcs_cmd.NewCmd(),
discover_cmd.NewCmd(),
pcs_cmd.NewCmd(),
version_cmd.NewCmd(),
Expand Down
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ require (
github.com/OpenCHAMI/smd/v2 v2.18.0
github.com/elliotchance/pie/v2 v2.9.1
github.com/google/uuid v1.6.0
github.com/gorilla/websocket v1.5.3
github.com/knadh/koanf/parsers/yaml v1.1.0
github.com/knadh/koanf/providers/file v1.2.0
github.com/knadh/koanf/providers/rawbytes v1.0.0
Expand All @@ -26,6 +27,7 @@ require (
github.com/spf13/cobra v1.10.2
github.com/synackd/go-kargs v0.0.1-beta.1
github.com/vbauerster/mpb/v8 v8.10.2
golang.org/x/term v0.42.0
gopkg.in/yaml.v3 v3.0.1
)

Expand Down
8 changes: 4 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ github.com/google/pprof v0.0.0-20250403155104-27863c87afa6 h1:BHT72Gu3keYf3ZEu2J
github.com/google/pprof v0.0.0-20250403155104-27863c87afa6/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=
github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
Expand Down Expand Up @@ -156,12 +158,8 @@ github.com/onsi/ginkgo/v2 v2.23.4 h1:ktYTpKJAVZnDT4VjxSbiBenUjmlL/5QkBEocaWXiQus
github.com/onsi/ginkgo/v2 v2.23.4/go.mod h1:Bt66ApGPBFzHyR+JO10Zbt0Gsp4uWxu5mIOTusL46e8=
github.com/onsi/gomega v1.37.0 h1:CdEG8g0S133B4OswTDC/5XPSzE1OeP29QOioj2PID2Y=
github.com/onsi/gomega v1.37.0/go.mod h1:8D9+Txp43QWKhM24yyOBEdpkzN8FvJyAwecBgsU4KU0=
github.com/openchami/boot-service v0.1.5 h1:EqE+dFfU0N4fk2urDVw57aL6y2p07vhkP7gZzMAf31A=
github.com/openchami/boot-service v0.1.5/go.mod h1:SZCVOoQeQxHAYPqSRshjic1uwOOP5P+MbES8FTkGA/0=
github.com/openchami/boot-service v0.1.6 h1:LzHm0mu1cP8yAr70WMG7KzdK/alKkhFjTkdpgEB/+0o=
github.com/openchami/boot-service v0.1.6/go.mod h1:ftV0yxv5XexP0LQbFAfGVJe8hCfD2jNRFTh+59ueKzw=
github.com/openchami/fabrica v0.4.5 h1:ZokuHjWGXYHz3jq3mNStIopIBAhLp+NQdUxjUHwxKYM=
github.com/openchami/fabrica v0.4.5/go.mod h1:h/0CX1tDwqdmBxk4lm8EtxcMgI6ebaxbz65ic4uozfg=
github.com/openchami/fabrica v0.4.7 h1:H63fRqSfiUud/jlPo3NS7tXEtSyXBlgWZ7MDhJuTRnM=
github.com/openchami/fabrica v0.4.7/go.mod h1:h/0CX1tDwqdmBxk4lm8EtxcMgI6ebaxbz65ic4uozfg=
github.com/openchami/schemas v0.0.0-20250625220233-9aad17a286c4 h1:89rudSw0TeedlHbGr5L9WEW9lJ3yMEtY2EgxoC7EGso=
Expand Down Expand Up @@ -225,6 +223,8 @@ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.43.0 h1:Rlag2XtaFTxp19wS8MXlJwTvoh8ArU6ezoyFsMyCTNI=
golang.org/x/sys v0.43.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
golang.org/x/term v0.42.0 h1:UiKe+zDFmJobeJ5ggPwOshJIVt6/Ft0rcfrXZDLWAWY=
golang.org/x/term v0.42.0/go.mod h1:Dq/D+snpsbazcBG5+F9Q1n2rXV8Ma+71xEjTRufARgY=
golang.org/x/text v0.36.0 h1:JfKh3XmcRPqZPKevfXVpI1wXPTqbkE5f7JA92a55Yxg=
golang.org/x/text v0.36.0/go.mod h1:NIdBknypM8iqVmPiuco0Dh6P5Jcdk8lJL0CUebqK164=
golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE=
Expand Down
Loading
Loading