-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Boernsman
authored and
Boernsman
committed
Jul 11, 2024
0 parents
commit 7579fd2
Showing
20 changed files
with
1,092 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
name: Build and Upload | ||
|
||
on: | ||
push: | ||
branches: | ||
- main | ||
pull_request: | ||
branches: | ||
- main | ||
|
||
jobs: | ||
build: | ||
runs-on: ubuntu-latest | ||
|
||
steps: | ||
- name: Checkout code | ||
uses: actions/checkout@v4 | ||
|
||
- name: Set up Go | ||
uses: actions/setup-go@v5 | ||
with: | ||
go-version: 1.22 | ||
|
||
- name: Build | ||
run: ./build.sh | ||
|
||
- name: Archive production artifacts | ||
uses: actions/upload-artifact@v4 | ||
with: | ||
name: bon-voyage-agent | ||
path: build |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
name: Manual Release Upload | ||
|
||
on: | ||
workflow_dispatch: | ||
|
||
jobs: | ||
|
||
upload: | ||
runs-on: ubuntu-latest | ||
needs: build | ||
|
||
steps: | ||
- name: Download artifacts for amd64 | ||
uses: actions/download-artifact@v3 | ||
with: | ||
name: ${{ github.event.repository.name }}-amd64 | ||
|
||
- name: Download artifacts for arm64 | ||
uses: actions/download-artifact@v3 | ||
with: | ||
name: ${{ github.event.repository.name }}-arm64 | ||
|
||
- name: Set up GitHub CLI | ||
uses: cli/cli-action@v2 | ||
|
||
- name: Get the latest tag | ||
id: get_tag | ||
run: echo "::set-output name=tag::$(git describe --tags `git rev-list --tags --max-count=1`)" | ||
|
||
- name: Upload artifacts to GitHub Packages | ||
run: | | ||
gh release create ${{ steps.get_tag.outputs.tag }} bin/${{ github.event.repository.name }}-amd64 --title "${{ steps.get_tag.outputs.tag }}" --notes "Release ${{ steps.get_tag.outputs.tag }}" --target main | ||
gh release upload ${{ steps.get_tag.outputs.tag }} bin/${{ github.event.repository.name }}-arm64 --clobber | ||
env: | ||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
build/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
# Bon Voyage Agent | ||
|
||
## Usage | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
#!/usr/bin/env bash | ||
|
||
# Exit immediately if a command exits with a non-zero status | ||
set -e | ||
|
||
# Variables | ||
BASEDIR=$(dirname $(realpath "$0")) | ||
echo "Base Dir: $BASEDIR" | ||
TARGET="bon-voyage-agent" | ||
SRC_DIR="$BASEDIR/src" | ||
PLUGIN_SRC_DIR="$BASEDIR/src/plugins" | ||
BUILD_DIR="$BASEDIR/build" | ||
PLUGIN_BUILD_DIR="$BUILD_DIR/plugins" | ||
|
||
# Check if Go is installed | ||
if ! [ -x "$(command -v go)" ]; then | ||
echo "Error: Go is not installed." >&2 | ||
exit 1 | ||
fi | ||
|
||
# Determine the operating system | ||
OS="$(uname -s)" | ||
case "$OS" in | ||
Linux*) GOOS="linux";; | ||
Darwin*) GOOS="darwin";; | ||
*) echo "Unsupported OS: $OS"; exit 1;; | ||
esac | ||
|
||
# Clean previous builds | ||
echo "Cleaning previous builds..." | ||
rm -f $BUILD_DIR/$TARGET | ||
|
||
# Build the agent | ||
echo "Building agent ..." | ||
cd $SRC_DIR | ||
|
||
GIT_HASH=$(git rev-parse HEAD) | ||
go build -o $BUILD_DIR/$TARGET -ldflags="-X main.Commit=$GIT_HASH" | ||
cd $BASEDIR | ||
|
||
# Build the plugins | ||
cd $PLUGIN_SRC_DIR | ||
./build_plugins.sh $PLUGIN_BUILD_DIR | ||
cd $BASEDIR | ||
echo "Build finished. See README.md for usage." |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
# Bon Voyage Agent | ||
agent: | ||
name: "Voyager" | ||
id: "60F8A8EF-0D07-4353-B238-A4D568100E3B" | ||
server: | ||
host: "192.168.1.148" | ||
port: 6666 | ||
key: "" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
package connection | ||
|
||
import ( | ||
"bon-voyage-agent/models" | ||
"encoding/json" | ||
"fmt" | ||
) | ||
|
||
const pluginName = "serial" | ||
|
||
// Implements interface Plugin | ||
type PluginAgent struct { | ||
Name string | ||
Information models.AgentInformation | ||
Capabilities []string | ||
Plugins []string | ||
} | ||
|
||
func (p PluginAgent) Init(params any) string { | ||
|
||
switch v := params.(type) { | ||
case models.AgentInformation: | ||
PluginInstance.Information = v | ||
default: | ||
fmt.Printf("Invalid plugin params") | ||
} | ||
p.Name = pluginName | ||
return p.Name | ||
} | ||
|
||
func AgentCall(request models.RPCRequest, response *models.RPCResponse) { | ||
|
||
switch request.Method { | ||
case "agent_get_information": | ||
i, err := json.Marshal(PluginInstance.Information) | ||
if err != nil { | ||
response.Error = err.Error() | ||
return | ||
} | ||
response.Result = string(i) | ||
case "agent_set_name": | ||
var name models.SetNameMethod | ||
err := json.Unmarshal(request.Params, &name) | ||
if err != nil { | ||
response.Error = err.Error() | ||
} | ||
PluginInstance.Information.Name = name.Name | ||
|
||
case "agent_get_capabilities": | ||
i, err := json.Marshal(PluginInstance.Capabilities) | ||
if err != nil { | ||
response.Error = err.Error() | ||
return | ||
} | ||
response.Result = string(i) | ||
case "agent_get_plugins": | ||
i, err := json.Marshal(PluginInstance.Plugins) | ||
if err != nil { | ||
response.Error = err.Error() | ||
return | ||
} | ||
response.Result = string(i) | ||
default: | ||
response.Error = "Unknown method" | ||
} | ||
} | ||
|
||
// Exported symbol | ||
var PluginInstance PluginAgent |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
package connection | ||
|
||
import ( | ||
"bon-voyage-agent/models" | ||
"encoding/json" | ||
"fmt" | ||
"strings" | ||
) | ||
|
||
type Handler func(models.RPCRequest, *models.RPCResponse) | ||
|
||
type Route struct { | ||
handler Handler | ||
} | ||
|
||
func NewRoute() *Route { | ||
return &Route{} | ||
} | ||
|
||
type Router struct { | ||
NotFoundHandler Handler | ||
namedRoutes map[string]*Route | ||
} | ||
|
||
func NewRouter() *Router { | ||
r := Router{namedRoutes: make(map[string]*Route)} | ||
r.HandleFunc("agent", AgentCall) | ||
return &r | ||
} | ||
|
||
func (r *Router) HandleFunc(name string, f func(request models.RPCRequest, response *models.RPCResponse)) *Route { | ||
route := &Route{handler: f} | ||
r.namedRoutes[name] = route | ||
return route | ||
} | ||
|
||
func (r *Router) ParseMessage(data []byte) ([]byte, error) { | ||
|
||
var request models.RPCRequest | ||
err := json.Unmarshal(data, &request) | ||
if err != nil { | ||
return nil, fmt.Errorf("unmarshal error: %v", err) | ||
} | ||
if request.Jsonrpc != "2.0" { | ||
return nil, fmt.Errorf("jsonrpc field not '2.0'") | ||
} | ||
|
||
response := models.RPCResponse{ | ||
Jsonrpc: "2.0", | ||
ID: request.ID, | ||
} | ||
if len(strings.Split(request.Method, "_")) == 0 { | ||
return nil, fmt.Errorf("method malformed") | ||
} | ||
routeName := strings.Split(request.Method, "_")[0] | ||
|
||
route := r.namedRoutes[routeName] | ||
route.handler(request, &response) | ||
|
||
resBytes, err := json.Marshal(response) | ||
if err != nil { | ||
return nil, fmt.Errorf("marshal error: %v", err) | ||
} | ||
return resBytes, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
package connection | ||
|
||
import ( | ||
"fmt" | ||
"net/http" | ||
"net/url" | ||
|
||
"github.com/gorilla/websocket" | ||
) | ||
|
||
type Connection struct { | ||
Host string | ||
Port string | ||
Name string | ||
Uuid string | ||
Key string | ||
Token string | ||
} | ||
|
||
func (c Connection) serverUrl(path string) *url.URL { | ||
return &url.URL{ | ||
Scheme: "ws", | ||
Host: c.Host + ":" + c.Port, | ||
Path: path, | ||
} | ||
} | ||
|
||
func (c Connection) header() http.Header { | ||
h := http.Header{} | ||
h.Add("X-Device-UUID", c.Uuid) | ||
h.Add("X-Device-Name", c.Name) | ||
if c.Key != "" { | ||
h.Add("X-Device-Api-Key", c.Key) | ||
} | ||
return h | ||
} | ||
|
||
func (c Connection) ConnectDataSocket() (*websocket.Conn, error) { | ||
|
||
d := websocket.DefaultDialer | ||
d.Subprotocols = []string{"serial-tunnel-v1"} | ||
|
||
socket, _, err := d.Dial(c.serverUrl("/api/device/data").String(), c.header()) | ||
if err != nil { | ||
return nil, fmt.Errorf("dial: %v", err) | ||
} | ||
|
||
return socket, nil | ||
|
||
// done := make(chan struct{}) | ||
|
||
// go func() { | ||
// defer close(done) | ||
// for { | ||
// _, message, err := socket.ReadMessage() | ||
// if err != nil { | ||
// if websocket.IsCloseError(err, websocket.CloseNormalClosure) { | ||
// return | ||
// } | ||
// fmt.Println("read:", err) | ||
// return | ||
// } | ||
// fmt.Printf("Received: %s\n", message) | ||
// } | ||
// }() | ||
|
||
// go func() { | ||
// scanner := bufio.NewScanner(os.Stdin) | ||
// for scanner.Scan() { | ||
// text := scanner.Text() | ||
// err := socket.WriteMessage(websocket.TextMessage, []byte(text)) | ||
// if err != nil { | ||
// fmt.Println("write:", err) | ||
// return | ||
// } | ||
// } | ||
// if err := scanner.Err(); err != nil { | ||
// fmt.Println("Error reading from stdin:", err) | ||
// } | ||
// }() | ||
|
||
// select { | ||
// case <-done: | ||
// fmt.Println("WebSocket connection closed") | ||
// case <-interrupt: | ||
// fmt.Println("\nInterrupt signal received, closing connection...") | ||
// err := socket.WriteMessage(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseNormalClosure, "")) | ||
// if err != nil { | ||
// fmt.Println("write close:", err) | ||
// return err | ||
// } | ||
// select { | ||
// case <-done: | ||
// case <-time.After(time.Second): | ||
// } | ||
// } | ||
} | ||
|
||
func (c Connection) ConnectConfigSocket() (*websocket.Conn, error) { | ||
|
||
d := websocket.DefaultDialer | ||
d.Subprotocols = []string{"config-tunnel-v1"} | ||
|
||
socket, _, err := d.Dial(c.serverUrl("/api/device/config").String(), c.header()) | ||
if err != nil { | ||
return nil, fmt.Errorf("dial: %v", err) | ||
} | ||
|
||
return socket, nil | ||
} |
Oops, something went wrong.