Skip to content

Commit 781ded8

Browse files
committed
feat(bladectl)!: add more bladectl commands (#91)
This PR introduces a comprehensive set of new subcommands to bladectl, expanding its capabilities for querying and managing compute blade state. It also includes an internal refactor to simplify interface management across the gRPC API. * `get` * `fan`: Returns current fan speed. * `identify`: Indicates whether the identify mode is active. * `stealth`: Shows if stealth mode is currently enabled. * `status`: Prints a full blade status report. * `temperature`: Retrieves current SoC temperature. * `critical`: Shows whether critical mode is active. * `power`: Reports the current power source (e.g., PoE+ or USB). * `set` * `stealth`: Enables stealth mode. * `remove` * `stealth`: Disables stealth mode. * `describe` * `fan`: Outputs the current fan curve configuration. * `monitor`: plot some charts about the state of the compute-blade-agent * **gRPC API refactor**: The gRPC service definitions previously located in `internal/api` have been folded into `internal/agent`. This eliminates redundant interface declarations and ensures that all ComputeBladeAgent implementations are directly compatible with the gRPC API. This reduces duplication and improves long-term maintainability and clarity of the interface contract. ```bash bladectl set fan --percent 90 --blade 1 --blade 2 bladectl unset identify --blade 1 --blade 2 --blade 3 --blade 4 bladectl set stealth --blade 1 --blade 2 --blade 3 --blade 4 bladectl get status --blade 1 --blade 2 --blade 3 --blade 4 ┌───────┬─────────────┬────────────────────┬───────────────┬──────────────┬──────────┬───────────────┬──────────────┐ │ BLADE │ TEMPERATURE │ FAN SPEED OVERRIDE │ FAN SPEED │ STEALTH MODE │ IDENTIFY │ CRITICAL MODE │ POWER STATUS │ ├───────┼─────────────┼────────────────────┼───────────────┼──────────────┼──────────┼───────────────┼──────────────┤ │ 1 │ 50°C │ 90% │ 5825 RPM(90%) │ Active │ Off │ Off │ poe+ │ │ 2 │ 48°C │ 90% │ 5825 RPM(90%) │ Active │ Off │ Off │ poe+ │ │ 3 │ 49°C │ Not set │ 4643 RPM(56%) │ Active │ Off │ Off │ poe+ │ │ 4 │ 49°C │ Not set │ 4774 RPM(58%) │ Active │ Off │ Off │ poe+ │ └───────┴─────────────┴────────────────────┴───────────────┴──────────────┴──────────┴───────────────┴──────────────┘ bladectl rm stealth --blade 1 --blade 2 --blade 3 --blade 4 bladectl rm fan --blade 1 --blade 2 --blade 3 --blade 4 bladectl get status --blade 1 --blade 2 --blade 3 --blade 4 ┌───────┬─────────────┬────────────────────┬───────────────┬──────────────┬──────────┬───────────────┬──────────────┐ │ BLADE │ TEMPERATURE │ FAN SPEED OVERRIDE │ FAN SPEED │ STEALTH MODE │ IDENTIFY │ CRITICAL MODE │ POWER STATUS │ ├───────┼─────────────┼────────────────────┼───────────────┼──────────────┼──────────┼───────────────┼──────────────┤ │ 1 │ 51°C │ Not set │ 5177 RPM(66%) │ Off │ Off │ Off │ poe+ │ │ 2 │ 49°C │ Not set │ 5177 RPM(58%) │ Off │ Off │ Off │ poe+ │ │ 3 │ 50°C │ Not set │ 4659 RPM(60%) │ Off │ Off │ Off │ poe+ │ │ 4 │ 48°C │ Not set │ 4659 RPM(54%) │ Off │ Off │ Off │ poe+ │ └───────┴─────────────┴────────────────────┴───────────────┴──────────────┴──────────┴───────────────┴──────────────┘ ``` when having multiple compute-blades in your bladeconfig: ```yaml blades: - name: 1 blade: server: blade-pi1:8081 cert: certificate-authority-data: <redacted> client-certificate-data: <redacted> client-key-data: <redacted> - name: 2 blade: server: blade-pi2:8081 cert: certificate-authority-data: <redacted> client-certificate-data: <redacted> client-key-data: <redacted> - name: 3 blade: server: blade-pi3:8081 cert: certificate-authority-data: <redacted> client-certificate-data: <redacted> client-key-data: <redacted> - name: 4 blade: server: blade-pi4:8081 cert: certificate-authority-data: <redacted> client-certificate-data: <redacted> client-key-data: <redacted> - name: 4 blade: server: blade-pi4:8081 cert: certificate-authority-data: <redacted> client-certificate-data: <redacted> client-key-data: <redacted> current-blade: 1 ``` Fixes #4, #9 (partially), should help with #5 * test: improve unit-testing * fix: pin github.com/warthog618/gpiod --------- Co-authored-by: Cedric Kienzler <[email protected]>
1 parent 7ec49ce commit 781ded8

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+1936
-737
lines changed

api/bladeapi/v1alpha1/blade.pb.go

Lines changed: 190 additions & 63 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

api/bladeapi/v1alpha1/blade.proto

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
syntax = "proto4";
1+
syntax = "proto3";
22

33
import "google/protobuf/empty.proto";
44
package api.bladeapi.v1alpha1;
@@ -37,13 +37,22 @@ message EmitEventRequest {
3737
Event event = 1;
3838
}
3939

40+
message FanCurveStep {
41+
int64 temperature = 1;
42+
uint32 percent = 2;
43+
}
44+
4045
message StatusResponse {
4146
bool stealth_mode = 1;
4247
bool identify_active = 2;
4348
bool critical_active = 3;
4449
int64 temperature = 4;
4550
int64 fan_rpm = 5;
4651
PowerStatus power_status = 6;
52+
uint32 fan_percent = 7;
53+
bool fan_speed_automatic = 8;
54+
int64 critical_temperature_threshold = 9;
55+
repeated FanCurveStep fan_curve_steps = 10;
4756
}
4857

4958
service BladeAgentService {
@@ -53,9 +62,17 @@ service BladeAgentService {
5362
// WaitForIdentifyConfirm blocks until the blades button is pressed
5463
rpc WaitForIdentifyConfirm(google.protobuf.Empty) returns (google.protobuf.Empty) {}
5564

65+
// Sets the fan speed to a specific value.
5666
rpc SetFanSpeed(SetFanSpeedRequest) returns (google.protobuf.Empty) {}
5767

68+
// Sets the fan speed to automatic mode.
69+
//
70+
// Internally, this is equivalent to calling SetFanSpeed with a nil/empty value.
71+
rpc SetFanSpeedAuto(google.protobuf.Empty) returns (google.protobuf.Empty) {}
72+
73+
// Sets the blade to stealth mode (disables all LEDs)
5874
rpc SetStealthMode(StealthModeRequest) returns (google.protobuf.Empty) {}
5975

76+
// Gets the current status of the blade
6077
rpc GetStatus(google.protobuf.Empty) returns (StatusResponse) {}
6178
}

api/bladeapi/v1alpha1/blade_grpc.pb.go

Lines changed: 49 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

cmd/agent/main.go

Lines changed: 10 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ import (
1313
"syscall"
1414
"time"
1515

16-
"github.com/compute-blade-community/compute-blade-agent/internal/agent"
17-
"github.com/compute-blade-community/compute-blade-agent/internal/api"
16+
internal_agent "github.com/compute-blade-community/compute-blade-agent/internal/agent"
17+
"github.com/compute-blade-community/compute-blade-agent/pkg/agent"
1818
"github.com/compute-blade-community/compute-blade-agent/pkg/log"
1919
"github.com/prometheus/client_golang/prometheus/promhttp"
2020
"github.com/spechtlabs/go-otel-utils/otelprovider"
@@ -153,8 +153,8 @@ func main() {
153153
}
154154
}()
155155

156-
log.FromContext(ctx).Info("Bootstrapping compute-blade-agent")
157-
computebladeAgent, err := agent.NewComputeBladeAgent(ctx, cbAgentConfig)
156+
log.FromContext(ctx).Info("Bootstrapping compute-blade-agent", zap.String("version", Version), zap.String("commit", Commit))
157+
computebladeAgent, err := internal_agent.NewComputeBladeAgent(ctx, cbAgentConfig)
158158
if err != nil {
159159
cancelCtx(err)
160160
log.FromContext(ctx).WithError(err).Fatal("Failed to create agent")
@@ -163,17 +163,6 @@ func main() {
163163
// Run agent
164164
computebladeAgent.RunAsync(ctx, cancelCtx)
165165

166-
// Setup GRPC server
167-
grpcServer := api.NewGrpcApiServer(ctx,
168-
api.WithComputeBladeAgent(computebladeAgent),
169-
api.WithAuthentication(cbAgentConfig.Listen.GrpcAuthenticated),
170-
api.WithListenAddr(cbAgentConfig.Listen.Grpc),
171-
api.WithListenMode(cbAgentConfig.Listen.GrpcListenMode),
172-
)
173-
174-
// Run gRPC API
175-
grpcServer.ServeAsync(ctx, cancelCtx)
176-
177166
// setup prometheus endpoint
178167
promServer := runPrometheusEndpoint(ctx, cancelCtx, &cbAgentConfig.Listen)
179168

@@ -190,8 +179,11 @@ func main() {
190179
wg.Add(1)
191180
go func() {
192181
defer wg.Done()
193-
otelzap.L().Info("Shutting down grpc server")
194-
grpcServer.GracefulStop()
182+
183+
log.FromContext(ctx).Info("Shutting down compute blade agent...")
184+
if err := computebladeAgent.GracefulStop(ctx); err != nil {
185+
log.FromContext(ctx).WithError(err).Error("Failed to close compute blade agent")
186+
}
195187
}()
196188

197189
// Shut-Down Prometheus Endpoint
@@ -218,7 +210,7 @@ func main() {
218210
}
219211
}
220212

221-
func runPrometheusEndpoint(ctx context.Context, cancel context.CancelCauseFunc, apiConfig *api.Config) *http.Server {
213+
func runPrometheusEndpoint(ctx context.Context, cancel context.CancelCauseFunc, apiConfig *agent.ApiConfig) *http.Server {
222214
instrumentationHandler := http.NewServeMux()
223215
instrumentationHandler.Handle("/metrics", promhttp.Handler())
224216
instrumentationHandler.HandleFunc("/debug/pprof/", pprof.Index)

0 commit comments

Comments
 (0)