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
1 change: 0 additions & 1 deletion .dockerignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
**/.dockerignore
**/Dockerfile
.git
*.md
LICENSE
29 changes: 29 additions & 0 deletions api/api.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package api

// MetalConfig is consumed by metal-hammer to get all options to open a grpc connection to the metal-api
// Deprecated: This mixes up the pixie configuration with server responses, this will be removed once the
// metal-hammer was fully migrated to V2MetalHammerConfigPayload
type MetalConfig struct {
Debug bool `json:"debug"`
GRPCAddress string `json:"address,omitempty"`
Expand All @@ -12,10 +14,37 @@ type MetalConfig struct {
HMAC string `json:"hmac,omitempty"`
NTPServers []string `json:"ntp_servers,omitempty"`
Partition string `json:"partition"`

// metal-apiserver related fields
MetalAPIServerUrl string `json:"-"`
MetalAPIServerTokenFile string `json:"-"`
MetalHammerTenant string `json:"-"`
Comment thread
Gerrit91 marked this conversation as resolved.

// Logging contains logging configurations passed to metal-hammer
Logging *Logging `json:"logging,omitempty"`
}

// V2MetalHammerConfigPayload contains initial configuration options for the metal-hammer.
type V2MetalHammerConfigPayload struct {
// Client contains data for initializing the v2 metal-apiserver client
Client Client `json:"client"`

// NTPServers to use for synchronize time in the metal-hammer, defaults back to public ntp servers if empty
NTPServers []string `json:"ntp_servers,omitempty"`
// Partition used for registering the machine in the metal-hammer
Partition string `json:"partition"`

// Logging contains logging configurations passed to metal-hammer
Logging *Logging `json:"logging,omitempty"`
}

type Client struct {
// ApiUrl contains the URL to the metal-apiserver
ApiUrl string `json:"metal_apiserver_url"`
// Token contains the token for the client
Token string `json:"metal_hammer_token"`
}

type Logging struct {
// Endpoint is the url where the logs must be shipped to
Endpoint string `json:"endpoint,omitempty"`
Expand Down
14 changes: 10 additions & 4 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module github.com/metal-stack/pixie
go 1.27

require (
github.com/metal-stack/metal-api v0.45.0
github.com/metal-stack/api v0.7.0
github.com/metal-stack/v v1.0.3
github.com/pin/tftp/v3 v3.2.0
github.com/prometheus/client_golang v1.24.1
Expand All @@ -12,15 +12,23 @@ require (
github.com/stretchr/testify v1.12.1
golang.org/x/crypto v0.57.0
golang.org/x/net v0.59.0
google.golang.org/grpc v1.84.0
google.golang.org/protobuf v1.36.12
)

require (
buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.36.12-20260825204119-511051f7f437.2 // indirect
connectrpc.com/connect v1.21.0 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/fsnotify/fsnotify v1.10.1 // indirect
github.com/go-viper/mapstructure/v2 v2.5.0 // indirect
github.com/golang-jwt/jwt/v5 v5.3.1 // indirect
github.com/google/go-cmp v0.7.0 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/klauspost/compress v1.20.1 // indirect
github.com/klauspost/connect-compress/v2 v2.1.1 // indirect
github.com/minio/minlz v1.2.0 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/pelletier/go-toml/v2 v2.4.3 // indirect
github.com/prometheus/client_model v0.6.3 // indirect
Expand All @@ -34,6 +42,4 @@ require (
go.yaml.in/yaml/v3 v3.0.5 // indirect
golang.org/x/sys v0.48.0 // indirect
golang.org/x/text v0.42.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20260918162117-cecb64721679 // indirect
google.golang.org/protobuf v1.36.12 // indirect
)
34 changes: 22 additions & 12 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.36.12-20260825204119-511051f7f437.1 h1:Slv0uGxx219srASyiaI5C9cDlyG8kNDcXpTSYcuAeE4=
buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.36.12-20260825204119-511051f7f437.1/go.mod h1:TCt1lluMFnctISJXvkIQ4x3ABrPuUKCWKyjKdkJNBpw=
buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.36.12-20260825204119-511051f7f437.2 h1:NbnlmV26O7oZ1iM5tsCI+GEx+3ZSdrhvnKQ/eWSrLiY=
buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.36.12-20260825204119-511051f7f437.2/go.mod h1:TCt1lluMFnctISJXvkIQ4x3ABrPuUKCWKyjKdkJNBpw=
connectrpc.com/connect v1.20.0 h1:6TNDAB+WeNd2uolWNlYczB5E0KNNaVMNUEx8JEUsPmQ=
connectrpc.com/connect v1.20.0/go.mod h1:A2ygJrukXwWy32vkCAAHNVguZrqZ+jeZ9rGRnGR4dN4=
connectrpc.com/connect v1.21.0 h1:LhqSJt7jHf5NJBo9Jq/t/9FjcYAideif0mg+qe2jCUs=
connectrpc.com/connect v1.21.0/go.mod h1:A2ygJrukXwWy32vkCAAHNVguZrqZ+jeZ9rGRnGR4dN4=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
Expand All @@ -9,24 +17,32 @@ github.com/fsnotify/fsnotify v1.10.1 h1:b0/UzAf9yR5rhf3RPm9gf3ehBPpf0oZKIjtpKrx5
github.com/fsnotify/fsnotify v1.10.1/go.mod h1:TLheqan6HD6GBK6PrDWyDPBaEV8LspOxvPSjC+bVfgo=
github.com/go-viper/mapstructure/v2 v2.5.0 h1:vM5IJoUAy3d7zRSVtIwQgBj7BiWtMPfmPEgAXnvj1Ro=
github.com/go-viper/mapstructure/v2 v2.5.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
github.com/golang-jwt/jwt/v5 v5.3.1 h1:kYf81DTWFe7t+1VvL7eS+jKFVWaUnK9cB1qbwn63YCY=
github.com/golang-jwt/jwt/v5 v5.3.1/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE=
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
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/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/klauspost/compress v1.19.1 h1:VsB4HPswih7mmZ8WleSFQ75c/Ui1M4trX5oAsJnhSlk=
github.com/klauspost/compress v1.19.1/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ=
github.com/klauspost/compress v1.20.0 h1:a3C1ke2ohxFymNlb2HWAHjDeKCI90scRskErZkR0ezA=
github.com/klauspost/compress v1.20.0/go.mod h1:LUdAzn7YLVvxLpc7y3V1m40wESHTgc1422pwwBSKYuI=
github.com/klauspost/compress v1.20.1 h1:T7kKElXUMXrUJ2E9QhQhxFtcK5rPyLdsGZvdbLMPdiQ=
github.com/klauspost/compress v1.20.1/go.mod h1:LUdAzn7YLVvxLpc7y3V1m40wESHTgc1422pwwBSKYuI=
github.com/klauspost/connect-compress/v2 v2.1.1 h1:ycZNp4rWOZBodVE2Ls5AzK4aHkyK+GteEfzRZgKNs+c=
github.com/klauspost/connect-compress/v2 v2.1.1/go.mod h1:9oilsPHJMzGKkjafSBk9J7iVo4mO+dw0G0KSdVpnlVE=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
github.com/metal-stack/metal-api v0.45.0 h1:FG/byWdsN4x6Oy3I4MWp7BhHG6TRVBVSlwbf2cukmG8=
github.com/metal-stack/metal-api v0.45.0/go.mod h1:VvibW4YHsdyQaStxpu3KDpL41BMhL12ADdVUR56Mo2A=
github.com/metal-stack/api v0.7.0 h1:z+J788nCCmIyBaG/hNmKLPJ/S1K6nfePqSDyMIIX470=
github.com/metal-stack/api v0.7.0/go.mod h1:rWdj0dTAg2w/WuQhIZ+JVp9b68v6VVCm1k7sLx4U+PQ=
github.com/metal-stack/v v1.0.3 h1:Sh2oBlnxrCUD+mVpzfC8HiqL045YWkxs0gpTvkjppqs=
github.com/metal-stack/v v1.0.3/go.mod h1:YTahEu7/ishwpYKnp/VaW/7nf8+PInogkfGwLcGPdXg=
github.com/minio/minlz v1.2.0 h1:6IOBuiHg04QxvbFfgFLT/9sMaO/UhL7S+ApW1mK8q5A=
github.com/minio/minlz v1.2.0/go.mod h1:Ls9H7nlkASeCcdl5thjVD5Eraj6z+zGa7xtq57jIKD4=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
github.com/pelletier/go-toml/v2 v2.4.3 h1:GTRvJQutkOSftxIFD5xw9aepkYNuPWmVJpffdDPYVpY=
Expand Down Expand Up @@ -76,12 +92,6 @@ golang.org/x/sys v0.48.0 h1:bbX/i/6MgT9BVLM9RT1thmxL04yeTAhbEz4SyadbXoo=
golang.org/x/sys v0.48.0/go.mod h1:hNLxWAXmnKAxqDtdwIYC4bM9oQPEecfsnNMuSxOs3og=
golang.org/x/text v0.42.0 h1:JbOZXgfeCPU9gacVtYliJqOhD+zhrEqK4LfdpmlUZqI=
golang.org/x/text v0.42.0/go.mod h1:ojzP1Z+2QtioaF8DTtO8K5q7JWVVYwZKenzujK0Zd0E=
gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4=
gonum.org/v1/gonum v0.17.0/go.mod h1:El3tOrEuMpv2UdMrbNlKEh9vd86bmQ6vqIcDwxEOc1E=
google.golang.org/genproto/googleapis/rpc v0.0.0-20260918162117-cecb64721679 h1:KmqdJU4vrNcxy/6qdg3JduZtalEXrJLspVltnR1cE+8=
google.golang.org/genproto/googleapis/rpc v0.0.0-20260918162117-cecb64721679/go.mod h1:OaIUM3+LpYcK2GXM4FTmhWoIq371Owdr+Cc7/BsYHHc=
google.golang.org/grpc v1.84.0 h1:soMyaPJ8pAak5PIQ0DGBUir0XRo2fRoMqhNWMLlLxO0=
google.golang.org/grpc v1.84.0/go.mod h1:ljCht0DrxQrXBDRTZp52Qxh3Ffk8CdYm2sj4O2QN2C0=
google.golang.org/protobuf v1.36.12 h1:pJOKDDOyeXErUroCihFAd5LQuwXBSpVnKGrj5o/fwxc=
google.golang.org/protobuf v1.36.12/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
44 changes: 26 additions & 18 deletions pixiecore/booters.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ import (
"text/template"
"time"

v1 "github.com/metal-stack/metal-api/pkg/api/v1"
"github.com/metal-stack/api/go/client"
infrav2 "github.com/metal-stack/api/go/metalstack/infra/v2"
"github.com/metal-stack/pixie/api"
)

Expand All @@ -50,9 +51,9 @@ func APIBooter(url string, timeout time.Duration) (Booter, error) {

return ret, nil
}
func GRPCBooter(log *slog.Logger, client *GrpcClient, partition string, metalAPIConfig *api.MetalConfig) (Booter, error) {
func GRPCBooter(log *slog.Logger, v2client client.Client, partition string, metalAPIConfig *api.MetalConfig) (Booter, error) {
ret := &grpcbooter{
grpc: client,
v2client: v2client,
partition: partition,
log: log,
config: metalAPIConfig,
Expand All @@ -72,7 +73,8 @@ type apibooter struct {

type grpcbooter struct {
apibooter
grpc *GrpcClient
// v1client *GrpcClient
v2client client.Client
config *api.MetalConfig
partition string
log *slog.Logger
Expand All @@ -86,32 +88,38 @@ func (g *grpcbooter) BootSpec(m Machine) (*Spec, error) {

var r rawSpec
if m.GUID != "" {
// Very first dhcp call which contains Machine UUID, tell metal-api this uuid
req := &v1.BootServiceDhcpRequest{
Uuid: string(m.GUID),
}
g.log.Info("dhcp", "req", req)
_, err := g.grpc.BootService().Dhcp(ctx, req)
// Very first dhcp call which contains Machine UUID, tell metal-apiserver this uuid
g.log.Info("dhcp", "machine-guid", m.GUID)
_, err := g.v2client.Infrav2().Boot().Dhcp(ctx, &infrav2.BootServiceDhcpRequest{
Uuid: m.GUID,
Partition: g.partition,
})
if err != nil {
g.log.Error("boot", "error", err)
return nil, err
}
r = rawSpec{}
} else {
// machine asks for a dhcp answer, ask metal-api for a proper response in this partition
req := &v1.BootServiceBootRequest{
Mac: m.MAC.String(),
PartitionId: g.partition,
}
g.log.Info("boot", "req", req)
resp, err := g.grpc.BootService().Boot(ctx, req)
// machine asks for a dhcp answer, ask metal-apiserver for a proper response in this partition
g.log.Info("boot", "machine-mac", m.MAC.String())
Comment thread
Gerrit91 marked this conversation as resolved.
resp, err := g.v2client.Infrav2().Boot().Boot(ctx, &infrav2.BootServiceBootRequest{
Mac: m.MAC.String(),
Partition: g.partition,
})
if err != nil {
g.log.Error("boot", "error", err)
return nil, err
}
g.log.Info("boot", "resp", resp)

cmdline := []string{resp.GetCmdline(), fmt.Sprintf("PIXIE_API_URL=%s", g.config.PixieAPIURL)}
var cmdline []string

if resp.Cmdline != nil {
cmdline = append(cmdline, *resp.Cmdline)
}

cmdline = append(cmdline, fmt.Sprintf("PIXIE_API_URL=%s", g.config.PixieAPIURL))

if g.config.Debug {
cmdline = append(cmdline, "DEBUG=1")
}
Expand Down
94 changes: 79 additions & 15 deletions pixiecore/cli/grpccmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,17 @@ package cli

import (
"fmt"
"log/slog"
"net/url"
"os"
"strings"
"time"

"github.com/metal-stack/api/go/client"
apiv2 "github.com/metal-stack/api/go/metalstack/api/v2"
"github.com/metal-stack/pixie/api"
"github.com/metal-stack/pixie/pixiecore"
"github.com/metal-stack/v"
"github.com/spf13/cobra"
)

Expand All @@ -42,20 +47,54 @@ the Pixiecore boot API. The specification can be found at <TODO>.`,
if err != nil {
fatalf("unable to create metal-api config: %s", err)
}
client, err := pixiecore.NewGrpcClient(s.Log, metalAPIConfig)

tokenPersister, err := client.NewFilesystemTokenPersister(metalAPIConfig.MetalAPIServerTokenFile)
if err != nil {
fatalf("error creating token persister: %s", err)
}

token, err := os.ReadFile(metalAPIConfig.MetalAPIServerTokenFile)
if err != nil {
fatalf("error reading token: %s", err)
}

v2client, err := client.New(&client.DialConfig{
BaseURL: metalAPIConfig.MetalAPIServerUrl,
Token: strings.TrimSpace(string(token)),
UserAgent: "pixie",
Log: slog.Default(),
TokenRenewal: &client.TokenRenewal{
PersistTokenFn: tokenPersister,
},
})
if err != nil {
fatalf("unable to create grpc client: %s", err)
fatalf("failed to create metal-apiserver client: %s", err)
}

partition, err := cmd.Flags().GetString("partition")
if err != nil {
fatalf("Error reading flag: %s", err)
fatalf("error reading flag: %s", err)
}
booter, err := pixiecore.GRPCBooter(s.Log, client, partition, metalAPIConfig)

booter, err := pixiecore.GRPCBooter(s.Log, v2client, partition, metalAPIConfig)
if err != nil {
fatalf("unable to create grpc booter: %s", err)
}

s.Booter = booter
s.MetalConfig = metalAPIConfig
s.V2Client = v2client

v2client.Ping(cmd.Context(), &client.PingConfig{
ComponentType: apiv2.ComponentType_COMPONENT_TYPE_PIXIECORE,
StartedAt: time.Now(),
Version: apiv2.Version{
Version: v.Version,
Revision: v.Revision,
GitSha1: v.GitSHA1,
BuildDate: v.BuildDate,
},
})

fmt.Println(s.Serve())
}}
Expand All @@ -77,6 +116,10 @@ func init() {
grpcCmd.Flags().StringSlice("ntp-servers", nil, "custom ntp-servers")
grpcCmd.Flags().Bool("metal-hammer-debug", true, "set metal-hammer to debug")

grpcCmd.Flags().String("metal-apiserver-url", "", "url to access the metal-apiserver")
grpcCmd.Flags().String("metal-apiserver-token-file", "", "token file path to access the metal-apiserver")
grpcCmd.Flags().String("metal-hammer-tenant", "", "the metal-hammer tenant in the metal-apiserver for which tokens will be issued")

// metal-hammer remote logging configuration
grpcCmd.Flags().String("metal-hammer-logging-endpoint", "", "set metal-hammer to send logs to this endpoint")
grpcCmd.Flags().String("metal-hammer-logging-user", "", "set metal-hammer to send logs to a remote endpoint and authenticate with this user")
Expand Down Expand Up @@ -139,6 +182,24 @@ func getMetalAPIConfig(cmd *cobra.Command) (*api.MetalConfig, error) {
if err != nil {
return nil, fmt.Errorf("unable to parse pixie-api-url: %w", err)
}

metalApiServerUrl, err := cmd.Flags().GetString("metal-apiserver-url")
if err != nil {
return nil, fmt.Errorf("error reading flag: %w", err)
}
_, err = url.Parse(metalApiServerUrl)
if err != nil {
return nil, fmt.Errorf("unable to parse metal-apiserver-url: %w", err)
}
metalApiServerTokenFile, err := cmd.Flags().GetString("metal-apiserver-token-file")
if err != nil {
return nil, fmt.Errorf("error reading flag: %w", err)
}
metalHammerTenant, err := cmd.Flags().GetString("metal-hammer-tenant")
if err != nil {
return nil, fmt.Errorf("error reading flag: %w", err)
}

ntpServers, err := cmd.Flags().GetStringSlice("ntp-servers")
if err != nil {
return nil, fmt.Errorf("unable reading ntp-servers flag: %w", err)
Expand Down Expand Up @@ -220,16 +281,19 @@ func getMetalAPIConfig(cmd *cobra.Command) (*api.MetalConfig, error) {
}

return &api.MetalConfig{
Debug: metalHammerDebug,
GRPCAddress: grpcAddress,
MetalAPIUrl: metalAPIUrl,
PixieAPIURL: pixieAPIUrl,
CACert: string(caCert),
Cert: string(clientCert),
Key: string(clientKey),
HMAC: hmac,
NTPServers: ntpServers,
Logging: logging,
Partition: partition,
Debug: metalHammerDebug,
GRPCAddress: grpcAddress,
MetalAPIUrl: metalAPIUrl,
PixieAPIURL: pixieAPIUrl,
CACert: string(caCert),
Cert: string(clientCert),
Key: string(clientKey),
HMAC: hmac,
NTPServers: ntpServers,
Logging: logging,
Partition: partition,
MetalAPIServerUrl: metalApiServerUrl,
MetalAPIServerTokenFile: metalApiServerTokenFile,
MetalHammerTenant: metalHammerTenant,
}, nil
}
Loading
Loading