Skip to content

Commit

Permalink
feat: new phenix-tunneler exe to tunnel port forwards using WebSockets
Browse files Browse the repository at this point in the history
  • Loading branch information
activeshadow committed Sep 14, 2023
1 parent d65ab2c commit 6370ff5
Show file tree
Hide file tree
Showing 44 changed files with 2,888 additions and 882 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/docker.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ jobs:
context: .
file: docker/Dockerfile
build-args: |
MM_MIN_REV=2bd71c0
MM_MIN_REV=2b2b341
PHENIX_COMMIT=${{ env.sha }}
PHENIX_TAG=${{ env.branch }}
APPS_REPO=${{ github.event_name == 'repository_dispatch' && github.event.client_payload.repo || 'sandialabs/sceptre-phenix-apps' }}
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/minimega.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name: Publish minimega Docker image
on:
push:
branches: [main]
branches: ['**']
jobs:
push-to-ghcr:
name: Push minimega Docker image to GitHub Packages
Expand All @@ -28,10 +28,10 @@ jobs:
context: docker
file: docker/Dockerfile.minimega
build-args: |
MM_REV=2bd71c0
MM_REV=2b2b341
PHENIX_REVISION=${{ env.sha }}
push: true
tags: |
ghcr.io/${{ github.repository }}/minimega:2bd71c0
ghcr.io/${{ github.repository }}/minimega:2b2b341
ghcr.io/${{ github.repository }}/minimega:${{ env.sha }}
ghcr.io/${{ github.repository }}/minimega:${{ env.branch }}
9 changes: 7 additions & 2 deletions docker/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ WORKDIR /phenix/src/go/web/public/docs
RUN npx redoc-cli build openapi.yml -o index.html --title 'phenix API'


FROM golang:1.20.5 AS gobuilder
FROM golang:1.20.7 AS gobuilder

RUN apt update \
&& apt install -y protobuf-compiler xz-utils
Expand All @@ -65,6 +65,7 @@ ARG PHENIX_COMMIT
ARG PHENIX_TAG

RUN COMMIT=${PHENIX_COMMIT} TAG=${PHENIX_TAG} make bin/phenix
RUN make -C src/go phenix-tunneler

ARG APPS_REPO=sandialabs/sceptre-phenix-apps
ARG APPS_BRANCH=main
Expand Down Expand Up @@ -134,9 +135,13 @@ RUN wget -O filebeat.deb https://artifacts.elastic.co/downloads/beats/filebeat/f
COPY --from=gobuilder /phenix/bin/phenix /usr/local/bin/phenix
COPY --from=gobuilder /go/bin/phenix-app-* /usr/local/bin

COPY --from=gobuilder /phenix/src/go/bin/phenix-tunneler-* /opt/phenix/downloads/tunneler/

# Update GitHub workflow config to change the minimum version of minimega
# required for use with phenix.
ARG MM_MIN_REV=2bd71c0
ARG MM_MIN_REV=2b2b341
LABEL gov.sandia.phenix.minimega-min-revision="ghcr.io/sandialabs/sceptre-phenix/minimega:${MM_MIN_REV}"

WORKDIR /opt/phenix

CMD ["phenix", "help"]
4 changes: 2 additions & 2 deletions docker/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ services:
context: ../
dockerfile: docker/Dockerfile
args:
MM_MIN_REV: 2bd71c0
MM_MIN_REV: 2b2b341
PHENIX_WEB_AUTH: disabled
command:
- phenix
Expand Down Expand Up @@ -44,7 +44,7 @@ services:
context: .
dockerfile: Dockerfile.minimega
args:
MM_REV: 2bd71c0
MM_REV: 2b2b341
image: minimega
container_name: minimega
privileged: true
Expand Down
17 changes: 17 additions & 0 deletions src/go/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ UISOURCES := $(shell find web -name '*.go' -not -path 'web/rbac/known_policy.go'
CONFIGS := $(shell find api/config/default -name '*')
TEMPLATES := $(shell find tmpl/templates -name '*')

TUNNELSOURCES := $(shell find tunneler -name '*.go' )

THISFILE := $(lastword $(MAKEFILE_LIST))
THISDIR := $(shell dirname $(realpath $(THISFILE)))
GOBIN := $(THISDIR)/bin
Expand Down Expand Up @@ -120,3 +122,18 @@ bin/phenix: $(SOURCES) generate-bindata generate-protobuf go-generate
bin/phenix-debug: $(SOURCES) generate-bindata generate-protobuf go-generate
mkdir -p bin
CGO_ENABLED=0 GOOS=linux go build -gcflags "all=-N -l" -trimpath -o bin/phenix-debug main.go

.PHONY: phenix-tunneler
phenix-tunneler: bin/phenix-tunneler-linux-amd64 bin/phenix-tunneler-darwin-arm64 bin/phenix-tunneler-windows-amd64.exe

bin/phenix-tunneler-linux-amd64: $(TUNNELSOURCES)
mkdir -p bin
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -a -ldflags="-X 'phenix/version.Commit=$(COMMIT)' -s -w" -trimpath -o bin/phenix-tunneler-linux-amd64 $(TUNNELSOURCES)

bin/phenix-tunneler-darwin-arm64: $(TUNNELSOURCES)
mkdir -p bin
CGO_ENABLED=0 GOOS=darwin GOARCH=arm64 go build -a -ldflags="-X 'phenix/version.Commit=$(COMMIT)' -s -w" -trimpath -o bin/phenix-tunneler-darwin-arm64 $(TUNNELSOURCES)

bin/phenix-tunneler-windows-amd64.exe: $(TUNNELSOURCES)
mkdir -p bin
CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build -a -ldflags="-X 'phenix/version.Commit=$(COMMIT)' -s -w" -trimpath -o bin/phenix-tunneler-windows-amd64.exe $(TUNNELSOURCES)
22 changes: 16 additions & 6 deletions src/go/app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,12 @@ import (
"time"

"phenix/types"
ifaces "phenix/types/interfaces"
"phenix/util/notes"
"phenix/util/plog"
"phenix/util/pubsub"
"phenix/util/shell"

ifaces "phenix/types/interfaces"
)

// Action represents the different experiment lifecycle hooks.
Expand All @@ -21,9 +22,11 @@ type Action string
// AppFactory is a function that returns a new app struct.
type AppFactory func() App

type Publication struct {
type TriggerPublication struct {
Experiment string
Verb string
App string
Resource string
State string
Error error
}
Expand Down Expand Up @@ -178,7 +181,7 @@ func ApplyApps(ctx context.Context, exp *types.Experiment, opts ...Option) error
// Publish triggered app events so web broker can propogate the publish out to
// web clients. This was initially setup to help convey SOH status in the UI.
publish := func(app, state string, err error) {
pubsub.Publish("trigger-app", Publication{
pubsub.Publish("trigger-app", TriggerPublication{
Experiment: exp.Metadata.Name,
App: app,
State: state,
Expand Down Expand Up @@ -400,14 +403,21 @@ func PeriodicallyRunApps(ctx context.Context, wg *sync.WaitGroup, exp *types.Exp
plog.Error("[✗] error updating store with experiment", "exp", exp.Metadata.Name, "err", err)
}

pubsub.Publish("trigger-app", Publication{Experiment: exp.Spec.ExperimentName(), App: app.Name(), State: "start"})
pubsub.Publish("trigger-app", TriggerPublication{
Experiment: exp.Spec.ExperimentName(), App: app.Name(), State: "start",
})

if err := a.Running(ctx, exp); err != nil {
pubsub.Publish("trigger-app", Publication{Experiment: exp.Spec.ExperimentName(), App: app.Name(), State: "error", Error: err})
pubsub.Publish("trigger-app", TriggerPublication{
Experiment: exp.Spec.ExperimentName(), App: app.Name(), State: "error", Error: err,
})

plog.Error("[✗] error periodically running app", "app", app.Name(), "err", err)
}

pubsub.Publish("trigger-app", Publication{Experiment: exp.Spec.ExperimentName(), App: app.Name(), State: "success"})
pubsub.Publish("trigger-app", TriggerPublication{
Experiment: exp.Spec.ExperimentName(), App: app.Name(), State: "success",
})

exp.Status.SetAppRunning(app.Name(), false)

Expand Down
129 changes: 129 additions & 0 deletions src/go/tunneler/client.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
package main

import (
"encoding/gob"
"fmt"
"math/rand"
"net"
"os"
"path/filepath"
)

type client struct {
conn net.Conn

enc *gob.Encoder
dec *gob.Decoder
}

func newClient() (*client, error) {
var (
sockDir = filepath.Join(os.TempDir(), "phenix")
sockPath = filepath.Join(sockDir, "tunneler.sock")

err error
)

cli := new(client)

cli.conn, err = net.Dial("unix", sockPath)
if err != nil {
return nil, fmt.Errorf("dialing phenix unix socket %s: %w", sockPath, err)
}

cli.enc = gob.NewEncoder(cli.conn)
cli.dec = gob.NewDecoder(cli.conn)

return cli, nil
}

func (this client) close() error {
return this.conn.Close()
}

func (this client) getLocalListeners() (Listeners, error) {
msg := Message{
MID: rand.Int(),
Type: LISTENERS,
}

if err := this.enc.Encode(msg); err != nil {
return nil, fmt.Errorf("sending request: %w", err)
}

if err := this.dec.Decode(&msg); err != nil {
return nil, fmt.Errorf("receiving response: %w", err)
}

if payload, ok := msg.Payload.(Listeners); ok {
return payload, nil
} else {
return nil, fmt.Errorf("decoding listeners from response")
}
}

func (this client) moveLocalListener(id, port int) error {
msg := Message{
MID: rand.Int(),
Type: MOVE,
Payload: []int{id, port},
}

if err := this.enc.Encode(msg); err != nil {
return fmt.Errorf("sending request: %w", err)
}

if err := this.dec.Decode(&msg); err != nil {
return fmt.Errorf("receiving response: %w", err)
}

if msg.Error != "" {
return fmt.Errorf(msg.Error)
}

return nil
}

func (this client) activateLocalListener(id int) error {
msg := Message{
MID: rand.Int(),
Type: ACTIVATE,
Payload: id,
}

if err := this.enc.Encode(msg); err != nil {
return fmt.Errorf("sending request: %w", err)
}

if err := this.dec.Decode(&msg); err != nil {
return fmt.Errorf("receiving response: %w", err)
}

if msg.Error != "" {
return fmt.Errorf(msg.Error)
}

return nil
}

func (this client) deactivateLocalListener(id int) error {
msg := Message{
MID: rand.Int(),
Type: DEACTIVATE,
Payload: id,
}

if err := this.enc.Encode(msg); err != nil {
return fmt.Errorf("sending request: %w", err)
}

if err := this.dec.Decode(&msg); err != nil {
return fmt.Errorf("receiving response: %w", err)
}

if msg.Error != "" {
return fmt.Errorf(msg.Error)
}

return nil
}
Loading

0 comments on commit 6370ff5

Please sign in to comment.