Skip to content

Commit c42f640

Browse files
committed
feat(cmd/rofl): Add basic proxy support
1 parent 4f3721f commit c42f640

File tree

5 files changed

+290
-139
lines changed

5 files changed

+290
-139
lines changed

build/rofl/scheduler/metadata.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,6 @@ const (
99
MetadataKeyTLSPk = "net.oasis.tls.pk"
1010
// MetadataKeySchedulerAPI is the name of the metadata key that stores the API endpoint address.
1111
MetadataKeySchedulerAPI = "net.oasis.scheduler.api"
12+
// MetadataKeyProxyDomain is the name of the metadata key that stores the proxy domain.
13+
MetadataKeyProxyDomain = "net.oasis.proxy.domain"
1214
)

cmd/rofl/build/validate.go

Lines changed: 53 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"context"
55
"encoding/json"
66
"fmt"
7+
"strconv"
78
"strings"
89

910
"golang.org/x/net/idna"
@@ -59,9 +60,9 @@ func validateApp(manifest *buildRofl.Manifest) error {
5960
}
6061

6162
// validateComposeFile validates the Docker compose file.
62-
func validateComposeFile(composeFile string, manifest *buildRofl.Manifest) error {
63+
func validateComposeFile(composeFile string, manifest *buildRofl.Manifest) error { //nolint: gocyclo
6364
// Parse the compose file.
64-
options, err := compose.NewProjectOptions([]string{composeFile})
65+
options, err := compose.NewProjectOptions([]string{composeFile}, compose.WithInterpolation(false))
6566
if err != nil {
6667
return fmt.Errorf("failed to set-up compose options: %w", err)
6768
}
@@ -107,6 +108,9 @@ func validateComposeFile(composeFile string, manifest *buildRofl.Manifest) error
107108
if src == "/run/rofl-appd.sock" {
108109
return true
109110
}
111+
if src == "/run/podman.sock" {
112+
return true
113+
}
110114

111115
if strings.HasPrefix(src, "/storage/") {
112116
return true
@@ -129,7 +133,53 @@ func validateComposeFile(composeFile string, manifest *buildRofl.Manifest) error
129133
}
130134
}
131135

132-
return fmt.Errorf("volume '%s:%s' of service '%s' has an invalid external source (should be '/run/rofl-appd.sock' or reside inside '/storage/')", vol.Source, vol.Target, serviceName)
136+
return fmt.Errorf("volume '%s:%s' of service '%s' has an invalid external source (should be '/run/rofl-appd.sock', '/run/podman.sock' or reside inside '/storage/')", vol.Source, vol.Target, serviceName)
137+
}
138+
139+
// Validate ports.
140+
publishedPorts := make(map[uint64]struct{})
141+
for _, port := range service.Ports {
142+
if port.Target == 0 {
143+
return fmt.Errorf("service '%s' has an invalid zero port defined", serviceName)
144+
}
145+
if port.Published == "" || port.Published == "0" {
146+
return fmt.Errorf("port '%d' of service '%s' does not have an explicit published port defined", port.Target, serviceName)
147+
}
148+
publishedPort, err := strconv.ParseUint(port.Published, 10, 16)
149+
if err != nil {
150+
return fmt.Errorf("published port '%s' of service '%s' is invalid: %w", port.Published, serviceName, err)
151+
}
152+
publishedPorts[publishedPort] = struct{}{}
153+
}
154+
155+
// Validate annotations.
156+
for key, value := range service.Annotations {
157+
keyAtoms := strings.Split(key, ".")
158+
switch {
159+
case strings.HasPrefix(key, "net.oasis.proxy.ports"):
160+
port, err := strconv.ParseUint(keyAtoms[4], 10, 16)
161+
if err != nil {
162+
return fmt.Errorf("proxy port annotation of service '%s' has an invalid port: %s", serviceName, keyAtoms[4])
163+
}
164+
if _, ok := publishedPorts[port]; !ok {
165+
return fmt.Errorf("proxy port annotation of service '%s' references an unpublished port '%d'", serviceName, port)
166+
}
167+
168+
// Validate supported annotations.
169+
switch keyAtoms[5] {
170+
case "mode":
171+
// Validate supported modes.
172+
switch value {
173+
case "ignore":
174+
case "passthrough":
175+
case "terminate-tls":
176+
default:
177+
return fmt.Errorf("proxy port annotation of service '%s', port '%d' has an invalid mode: %s", serviceName, port, value)
178+
}
179+
default:
180+
}
181+
default:
182+
}
133183
}
134184
}
135185

cmd/rofl/machine/mgmt.go

Lines changed: 0 additions & 134 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,10 @@ package machine
33
import (
44
"context"
55
"fmt"
6-
"time"
76

87
"github.com/spf13/cobra"
98

109
"github.com/oasisprotocol/oasis-core/go/common/cbor"
11-
"github.com/oasisprotocol/oasis-sdk/client-sdk/go/client"
1210
"github.com/oasisprotocol/oasis-sdk/client-sdk/go/connection"
1311
"github.com/oasisprotocol/oasis-sdk/client-sdk/go/modules/rofl"
1412
"github.com/oasisprotocol/oasis-sdk/client-sdk/go/modules/roflmarket"
@@ -21,135 +19,6 @@ import (
2119
)
2220

2321
var (
24-
showCmd = &cobra.Command{
25-
Use: "show [<machine-name>]",
26-
Short: "Show information about a machine",
27-
Args: cobra.MaximumNArgs(1),
28-
Run: func(_ *cobra.Command, args []string) {
29-
_, deployment, npa := roflCommon.LoadManifestAndSetNPA(&roflCommon.ManifestOptions{
30-
NeedAppID: true,
31-
NeedAdmin: false,
32-
})
33-
34-
machine, machineName, machineID := resolveMachine(args, deployment)
35-
36-
// Establish connection with the target network.
37-
ctx := context.Background()
38-
conn, err := connection.Connect(ctx, npa.Network)
39-
cobra.CheckErr(err)
40-
41-
// Resolve provider address.
42-
providerAddr, _, err := common.ResolveLocalAccountOrAddress(npa.Network, machine.Provider)
43-
if err != nil {
44-
cobra.CheckErr(fmt.Sprintf("Invalid provider address: %s", err))
45-
}
46-
47-
insDsc, err := conn.Runtime(npa.ParaTime).ROFLMarket.Instance(ctx, client.RoundLatest, *providerAddr, machineID)
48-
cobra.CheckErr(err)
49-
50-
insCmds, err := conn.Runtime(npa.ParaTime).ROFLMarket.InstanceCommands(ctx, client.RoundLatest, *providerAddr, machineID)
51-
cobra.CheckErr(err)
52-
53-
fmt.Printf("Name: %s\n", machineName)
54-
fmt.Printf("Provider: %s\n", insDsc.Provider)
55-
fmt.Printf("ID: %s\n", insDsc.ID)
56-
fmt.Printf("Offer: %s\n", insDsc.Offer)
57-
fmt.Printf("Status: %s\n", insDsc.Status)
58-
fmt.Printf("Creator: %s\n", insDsc.Creator)
59-
fmt.Printf("Admin: %s\n", insDsc.Admin)
60-
switch insDsc.NodeID {
61-
case nil:
62-
fmt.Printf("Node ID: <none>\n")
63-
default:
64-
fmt.Printf("Node ID: %s\n", insDsc.NodeID)
65-
}
66-
67-
fmt.Printf("Created at: %s\n", time.Unix(int64(insDsc.CreatedAt), 0))
68-
fmt.Printf("Updated at: %s\n", time.Unix(int64(insDsc.UpdatedAt), 0))
69-
fmt.Printf("Paid until: %s\n", time.Unix(int64(insDsc.PaidUntil), 0))
70-
71-
if len(insDsc.Metadata) > 0 {
72-
fmt.Printf("Metadata:\n")
73-
for key, value := range insDsc.Metadata {
74-
fmt.Printf(" %s: %s\n", key, value)
75-
}
76-
}
77-
78-
fmt.Printf("Resources:\n")
79-
80-
fmt.Printf(" TEE: ")
81-
switch insDsc.Resources.TEE {
82-
case roflmarket.TeeTypeSGX:
83-
fmt.Printf("Intel SGX\n")
84-
case roflmarket.TeeTypeTDX:
85-
fmt.Printf("Intel TDX\n")
86-
default:
87-
fmt.Printf("[unknown: %d]\n", insDsc.Resources.TEE)
88-
}
89-
90-
fmt.Printf(" Memory: %d MiB\n", insDsc.Resources.Memory)
91-
fmt.Printf(" vCPUs: %d\n", insDsc.Resources.CPUCount)
92-
fmt.Printf(" Storage: %d MiB\n", insDsc.Resources.Storage)
93-
if insDsc.Resources.GPU != nil {
94-
fmt.Printf(" GPU:\n")
95-
if insDsc.Resources.GPU.Model != "" {
96-
fmt.Printf(" Model: %s\n", insDsc.Resources.GPU.Model)
97-
} else {
98-
fmt.Printf(" Model: <any>\n")
99-
}
100-
fmt.Printf(" Count: %d\n", insDsc.Resources.GPU.Count)
101-
}
102-
103-
switch insDsc.Deployment {
104-
default:
105-
fmt.Printf("Deployment:\n")
106-
fmt.Printf(" App ID: %s\n", insDsc.Deployment.AppID)
107-
108-
if len(insDsc.Deployment.Metadata) > 0 {
109-
fmt.Printf(" Metadata:\n")
110-
for key, value := range insDsc.Deployment.Metadata {
111-
fmt.Printf(" %s: %s\n", key, value)
112-
}
113-
}
114-
case nil:
115-
fmt.Printf("Deployment: <no current deployment>\n")
116-
}
117-
118-
// Show commands.
119-
fmt.Printf("Commands:\n")
120-
if len(insCmds) > 0 {
121-
for _, qc := range insCmds {
122-
fmt.Printf(" - ID: %s\n", qc.ID)
123-
124-
var cmd scheduler.Command
125-
err := cbor.Unmarshal(qc.Cmd, &cmd)
126-
switch err {
127-
case nil:
128-
// Decodable scheduler command.
129-
fmt.Printf(" Method: %s\n", cmd.Method)
130-
fmt.Printf(" Args:\n")
131-
132-
switch cmd.Method {
133-
case scheduler.MethodDeploy:
134-
showCommandArgs(npa, cmd.Args, scheduler.DeployRequest{})
135-
case scheduler.MethodRestart:
136-
showCommandArgs(npa, cmd.Args, scheduler.RestartRequest{})
137-
case scheduler.MethodTerminate:
138-
showCommandArgs(npa, cmd.Args, scheduler.TerminateRequest{})
139-
default:
140-
showCommandArgs(npa, cmd.Args, make(map[string]interface{}))
141-
}
142-
default:
143-
// Unknown command format.
144-
fmt.Printf(" <unknown format: %X>\n", qc.Cmd)
145-
}
146-
}
147-
} else {
148-
fmt.Printf(" <no queued commands>\n")
149-
}
150-
},
151-
}
152-
15322
restartCmd = &cobra.Command{
15423
Use: "restart [<machine-name>]",
15524
Short: "Restart a running machine or start a stopped one",
@@ -401,9 +270,6 @@ func showCommandArgs[V any](npa *common.NPASelection, raw []byte, args V) {
401270
}
402271

403272
func init() {
404-
showCmd.Flags().AddFlagSet(common.SelectorFlags)
405-
showCmd.Flags().AddFlagSet(roflCommon.DeploymentFlags)
406-
407273
restartCmd.Flags().AddFlagSet(common.SelectorFlags)
408274
restartCmd.Flags().AddFlagSet(common.RuntimeTxFlags)
409275
restartCmd.Flags().AddFlagSet(roflCommon.DeploymentFlags)

0 commit comments

Comments
 (0)