Skip to content

Commit 3bb881e

Browse files
OisinKynebussyjd
authored andcommitted
Opus's fixes to the fixes
1 parent 90da20f commit 3bb881e

10 files changed

Lines changed: 779 additions & 116 deletions

File tree

.github/workflows/docker-publish-x402.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ on:
44
push:
55
branches:
66
- main
7-
- feat/secure-enclave-inference
87
tags:
98
- 'v*'
109
paths:

.github/workflows/lint-test.yaml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
name: Lint and Test Charts
22

33
on:
4-
push:
5-
branches: [ main ]
64
pull_request:
75
branches: [ main ]
86

cmd/obol/sell.go

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ func sellCommand(cfg *config.Config) *cli.Command {
5050
sellStatusCommand(cfg),
5151
sellTestCommand(cfg),
5252
sellStopCommand(cfg),
53+
sellUpdateCommand(cfg),
5354
sellDeleteCommand(cfg),
5455
sellPricingCommand(cfg),
5556
sellRegisterCommand(cfg),
@@ -1334,6 +1335,137 @@ func sellStopCommand(cfg *config.Config) *cli.Command {
13341335
}
13351336
}
13361337

1338+
// ---------------------------------------------------------------------------
1339+
// sell update
1340+
// ---------------------------------------------------------------------------
1341+
1342+
func sellUpdateCommand(cfg *config.Config) *cli.Command {
1343+
return &cli.Command{
1344+
Name: "update",
1345+
Usage: "Update pricing or wallet on an existing ServiceOffer in place",
1346+
ArgsUsage: "<name>",
1347+
Description: `Patches a live ServiceOffer without deleting it. Only the fields you pass
1348+
are changed; everything else is preserved. The serviceoffer-controller will
1349+
reconcile the new payment config automatically.
1350+
1351+
Switching price models (e.g. per-request → per-mtok) nulls the previous keys
1352+
so the controller picks up the new model.
1353+
1354+
Examples:
1355+
obol sell update my-api -n llm --per-request 0.002
1356+
obol sell update my-api -n llm --per-mtok 5.0
1357+
obol sell update my-api -n llm --wallet 0xNew... --chain base`,
1358+
Flags: []cli.Flag{
1359+
&cli.StringFlag{
1360+
Name: "namespace",
1361+
Aliases: []string{"n"},
1362+
Usage: "Namespace of the ServiceOffer",
1363+
Required: true,
1364+
},
1365+
&cli.StringFlag{
1366+
Name: "wallet",
1367+
Aliases: []string{"w"},
1368+
Usage: "New USDC recipient wallet address",
1369+
},
1370+
&cli.StringFlag{
1371+
Name: "chain",
1372+
Usage: "New payment chain (base, base-sepolia, ethereum)",
1373+
},
1374+
&cli.StringFlag{
1375+
Name: "price",
1376+
Usage: "New per-request price in USDC (alias for --per-request)",
1377+
},
1378+
&cli.StringFlag{
1379+
Name: "per-request",
1380+
Usage: "New per-request price in USDC",
1381+
},
1382+
&cli.StringFlag{
1383+
Name: "per-mtok",
1384+
Usage: "New per-million-tokens price in USDC",
1385+
},
1386+
&cli.StringFlag{
1387+
Name: "per-hour",
1388+
Usage: "New per-compute-hour price in USDC",
1389+
},
1390+
},
1391+
Action: func(ctx context.Context, cmd *cli.Command) error {
1392+
u := getUI(cmd)
1393+
if cmd.NArg() == 0 {
1394+
return errors.New("name required: obol sell update <name> -n <ns> [--per-request N | --per-mtok N | --per-hour N] [--wallet 0x...] [--chain base]")
1395+
}
1396+
1397+
name := cmd.Args().First()
1398+
if err := validate.Name(name); err != nil {
1399+
return err
1400+
}
1401+
ns := cmd.String("namespace")
1402+
1403+
if _, err := kubectlOutput(cfg, "get", "serviceoffers.obol.org", name, "-n", ns, "-o", "name"); err != nil {
1404+
return fmt.Errorf("ServiceOffer %s/%s not found: %w", ns, name, err)
1405+
}
1406+
1407+
payment := map[string]any{}
1408+
1409+
if wallet := strings.TrimSpace(cmd.String("wallet")); wallet != "" {
1410+
if err := x402verifier.ValidateWallet(wallet); err != nil {
1411+
return err
1412+
}
1413+
payment["payTo"] = wallet
1414+
}
1415+
1416+
if chain := strings.TrimSpace(cmd.String("chain")); chain != "" {
1417+
payment["network"] = chain
1418+
}
1419+
1420+
priceSet := cmd.String("price") != "" || cmd.String("per-request") != "" || cmd.String("per-mtok") != "" || cmd.String("per-hour") != ""
1421+
if priceSet {
1422+
priceTable, err := resolvePriceTable(cmd, true)
1423+
if err != nil {
1424+
return err
1425+
}
1426+
1427+
price := map[string]any{
1428+
"perRequest": nil,
1429+
"perMTok": nil,
1430+
"perHour": nil,
1431+
}
1432+
switch {
1433+
case priceTable.PerRequest != "":
1434+
price["perRequest"] = priceTable.PerRequest
1435+
case priceTable.PerMTok != "":
1436+
price["perMTok"] = priceTable.PerMTok
1437+
case priceTable.PerHour != "":
1438+
price["perHour"] = priceTable.PerHour
1439+
}
1440+
payment["price"] = price
1441+
}
1442+
1443+
if len(payment) == 0 {
1444+
return errors.New("nothing to update: pass at least one of --per-request / --per-mtok / --per-hour / --wallet / --chain")
1445+
}
1446+
1447+
patch := map[string]any{
1448+
"spec": map[string]any{
1449+
"payment": payment,
1450+
},
1451+
}
1452+
patchBytes, err := json.Marshal(patch)
1453+
if err != nil {
1454+
return fmt.Errorf("marshal patch: %w", err)
1455+
}
1456+
1457+
if err := kubectlRun(cfg, "patch", "serviceoffers.obol.org", name, "-n", ns, "--type=merge", "-p", string(patchBytes)); err != nil {
1458+
return fmt.Errorf("failed to patch serviceoffer: %w", err)
1459+
}
1460+
1461+
u.Successf("ServiceOffer %s/%s updated", ns, name)
1462+
u.Info("The controller will reconcile the new payment config.")
1463+
u.Infof("Check status: obol sell status %s -n %s", name, ns)
1464+
return nil
1465+
},
1466+
}
1467+
}
1468+
13371469
// ---------------------------------------------------------------------------
13381470
// sell delete
13391471
// ---------------------------------------------------------------------------

internal/embed/infrastructure/values/monitoring.yaml.gotmpl

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,15 @@ nodeExporter:
4848
enabled: true
4949

5050
prometheus-node-exporter:
51+
# Pin to v1.11.0 — upstream v1.10.2 ships a multi-arch manifest that fails the
52+
# containerd image-integrity check on Apple Silicon (digest mismatch →
53+
# ImagePullBackOff). v1.11.0 pulls cleanly on both arm64 and amd64. Digest
54+
# pin defends against a re-tag landing a bad arm64 layer again.
55+
image:
56+
registry: quay.io
57+
repository: prometheus/node-exporter
58+
tag: v1.11.0
59+
digest: sha256:2f0cc335ef9ea15d6c96e1c0d693d8b57c0b794d0244b22313a6c162bd1cb1b8
5160
resources:
5261
requests:
5362
cpu: 10m

0 commit comments

Comments
 (0)