Skip to content

Commit f8cd26d

Browse files
fix: support direct rofl set-admin
1 parent e663fe8 commit f8cd26d

4 files changed

Lines changed: 105 additions & 44 deletions

File tree

cmd/rofl/set_admin.go

Lines changed: 90 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66

77
"github.com/spf13/cobra"
88

9+
"github.com/oasisprotocol/oasis-sdk/client-sdk/go/client"
910
"github.com/oasisprotocol/oasis-sdk/client-sdk/go/connection"
1011
"github.com/oasisprotocol/oasis-sdk/client-sdk/go/modules/rofl"
1112

@@ -16,45 +17,51 @@ import (
1617
)
1718

1819
var setAdminCmd = &cobra.Command{
19-
Use: "set-admin <new-admin>",
20-
Short: "Change the administrator of the application in ROFL",
20+
Use: "set-admin [<app-id>] <new-admin>",
21+
Short: "Change the administrator of a ROFL application",
2122
Aliases: []string{"change-admin"},
22-
Args: cobra.ExactArgs(1),
23+
Args: cobra.RangeArgs(1, 2),
2324
Run: func(_ *cobra.Command, args []string) {
25+
cfg := cliConfig.Global()
26+
npa := common.GetNPASelection(cfg)
2427
txCfg := common.GetTransactionConfig()
2528

26-
manifest, deployment, npa := roflCommon.LoadManifestAndSetNPA(&roflCommon.ManifestOptions{
27-
NeedAppID: true,
28-
NeedAdmin: true,
29-
})
29+
var (
30+
rawAppID string
31+
newAdminArg string
32+
manifest *buildRofl.Manifest
33+
deployment *buildRofl.Deployment
34+
useManifest bool
35+
)
36+
switch len(args) {
37+
case 2:
38+
// Direct mode: oasis rofl set-admin <app-id> <new-admin>
39+
rawAppID = args[0]
40+
newAdminArg = args[1]
41+
case 1:
42+
// Manifest mode: oasis rofl set-admin <new-admin>
43+
newAdminArg = args[0]
44+
manifest, deployment, npa = roflCommon.LoadManifestAndSetNPA(&roflCommon.ManifestOptions{
45+
NeedAppID: true,
46+
NeedAdmin: true,
47+
})
48+
rawAppID = deployment.AppID
49+
useManifest = true
50+
}
3051

3152
var appID rofl.AppID
32-
if err := appID.UnmarshalText([]byte(deployment.AppID)); err != nil {
53+
if err := appID.UnmarshalText([]byte(rawAppID)); err != nil {
3354
cobra.CheckErr(fmt.Errorf("malformed ROFL app ID: %w", err))
3455
}
3556

3657
npa.MustHaveAccount()
3758
npa.MustHaveParaTime()
3859

39-
if deployment.Policy == nil {
40-
cobra.CheckErr("no policy configured in the manifest")
41-
}
42-
43-
oldAdminAddr, _, err := common.ResolveLocalAccountOrAddress(npa.Network, deployment.Admin)
44-
if err != nil {
45-
cobra.CheckErr(fmt.Errorf("bad current administrator address: %w", err))
46-
}
47-
48-
newAdminAddr, newAdminEthAddr, err := common.ResolveLocalAccountOrAddress(npa.Network, args[0])
60+
newAdminAddr, newAdminEthAddr, err := common.ResolveLocalAccountOrAddress(npa.Network, newAdminArg)
4961
if err != nil {
5062
cobra.CheckErr(fmt.Errorf("invalid new admin address: %w", err))
5163
}
5264

53-
if *oldAdminAddr == *newAdminAddr {
54-
fmt.Println("New admin is the same as the current admin, nothing to do.")
55-
return
56-
}
57-
5865
// When not in offline mode, connect to the given network endpoint.
5966
ctx := context.Background()
6067
var conn connection.Connection
@@ -63,45 +70,88 @@ var setAdminCmd = &cobra.Command{
6370
cobra.CheckErr(err)
6471
}
6572

73+
// Build the update body.
74+
updateBody := rofl.Update{
75+
ID: appID,
76+
Admin: newAdminAddr,
77+
}
78+
79+
if useManifest {
80+
// Manifest mode: use local policy, metadata, secrets.
81+
if deployment.Policy == nil {
82+
cobra.CheckErr("no policy configured in the manifest")
83+
}
84+
85+
oldAdminAddr, _, err := common.ResolveLocalAccountOrAddress(npa.Network, deployment.Admin)
86+
if err != nil {
87+
cobra.CheckErr(fmt.Errorf("bad current administrator address: %w", err))
88+
}
89+
90+
if *oldAdminAddr == *newAdminAddr {
91+
fmt.Println("New admin is the same as the current admin, nothing to do.")
92+
return
93+
}
94+
95+
fmt.Printf("Old admin: %s\n", common.PrettyAddress(oldAdminAddr.String()))
96+
97+
updateBody.Policy = *deployment.Policy.AsDescriptor()
98+
updateBody.Metadata = manifest.GetMetadata(roflCommon.DeploymentName)
99+
updateBody.Secrets = buildRofl.PrepareSecrets(deployment.Secrets)
100+
} else {
101+
// Direct mode: fetch current app config from chain.
102+
if txCfg.Offline {
103+
cobra.CheckErr("direct mode requires network access")
104+
}
105+
106+
appCfg, err := conn.Runtime(npa.ParaTime).ROFL.App(ctx, client.RoundLatest, appID)
107+
cobra.CheckErr(err)
108+
109+
if appCfg.Admin != nil && *appCfg.Admin == *newAdminAddr {
110+
fmt.Println("New admin is the same as the current admin, nothing to do.")
111+
return
112+
}
113+
114+
if appCfg.Admin != nil {
115+
fmt.Printf("Old admin: %s\n", common.PrettyAddress(appCfg.Admin.String()))
116+
}
117+
118+
updateBody.Policy = appCfg.Policy
119+
updateBody.Metadata = appCfg.Metadata
120+
updateBody.Secrets = appCfg.Secrets
121+
}
122+
66123
newAdminStr := newAdminAddr.String()
67124
if newAdminEthAddr != nil {
68125
newAdminStr = newAdminEthAddr.Hex()
69126
}
70127

71-
fmt.Printf("App ID: %s\n", deployment.AppID)
72-
fmt.Printf("Old admin: %s\n", common.PrettyAddress(oldAdminAddr.String()))
128+
fmt.Printf("App ID: %s\n", appID)
73129
fmt.Printf("New admin: %s\n", common.PrettyAddress(newAdminStr))
74130

75-
secrets := buildRofl.PrepareSecrets(deployment.Secrets)
76-
77-
tx := rofl.NewUpdateTx(nil, &rofl.Update{
78-
ID: appID,
79-
Policy: *deployment.Policy.AsDescriptor(),
80-
Admin: newAdminAddr,
81-
Metadata: manifest.GetMetadata(roflCommon.DeploymentName),
82-
Secrets: secrets,
83-
})
131+
tx := rofl.NewUpdateTx(nil, &updateBody)
84132

85-
acc := common.LoadAccount(cliConfig.Global(), npa.AccountName)
133+
acc := common.LoadAccount(cfg, npa.AccountName)
86134
sigTx, meta, err := common.SignParaTimeTransaction(ctx, npa, acc, conn, tx, nil)
87135
cobra.CheckErr(err)
88136

89137
if !common.BroadcastOrExportTransaction(ctx, npa, conn, sigTx, meta, nil) {
90138
return
91139
}
92140

93-
// Transaction succeeded — update the manifest with the new admin.
94-
deployment.Admin = args[0]
95-
if err = manifest.Save(); err != nil {
96-
cobra.CheckErr(fmt.Errorf("failed to update manifest: %w", err))
141+
// Transaction succeeded — update the manifest if available.
142+
if manifest != nil {
143+
deployment.Admin = newAdminArg
144+
if err = manifest.Save(); err != nil {
145+
cobra.CheckErr(fmt.Errorf("failed to update manifest: %w", err))
146+
}
97147
}
98148

99149
fmt.Printf("ROFL admin changed to %s.\n", common.PrettyAddress(newAdminStr))
100150
},
101151
}
102152

103153
func init() {
104-
common.AddAccountFlag(setAdminCmd)
154+
common.AddSelectorFlags(setAdminCmd)
105155
setAdminCmd.Flags().AddFlagSet(common.RuntimeTxFlags)
106156
setAdminCmd.Flags().AddFlagSet(roflCommon.DeploymentFlags)
107157
}

docs/rofl.md

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -328,11 +328,22 @@ their latest versions. This includes:
328328
### Change ROFL app administrator {#set-admin}
329329

330330
Run `rofl set-admin` to transfer ownership of a ROFL app to a new
331-
administrator. The transaction is signed by the current admin and, on success,
332-
the manifest is updated with the new admin.
331+
administrator. The transaction must be signed by the current admin.
332+
333+
If the current directory contains a ROFL manifest, the manifest is updated with
334+
the new admin after a successful transaction.
333335

334336
![code shell](../examples/rofl/set-admin.in.static)
335337

338+
To change the administrator directly on an existing app without a local
339+
manifest, run:
340+
341+
```bash
342+
oasis rofl set-admin <app-id> <new-admin>
343+
```
344+
345+
This mode requires network access and does not modify local files.
346+
336347
### Change ROFL machine administrator {#machine-set-admin}
337348

338349
Run `rofl machine set-admin` to change the administrator of an individual
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
oasis rofl machine set-admin [<machine-name> | <provider-address>:<machine-id>] <new-admin>
1+
oasis rofl machine set-admin bob

examples/rofl/set-admin.in.static

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
oasis rofl set-admin <new-admin>
1+
oasis rofl set-admin bob

0 commit comments

Comments
 (0)