44 "context"
55 "fmt"
66 "os"
7+ "strings"
78
89 "github.com/spf13/cobra"
910
@@ -20,13 +21,14 @@ import (
2021 buildRoflProvider "github.com/oasisprotocol/cli/build/rofl/provider"
2122 "github.com/oasisprotocol/cli/build/rofl/scheduler"
2223 "github.com/oasisprotocol/cli/cmd/common"
24+ roflCmdBuild "github.com/oasisprotocol/cli/cmd/rofl/build"
2325 roflCommon "github.com/oasisprotocol/cli/cmd/rofl/common"
2426 cliConfig "github.com/oasisprotocol/cli/config"
2527)
2628
2729var (
2830 restartCmd = & cobra.Command {
29- Use : "restart [<machine-name>]" ,
31+ Use : "restart [<machine-name> | <provider-address>:<machine-id> ]" ,
3032 Short : "Restart a running machine or start a stopped one" ,
3133 Args : cobra .MaximumNArgs (1 ),
3234 Run : func (_ * cobra.Command , args []string ) {
4244 }
4345
4446 stopCmd = & cobra.Command {
45- Use : "stop [<machine-name>]" ,
47+ Use : "stop [<machine-name> | <provider-address>:<machine-id> ]" ,
4648 Short : "Stop a machine" ,
4749 Aliases : []string {"terminate" },
4850 Args : cobra .MaximumNArgs (1 ),
@@ -59,30 +61,21 @@ var (
5961 }
6062
6163 removeCmd = & cobra.Command {
62- Use : "remove [<machine-name>]" ,
64+ Use : "remove [<machine-name> | <provider-address>:<machine-id> ]" ,
6365 Short : "Cancel rental and remove the machine" ,
6466 Aliases : []string {"cancel" , "rm" },
6567 Args : cobra .MaximumNArgs (1 ),
6668 Run : func (_ * cobra.Command , args []string ) {
67- txCfg := common .GetTransactionConfig ()
68-
69- manifest , deployment , npa := roflCommon .LoadManifestAndSetNPA (& roflCommon.ManifestOptions {
69+ machine , machineName , machineID , manifest , _ , providerAddr , npa := resolveMachineManifestNpa (args , & roflCommon.ManifestOptions {
7070 NeedAppID : true ,
7171 NeedAdmin : false ,
7272 })
7373
74- machine , machineName , machineID := resolveMachine (args , deployment )
75-
76- // Resolve provider address.
77- providerAddr , _ , err := common .ResolveLocalAccountOrAddress (npa .Network , machine .Provider )
78- if err != nil {
79- cobra .CheckErr (fmt .Sprintf ("Invalid provider address: %s" , err ))
80- }
81-
8274 // When not in offline mode, connect to the given network endpoint.
8375 ctx := context .Background ()
76+ var err error
8477 var conn connection.Connection
85- if ! txCfg .Offline {
78+ if ! common . GetTransactionConfig () .Offline {
8679 conn , err = connection .Connect (ctx , npa .Network )
8780 cobra .CheckErr (err )
8881 }
@@ -111,20 +104,21 @@ var (
111104 // Update manifest to clear the machine ID as it has been cancelled.
112105 machine .ID = ""
113106
114- if err = manifest .Save (); err != nil {
115- cobra .CheckErr (fmt .Errorf ("failed to update manifest: %w" , err ))
107+ if manifest != nil {
108+ if err = manifest .Save (); err != nil {
109+ cobra .CheckErr (fmt .Errorf ("failed to update manifest: %w" , err ))
110+ }
116111 }
117112 },
118113 }
119114
120115 changeAdminCmd = & cobra.Command {
121- Use : "change-admin [<machine-name>] <new-admin>" ,
116+ Use : "change-admin [<machine-name> | <provider-address>:<machine-id> ] <new-admin>" ,
122117 Short : "Change the machine administrator" ,
123118 Args : cobra .RangeArgs (1 , 2 ),
124119 Run : func (_ * cobra.Command , args []string ) {
125120 txCfg := common .GetTransactionConfig ()
126-
127- _ , deployment , npa := roflCommon .LoadManifestAndSetNPA (& roflCommon.ManifestOptions {
121+ machine , machineName , machineID , _ , _ , providerAddr , npa := resolveMachineManifestNpa (args , & roflCommon.ManifestOptions {
128122 NeedAppID : true ,
129123 NeedAdmin : false ,
130124 })
@@ -141,18 +135,10 @@ var (
141135 args = args [:1 ]
142136 }
143137
144- machine , machineName , machineID := resolveMachine (args , deployment )
145-
146- // Resolve provider address.
147- providerAddr , _ , err := common .ResolveLocalAccountOrAddress (npa .Network , machine .Provider )
148- if err != nil {
149- cobra .CheckErr (fmt .Sprintf ("Invalid provider address: %s" , err ))
150- }
151-
152138 // Resolve new admin address.
153139 newAdminAddr , _ , err := common .ResolveLocalAccountOrAddress (npa .Network , newAdminAddress )
154140 if err != nil {
155- cobra .CheckErr (fmt .Sprintf ( "Invalid admin address: %s " , err ))
141+ cobra .CheckErr (fmt .Errorf ( "invalid admin address: %w " , err ))
156142 }
157143
158144 // When not in offline mode, connect to the given network endpoint.
@@ -196,13 +182,13 @@ var (
196182 }
197183
198184 topUpCmd = & cobra.Command {
199- Use : "top-up [<machine-name>]" ,
185+ Use : "top-up [<machine-name> | <provider-address>:<machine-id> ]" ,
200186 Short : "Top-up payment for a machine" ,
201187 Args : cobra .MaximumNArgs (1 ),
202188 Run : func (_ * cobra.Command , args []string ) {
203189 txCfg := common .GetTransactionConfig ()
204190
205- _ , deployment , npa := roflCommon . LoadManifestAndSetNPA ( & roflCommon.ManifestOptions {
191+ machine , machineName , machineID , _ , _ , providerAddr , npa := resolveMachineManifestNpa ( args , & roflCommon.ManifestOptions {
206192 NeedAppID : true ,
207193 NeedAdmin : false ,
208194 })
@@ -213,14 +199,6 @@ var (
213199 ctx = context .WithValue (ctx , config .ContextKeyParaTimeCfg , npa .ParaTime )
214200 }
215201
216- machine , machineName , machineID := resolveMachine (args , deployment )
217-
218- // Resolve provider address.
219- providerAddr , _ , err := common .ResolveLocalAccountOrAddress (npa .Network , machine .Provider )
220- if err != nil {
221- cobra .CheckErr (fmt .Sprintf ("invalid provider address: %s" , err ))
222- }
223-
224202 // Parse machine payment term.
225203 if roflCommon .Term == "" {
226204 cobra .CheckErr ("no term period specified. Use --term to specify it" )
@@ -231,6 +209,7 @@ var (
231209 }
232210
233211 // When not in offline mode, connect to the given network endpoint.
212+ var err error
234213 var conn connection.Connection
235214 var offer * roflmarket.Offer
236215 if ! txCfg .Offline {
@@ -240,7 +219,7 @@ var (
240219 // Fetch chosen offer, so we can calculate price.
241220 offers , err := conn .Runtime (npa .ParaTime ).ROFLMarket .Offers (ctx , client .RoundLatest , * providerAddr )
242221 if err != nil {
243- cobra .CheckErr (fmt .Errorf ("failed to query provider: %s " , err ))
222+ cobra .CheckErr (fmt .Errorf ("failed to query provider: %w " , err ))
244223 }
245224
246225 for _ , of := range offers {
@@ -249,6 +228,18 @@ var (
249228 break
250229 }
251230 }
231+ if offer == nil {
232+ machineDsc , err := conn .Runtime (npa .ParaTime ).ROFLMarket .Instance (ctx , client .RoundLatest , * providerAddr , machineID )
233+ if err != nil {
234+ cobra .CheckErr (fmt .Errorf ("failed to query machine: %w" , err ))
235+ }
236+ for _ , of := range offers {
237+ if of .ID == machineDsc .Offer {
238+ offer = of
239+ break
240+ }
241+ }
242+ }
252243 if offer == nil {
253244 cobra .CheckErr (fmt .Errorf ("unable to find existing machine offer (%s) among market offers" , machine .Offer ))
254245 }
@@ -295,7 +286,59 @@ var (
295286 }
296287)
297288
298- func resolveMachine (args []string , deployment * buildRofl.Deployment ) (* buildRofl.Machine , string , roflmarket.InstanceID ) {
289+ func resolveMachineManifestNpa (args []string , manifestOpts * roflCommon.ManifestOptions ) (machineCfg * buildRofl.Machine , machineName string , machineID roflmarket.InstanceID , manifest * buildRofl.Manifest , extraCfg * roflCmdBuild.AppExtraConfig , providerAddr * types.Address , npa * common.NPASelection ) {
290+ var err error
291+ machineCfg , machineName , machineID = resolveMachineFromArgs (args )
292+ if machineCfg != nil {
293+ cfg := cliConfig .Global ()
294+ npa = common .GetNPASelection (cfg )
295+ } else {
296+ var deployment * buildRofl.Deployment
297+ manifest , deployment , npa = roflCommon .LoadManifestAndSetNPA (manifestOpts )
298+
299+ machineCfg , machineName , machineID = resolveMachineFromManifest (args , deployment )
300+
301+ var appID rofl.AppID
302+ if err := appID .UnmarshalText ([]byte (deployment .AppID )); err != nil {
303+ cobra .CheckErr (fmt .Errorf ("malformed app id: %w" , err ))
304+ }
305+
306+ var err error
307+ extraCfg , err = roflCmdBuild .ValidateApp (manifest , roflCmdBuild.ValidationOpts {
308+ Offline : true ,
309+ })
310+ if err != nil {
311+ cobra .CheckErr (fmt .Errorf ("failed to validate app: %w" , err ))
312+ }
313+ }
314+
315+ providerAddr , _ , err = common .ResolveLocalAccountOrAddress (npa .Network , machineCfg .Provider )
316+ if err != nil {
317+ cobra .CheckErr (fmt .Errorf ("invalid provider address: %w" , err ))
318+ }
319+
320+ return
321+ }
322+
323+ func resolveMachineFromArgs (args []string ) (* buildRofl.Machine , string , roflmarket.InstanceID ) {
324+ if len (args ) > 0 {
325+ parts := strings .Split (args [0 ], ":" )
326+ if len (parts ) == 2 {
327+ m := & buildRofl.Machine {
328+ Provider : parts [0 ],
329+ ID : parts [1 ],
330+ }
331+ var machineID roflmarket.InstanceID
332+ if err := machineID .UnmarshalText ([]byte (m .ID )); err != nil {
333+ cobra .CheckErr (fmt .Errorf ("malformed machine ID: %w" , err ))
334+ }
335+ return m , args [0 ], machineID
336+ }
337+ }
338+ return nil , "" , roflmarket.InstanceID {}
339+ }
340+
341+ func resolveMachineFromManifest (args []string , deployment * buildRofl.Deployment ) (* buildRofl.Machine , string , roflmarket.InstanceID ) {
299342 machineName := buildRofl .DefaultMachineName
300343 if len (args ) > 0 {
301344 machineName = args [0 ]
@@ -333,25 +376,16 @@ func resolveMachine(args []string, deployment *buildRofl.Deployment) (*buildRofl
333376}
334377
335378func queueCommand (cliArgs []string , method string , args any , msgAfter string ) {
336- txCfg := common .GetTransactionConfig ()
337-
338- _ , deployment , npa := roflCommon .LoadManifestAndSetNPA (& roflCommon.ManifestOptions {
379+ machine , machineName , machineID , _ , _ , providerAddr , npa := resolveMachineManifestNpa (cliArgs , & roflCommon.ManifestOptions {
339380 NeedAppID : true ,
340381 NeedAdmin : false ,
341382 })
342383
343- machine , machineName , machineID := resolveMachine (cliArgs , deployment )
344-
345- // Resolve provider address.
346- providerAddr , _ , err := common .ResolveLocalAccountOrAddress (npa .Network , machine .Provider )
347- if err != nil {
348- cobra .CheckErr (fmt .Sprintf ("Invalid provider address: %s" , err ))
349- }
350-
351384 // When not in offline mode, connect to the given network endpoint.
352385 ctx := context .Background ()
386+ var err error
353387 var conn connection.Connection
354- if ! txCfg .Offline {
388+ if ! common . GetTransactionConfig () .Offline {
355389 conn , err = connection .Connect (ctx , npa .Network )
356390 cobra .CheckErr (err )
357391 }
0 commit comments