mirror of
https://github.com/kairos-io/openamt.git
synced 2025-07-17 23:21:07 +00:00
converted from provider plugin to bundle binary
Signed-off-by: Jacob Payne <jacob@spectrocloud.com>
This commit is contained in:
parent
fdedf683ee
commit
605659ba0e
@ -49,9 +49,10 @@ build:
|
|||||||
COPY +amt-rpc-lib/librpc.so /usr/local/lib/librpc.so
|
COPY +amt-rpc-lib/librpc.so /usr/local/lib/librpc.so
|
||||||
COPY +amt-rpc-lib/librpc.h /usr/local/include/librpc.h
|
COPY +amt-rpc-lib/librpc.h /usr/local/include/librpc.h
|
||||||
|
|
||||||
RUN go build -ldflags "-linkmode 'external'" -o agent-provider-amt cmd/main.go && upx agent-provider-amt
|
RUN go build -o agent-provider-amt cmd/main.go && upx agent-provider-amt
|
||||||
|
|
||||||
SAVE ARTIFACT agent-provider-amt AS LOCAL artifacts/agent-provider-amt
|
SAVE ARTIFACT agent-provider-amt AS LOCAL artifacts/agent-provider-amt
|
||||||
|
SAVE ARTIFACT /usr/local/lib/librpc.so AS LOCAL artifacts/librpc.so
|
||||||
|
|
||||||
image:
|
image:
|
||||||
FROM +version
|
FROM +version
|
||||||
@ -60,9 +61,8 @@ image:
|
|||||||
|
|
||||||
FROM scratch
|
FROM scratch
|
||||||
|
|
||||||
COPY --chmod 0777 +amt-rpc-lib/librpc.so /usr/local/lib/librpc.so
|
COPY --chmod 0777 +amt-rpc-lib/librpc.so librpc.so
|
||||||
COPY --chmod 0777 +amt-rpc-lib/librpc.h /usr/local/include/librpc.h
|
COPY --chmod 0777 +build/agent-provider-amt agent-provider-amt
|
||||||
COPY --chmod 0777 +build/agent-provider-amt /system/providers/agent-provider-amt
|
|
||||||
|
|
||||||
SAVE IMAGE --push $IMAGE_REPOSITORY:$VERSION
|
SAVE IMAGE --push $IMAGE_REPOSITORY:$VERSION
|
||||||
|
|
||||||
|
114
cmd/main.go
114
cmd/main.go
@ -1,11 +1,10 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/kairos-io/kairos-sdk/bus"
|
|
||||||
"github.com/mudler/go-pluggable"
|
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
|
"gopkg.in/yaml.v3"
|
||||||
|
"io"
|
||||||
"os"
|
"os"
|
||||||
"provider-amt/pkg/amtrpc"
|
"provider-amt/pkg/amtrpc"
|
||||||
"reflect"
|
"reflect"
|
||||||
@ -13,109 +12,46 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
|
||||||
StateActive = "active"
|
|
||||||
StateError = "error"
|
|
||||||
StateUnavailable = "unavailable"
|
|
||||||
StateSkipped = "skipped"
|
|
||||||
)
|
|
||||||
|
|
||||||
type AMT struct {
|
type AMT struct {
|
||||||
DnsSuffixOverride string `json:"dns_suffix_override,omitempty" flag:"-d"`
|
DnsSuffixOverride string `json:"dns_suffix_override,omitempty" yaml:"dns_suffix_override,omitempty" flag:"-d"`
|
||||||
Hostname string `json:"hostname,omitempty" flag:"-h"`
|
Hostname string `json:"hostname,omitempty" yaml:"hostname,omitempty" flag:"-h"`
|
||||||
LMSAddress string `json:"lms_address,omitempty" flag:"-lmsaddress"`
|
LMSAddress string `json:"lms_address,omitempty" yaml:"lms_address,omitempty" flag:"-lmsaddress"`
|
||||||
LMSPort string `json:"lms_port,omitempty" flag:"-lmsport"`
|
LMSPort string `json:"lms_port,omitempty" yaml:"lms_port,omitempty" flag:"-lmsport"`
|
||||||
ProxyAddress string `json:"proxy_address,omitempty" flag:"-p"`
|
ProxyAddress string `json:"proxy_address,omitempty" yaml:"proxy_address,omitempty" flag:"-p"`
|
||||||
Password string `json:"password,omitempty" flag:"-password"`
|
Password string `json:"password,omitempty" yaml:"password,omitempty" flag:"-password"`
|
||||||
Profile string `json:"profile,omitempty" flag:"-profile"`
|
Profile string `json:"profile,omitempty" yaml:"profile,omitempty" flag:"-profile"`
|
||||||
ServerAddress string `json:"server_address,omitempty" flag:"-u"`
|
ServerAddress string `json:"server_address,omitempty" yaml:"server_address,omitempty" flag:"-u"`
|
||||||
Timeout string `json:"timeout,omitempty" flag:"-t"`
|
Timeout string `json:"timeout,omitempty" yaml:"timeout,omitempty" flag:"-t"`
|
||||||
Extra map[string]string `json:"extra,omitempty"`
|
Extra map[string]string `json:"extra,omitempty" yaml:"extra,omitempty"`
|
||||||
}
|
|
||||||
|
|
||||||
type Configuration struct {
|
|
||||||
AMT *AMT `yaml:"amt,omitempty" json:"amt,omitempty"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
err := pluggable.NewPluginFactory(
|
var config AMT
|
||||||
pluggable.FactoryPlugin{
|
|
||||||
EventType: bus.EventInstall,
|
|
||||||
PluginHandler: func(event *pluggable.Event) pluggable.EventResponse {
|
|
||||||
return activateAMT(amtrpc.AMTRPC{}, event)
|
|
||||||
},
|
|
||||||
},
|
|
||||||
).Run(pluggable.EventType(os.Args[1]), os.Stdin, os.Stdout)
|
|
||||||
|
|
||||||
if err != nil {
|
if err := yaml.NewDecoder(io.TeeReader(os.Stdin, os.Stderr)).Decode(&config); err != nil {
|
||||||
logrus.Fatal(err)
|
logrus.Fatal("failed to parse configuration: ", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := activateAMT(amtrpc.AMTRPC{}, &config); err != nil {
|
||||||
|
logrus.Fatal()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func getConfiguration(event *pluggable.Event) (*AMT, error) {
|
func activateAMT(rpc amtrpc.Interface, config *AMT) error {
|
||||||
var payload bus.EventPayload
|
|
||||||
var config Configuration
|
|
||||||
|
|
||||||
// parse the event to get the configuration
|
|
||||||
if err := json.Unmarshal([]byte(event.Data), &payload); err != nil {
|
|
||||||
return nil, fmt.Errorf("failed to parse event payload %s", err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
// parse the configuration to get the amt configuration
|
|
||||||
if err := json.Unmarshal([]byte(payload.Config), &config); err != nil {
|
|
||||||
return nil, fmt.Errorf("failed to parse configuration %s", err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
return config.AMT, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func activateAMT(rpc amtrpc.Interface, event *pluggable.Event) pluggable.EventResponse {
|
|
||||||
config, err := getConfiguration(event)
|
|
||||||
if err != nil {
|
|
||||||
return pluggable.EventResponse{
|
|
||||||
State: StateError,
|
|
||||||
Data: event.Data,
|
|
||||||
Error: err.Error(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// if no amt configuration is given we do nothing
|
|
||||||
if config == nil {
|
|
||||||
return pluggable.EventResponse{
|
|
||||||
State: StateSkipped,
|
|
||||||
Data: event.Data,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if status := rpc.CheckAccess(); status != utils.Success {
|
if status := rpc.CheckAccess(); status != utils.Success {
|
||||||
if status == utils.AmtNotDetected {
|
if status == utils.AmtNotDetected {
|
||||||
return pluggable.EventResponse{
|
logrus.Info("amt device could not be detected, skipping configuration")
|
||||||
State: StateUnavailable,
|
return nil
|
||||||
Data: event.Data,
|
|
||||||
Logs: "no intel AMT device detected",
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return pluggable.EventResponse{
|
return fmt.Errorf("failed to access AMT device with status code: %d", status)
|
||||||
State: StateError,
|
|
||||||
Data: event.Data,
|
|
||||||
Error: fmt.Sprintf("failed to access AMT device with status code: %d", status),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if response, status := rpc.Exec(toCLIFlags("activate", config, config.Extra)); status != utils.Success {
|
if response, status := rpc.Exec(toCLIFlags("activate", config, config.Extra)); status != utils.Success {
|
||||||
return pluggable.EventResponse{
|
return fmt.Errorf("failed to access AMT device with status code: %d %s", status, response)
|
||||||
State: StateError,
|
|
||||||
Data: event.Data,
|
|
||||||
Error: fmt.Sprintf("failed to activate AMT device with status code: %d", status),
|
|
||||||
Logs: response,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return pluggable.EventResponse{
|
return nil
|
||||||
State: StateActive,
|
|
||||||
Data: event.Data,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const flagTag = "flag"
|
const flagTag = "flag"
|
||||||
|
102
cmd/main_test.go
102
cmd/main_test.go
@ -1,9 +1,6 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
|
||||||
"github.com/kairos-io/kairos-sdk/bus"
|
|
||||||
"github.com/mudler/go-pluggable"
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"provider-amt/pkg/amtrpc"
|
"provider-amt/pkg/amtrpc"
|
||||||
"rpc/pkg/utils"
|
"rpc/pkg/utils"
|
||||||
@ -31,93 +28,50 @@ var amtExecError = amtrpc.AMTRPC{
|
|||||||
}
|
}
|
||||||
|
|
||||||
func Test_activateAMTUnavailable(t *testing.T) {
|
func Test_activateAMTUnavailable(t *testing.T) {
|
||||||
config := Configuration{
|
config := &AMT{
|
||||||
AMT: &AMT{
|
ServerAddress: "wss://fake",
|
||||||
ServerAddress: "wss://fake",
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
event := encodeConfiguration(config)
|
|
||||||
|
|
||||||
resp := activateAMT(amtUnavailable, event)
|
err := activateAMT(amtUnavailable, config)
|
||||||
|
|
||||||
assert.Equal(t, StateUnavailable, resp.State)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, event.Data, resp.Data)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func Test_activateAMTCheckAccessError(t *testing.T) {
|
func Test_activateAMTCheckAccessError(t *testing.T) {
|
||||||
config := Configuration{
|
config := &AMT{
|
||||||
AMT: &AMT{
|
ServerAddress: "wss://fake",
|
||||||
ServerAddress: "wss://fake",
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
event := encodeConfiguration(config)
|
|
||||||
|
|
||||||
resp := activateAMT(amtAccessError, event)
|
err := activateAMT(amtAccessError, config)
|
||||||
|
|
||||||
assert.Equal(t, StateError, resp.State)
|
assert.Error(t, err)
|
||||||
assert.Equal(t, event.Data, resp.Data)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func Test_activateAMTNoConfiguration(t *testing.T) {
|
func Test_activateAMTNoConfiguration(t *testing.T) {
|
||||||
config := Configuration{}
|
err := activateAMT(amtActive, &AMT{})
|
||||||
event := encodeConfiguration(config)
|
|
||||||
|
|
||||||
resp := activateAMT(amtActive, event)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
assert.Equal(t, StateSkipped, resp.State)
|
|
||||||
assert.Equal(t, event.Data, resp.Data)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Test_activateAMTInvalidEventData(t *testing.T) {
|
|
||||||
config := Configuration{
|
|
||||||
AMT: &AMT{
|
|
||||||
ServerAddress: "wss://fake",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
event := encodeConfiguration(config)
|
|
||||||
event.Data = event.Data[1:]
|
|
||||||
|
|
||||||
resp := activateAMT(amtActive, event)
|
|
||||||
|
|
||||||
assert.Equal(t, StateError, resp.State)
|
|
||||||
assert.Equal(t, event.Data, resp.Data)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Test_activateAMTInvalidConfiguration(t *testing.T) {
|
|
||||||
event := &pluggable.Event{Data: `{"config":"{"}`}
|
|
||||||
|
|
||||||
resp := activateAMT(amtActive, event)
|
|
||||||
|
|
||||||
assert.Equal(t, StateError, resp.State)
|
|
||||||
assert.Equal(t, event.Data, resp.Data)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func Test_activateAMTApplyError(t *testing.T) {
|
func Test_activateAMTApplyError(t *testing.T) {
|
||||||
config := Configuration{
|
config := &AMT{
|
||||||
AMT: &AMT{
|
ServerAddress: "wss://fake",
|
||||||
ServerAddress: "wss://fake",
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
event := encodeConfiguration(config)
|
|
||||||
|
|
||||||
resp := activateAMT(amtExecError, event)
|
err := activateAMT(amtExecError, config)
|
||||||
|
|
||||||
assert.Equal(t, StateError, resp.State)
|
assert.Error(t, err)
|
||||||
assert.Equal(t, event.Data, resp.Data)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func Test_activateAMTStandard(t *testing.T) {
|
func Test_activateAMTStandard(t *testing.T) {
|
||||||
var execCommand string
|
var execCommand string
|
||||||
|
|
||||||
config := Configuration{
|
config := &AMT{
|
||||||
AMT: &AMT{
|
ServerAddress: "wss://fake",
|
||||||
ServerAddress: "wss://fake",
|
Extra: map[string]string{
|
||||||
Extra: map[string]string{
|
"-foo": "bar",
|
||||||
"-foo": "bar",
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
event := encodeConfiguration(config)
|
|
||||||
amt := amtrpc.AMTRPC{
|
amt := amtrpc.AMTRPC{
|
||||||
MockAccessStatus: func() int { return utils.Success },
|
MockAccessStatus: func() int { return utils.Success },
|
||||||
MockExec: func(s string) (string, int) {
|
MockExec: func(s string) (string, int) {
|
||||||
@ -126,24 +80,10 @@ func Test_activateAMTStandard(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
resp := activateAMT(amt, event)
|
err := activateAMT(amt, config)
|
||||||
|
|
||||||
assert.Contains(t, execCommand, "activate")
|
assert.Contains(t, execCommand, "activate")
|
||||||
assert.Contains(t, execCommand, "-u "+config.AMT.ServerAddress)
|
assert.Contains(t, execCommand, "-u "+config.ServerAddress)
|
||||||
assert.Contains(t, execCommand, "-foo bar")
|
assert.Contains(t, execCommand, "-foo bar")
|
||||||
assert.Equal(t, StateActive, resp.State)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, event.Data, resp.Data)
|
|
||||||
assert.False(t, resp.Errored())
|
|
||||||
}
|
|
||||||
|
|
||||||
func encodeConfiguration(config Configuration) *pluggable.Event {
|
|
||||||
inner, _ := json.Marshal(config)
|
|
||||||
data, _ := json.Marshal(bus.EventPayload{
|
|
||||||
Config: string(inner),
|
|
||||||
})
|
|
||||||
|
|
||||||
return &pluggable.Event{
|
|
||||||
Name: bus.EventInstall,
|
|
||||||
Data: string(data),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
package amtrpc
|
package amtrpc
|
||||||
|
|
||||||
/*
|
/*
|
||||||
#cgo LDFLAGS: -L/usr/local/lib -lrpc -Wl,-rpath=/usr/local/lib
|
#cgo LDFLAGS: -L'$ORIGIN' -lrpc -Wl,-rpath='$ORIGIN'
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include "librpc.h"
|
#include "librpc.h"
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user