Skip to content

Commit

Permalink
add created/destroyed/downloaded handlers to propagate events up hier…
Browse files Browse the repository at this point in the history
…archy
  • Loading branch information
scottfeldman committed Jan 17, 2025
1 parent d2cab4c commit df5c561
Show file tree
Hide file tree
Showing 16 changed files with 102 additions and 49 deletions.
4 changes: 0 additions & 4 deletions devices/hubdevice/hubdevice.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,6 @@ func (h *hubDevice) GetConfig() device.Config {
Targets: []string{"x86-64", "rpi", "koyeb"},
BgColor: "sunflower",
FgColor: "black",
PacketHandlers: device.PacketHandlers{
"/created": &device.PacketHandler[device.MsgCreated]{device.BroadcastUp},
"/destroyed": &device.PacketHandler[device.MsgDestroyed]{device.BroadcastUp},
},
}
}

Expand Down
75 changes: 52 additions & 23 deletions pkg/device/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -467,6 +467,23 @@ func (d *device) showInstructionsTarget(w http.ResponseWriter, r *http.Request)
}
}

func (d *device) showModel(w http.ResponseWriter, r *http.Request) {
view := r.URL.Query().Get("view")
template := "model-" + view + ".tmpl"
if err := d.renderTmpl(w, template, d.Config); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
}
}

func (d *device) showNewModal(w http.ResponseWriter, r *http.Request) {
err := d.renderTmpl(w, "modal-new.tmpl", map[string]any{
"models": d.childModels(),
"newid": generateRandomId(),
})
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
}
}
func (d *device) editName(w http.ResponseWriter, r *http.Request) {
if err := d.renderTmpl(w, "edit-name.tmpl", d.Name); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
Expand Down Expand Up @@ -510,20 +527,27 @@ func (d *device) apiRouteDown(w http.ResponseWriter, r *http.Request) {
pkt.SetDst(d.Id).RouteDown()
}

func (d *device) showModel(w http.ResponseWriter, r *http.Request) {
view := r.URL.Query().Get("view")
template := "model-" + view + ".tmpl"
if err := d.renderTmpl(w, template, d.Config); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
}
}

type MsgCreated struct {
Id string
Model string
Name string
}

func (d *device) handleCreated(pkt *Packet) {
var msg MsgCreated

pkt.Unmarshal(&msg)

if err := addChild(d, msg.Id, msg.Model, msg.Name, flagLocked); err != nil {
LogError("Adding child failed", "device", d, "msg", msg)
return
}

routesBuild(root)

pkt.BroadcastUp()
}

func (d *device) createChild(w http.ResponseWriter, r *http.Request) {
var msg MsgCreated

Expand All @@ -541,7 +565,7 @@ func (d *device) createChild(w http.ResponseWriter, r *http.Request) {

// TODO validate msg.Id, msg.Model, msg.Name

if err := addChild(d, msg.Id, msg.Model, msg.Name); err != nil {
if err := addChild(d, msg.Id, msg.Model, msg.Name, 0); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
Expand All @@ -552,14 +576,29 @@ func (d *device) createChild(w http.ResponseWriter, r *http.Request) {
// Mark root dirty
deviceDirty(root.Id)

// Route /created msg down
pkt.SetDst(d.Id).SetPath("/created").RouteDown()
// Route /created msg up
pkt.SetDst(d.Id).SetPath("/created").RouteUp()
}

type MsgDestroyed struct {
ChildId string
}

func (d *device) handleDestroyed(pkt *Packet) {
var msg MsgDestroyed

pkt.Unmarshal(&msg)

if err := removeChild(msg.ChildId); err != nil {
LogError("Removing child failed", "device", d, "msg", msg)
return
}

routesBuild(root)

pkt.BroadcastUp()
}

func (d *device) destroyChild(w http.ResponseWriter, r *http.Request) {
var msg MsgDestroyed

Expand All @@ -582,16 +621,6 @@ func (d *device) destroyChild(w http.ResponseWriter, r *http.Request) {
// Mark root dirty
deviceDirty(root.Id)

// Route /destroyed msg down
pkt.SetDst(parentId).SetPath("/destroyed").RouteDown()
}

func (d *device) showNewModal(w http.ResponseWriter, r *http.Request) {
err := d.renderTmpl(w, "modal-new.tmpl", map[string]any{
"models": d.childModels(),
"newid": generateRandomId(),
})
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
}
// Route /destroyed msg up
pkt.SetDst(parentId).SetPath("/destroyed").RouteUp()
}
9 changes: 8 additions & 1 deletion pkg/device/device-linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,11 @@ func (d *device) _buildOS() error {
// Build the device templates using combined funcs
d.templates, err = d.layeredFS.parseFS("template/*.tmpl", d.FuncMap)

// Default handlers for Linux devices
d.PacketHandlers["/created"] = &PacketHandler[MsgCreated]{d.handleCreated}
d.PacketHandlers["/destroyed"] = &PacketHandler[MsgDestroyed]{d.handleDestroyed}
d.PacketHandlers["/downloaded"] = &PacketHandler[MsgDownloaded]{d.handleDownloaded}

return err
}

Expand Down Expand Up @@ -141,7 +146,7 @@ func devicesSetupAPI() {
}
}

func addChild(parent *device, id, model, name string) error {
func addChild(parent *device, id, model, name string, flags flags) error {

var resurrect bool

Expand Down Expand Up @@ -185,6 +190,8 @@ func addChild(parent *device, id, model, name string) error {
return err
}

child._set(flags)

parent.Children = append(parent.Children, id)
devices[id] = child

Expand Down
2 changes: 1 addition & 1 deletion pkg/device/device.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ func (d *device) _build(maker Maker) error {
d._set(flagDemo | flagOnline | flagMetal)
}

// Special handlers
// Default handlers for all devices
d.PacketHandlers["/state"] = &PacketHandler[any]{d.handleState}
d.PacketHandlers["/online"] = &PacketHandler[any]{d.handleOnline}
d.PacketHandlers["/offline"] = &PacketHandler[any]{d.handleOffline}
Expand Down
12 changes: 12 additions & 0 deletions pkg/device/devices.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,15 @@ func getDevice(id string) (*device, error) {
}
return nil, deviceNotFound(id)
}

func aliveDevices() (alive deviceMap) {
devicesMu.RLock()
defer devicesMu.RUnlock()
alive = make(deviceMap)
for id, d := range devices {
if !d.isSet(flagGhost) {
alive[id] = d
}
}
return
}
12 changes: 0 additions & 12 deletions pkg/device/funcs.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,18 +30,6 @@ func (d *device) stateJSON() (string, error) {
return string(bytes), err
}

func aliveDevices() (alive deviceMap) {
devicesMu.RLock()
defer devicesMu.RUnlock()
alive = make(deviceMap)
for id, d := range devices {
if !d.isSet(flagGhost) {
alive[id] = d
}
}
return
}

func devicesJSON() (string, error) {
bytes, err := json.MarshalIndent(aliveDevices(), "", "\t")
return string(bytes), err
Expand Down
2 changes: 1 addition & 1 deletion pkg/device/handle.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ func (h *PacketHandler[T]) cb(pkt *Packet) {
type PacketHandlers map[string]packetHandler

func (d *device) handle(pkt *Packet) {
if d.isSet(flagOnline) || pkt.Path == "/online" {
if d.isSet(flagOnline) || pkt.Path == "/online" || pkt.Path == "/downloaded" {
if handler, ok := d.PacketHandlers[pkt.Path]; ok {
LogDebug("Handling", "pkt", pkt)
d.stateMu.Lock()
Expand Down
18 changes: 18 additions & 0 deletions pkg/device/image.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"bytes"
"encoding/base64"
"fmt"
"html/template"
"io"
"net/http"
"net/url"
Expand Down Expand Up @@ -313,6 +314,17 @@ func (d *device) downloadMsgError(sessionId string, downloadErr error) {
sessionSend(sessionId, string(buf.Bytes()))
}

type MsgDownloaded struct {
DeployParams template.HTML
}

func (d *device) handleDownloaded(pkt *Packet) {
var msg MsgDownloaded
pkt.Unmarshal(&msg)
d.formConfig(string(msg.DeployParams))
pkt.BroadcastUp()
}

func (d *device) downloadImage(w http.ResponseWriter, r *http.Request) {

var sessionId = r.PathValue("sessionId")
Expand Down Expand Up @@ -356,4 +368,10 @@ func (d *device) downloadImage(w http.ResponseWriter, r *http.Request) {
deviceDirty(root.Id)
downlinkClose(d.Id)
}

// Send a /downloaded msg up so uplinks can update their DeployParams

msg := MsgDownloaded{d.DeployParams}
pkt := Packet{Dst: d.Id, Path: "/downloaded"}
pkt.Marshal(&msg).RouteUp()
}
5 changes: 3 additions & 2 deletions pkg/device/pkt.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import (
"net/http"
)

const maxLength = 100 // Max length of packet string

// NoMsg is an empty message type for PacketHandle's
type NoMsg struct{}

Expand Down Expand Up @@ -50,7 +52,6 @@ func (p *Packet) String() string {

// Convert msg to string and truncate if needed
msgStr := fmt.Sprintf("%v", msg)
const maxLength = 100
if len(msgStr) > maxLength {
msgStr = msgStr[:maxLength] + "..."
}
Expand Down Expand Up @@ -152,8 +153,8 @@ func (p *Packet) RouteDown() {
// the websocket, and JSON-decoded by the receiving uplink device.
func (p *Packet) RouteUp() {
LogDebug("RouteUp", "pkt", p)
sessionsRoute(p)
uplinksRoute(p)
sessionsRoute(p)
}

// RouteUp is a device packet handler that routes the packet up
Expand Down
1 change: 1 addition & 0 deletions pkg/device/template/downloaded-detail.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{{ template "device-detail.tmpl" . }}
Empty file.
1 change: 1 addition & 0 deletions pkg/device/template/downloaded-overview.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{{ template "device-overview.tmpl" . }}
Empty file.
Empty file.
4 changes: 2 additions & 2 deletions pkg/device/ws-client.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ func wsClient(conn *websocket.Conn) {
}

devicesMu.RLock()
pkt.Marshal(&devices)
pkt.Marshal(aliveDevices())
devicesMu.RUnlock()

// Send announcement
Expand Down Expand Up @@ -107,7 +107,7 @@ func wsClient(conn *websocket.Conn) {
LogError("Receiving packet", "err", err)
break
}
LogDebug("Route packet DOWN", "pkt", pkt)
LogDebug("-> Route packet DOWN", "pkt", pkt)
downlinksRoute(pkt)
}

Expand Down
6 changes: 3 additions & 3 deletions pkg/device/ws-server.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ func wsServer(conn *websocket.Conn) {
LogError("Expected announcement, got", "path", pkt.Path)
return
}
LogDebug("Announcement", "pkt", pkt)
LogDebug("-> Announcement", "pkt", pkt)

var annDevices = make(deviceMap)
pkt.Unmarshal(&annDevices)
Expand Down Expand Up @@ -77,7 +77,7 @@ func wsServer(conn *websocket.Conn) {
// Announcement is good, reply with /welcome packet

pkt.ClearMsg().SetPath("/welcome")
LogDebug("Sending welcome", "pkt", pkt)
LogDebug("<- Sending welcome", "pkt", pkt)
link.Send(pkt)

// Add as active download link
Expand All @@ -94,7 +94,7 @@ func wsServer(conn *websocket.Conn) {
LogError("Receiving packet", "err", err)
break
}
LogDebug("Route packet UP", "pkt", pkt)
LogDebug("-> Route packet UP", "pkt", pkt)
deviceRouteUp(pkt.Dst, pkt)
}

Expand Down

0 comments on commit df5c561

Please sign in to comment.