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,26 @@ 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 , _ , npa := resolveMachineManifestNpa (args , & roflCommon.ManifestOptions {
7070 NeedAppID : true ,
7171 NeedAdmin : false ,
7272 })
7373
74- machine , machineName , machineID := resolveMachine (args , deployment )
75-
7674 // Resolve provider address.
7775 providerAddr , _ , err := common .ResolveLocalAccountOrAddress (npa .Network , machine .Provider )
7876 if err != nil {
79- cobra .CheckErr (fmt .Sprintf ( "Invalid provider address: %s " , err ))
77+ cobra .CheckErr (fmt .Errorf ( "invalid provider address: %w " , err ))
8078 }
8179
8280 // When not in offline mode, connect to the given network endpoint.
8381 ctx := context .Background ()
8482 var conn connection.Connection
85- if ! txCfg .Offline {
83+ if ! common . GetTransactionConfig () .Offline {
8684 conn , err = connection .Connect (ctx , npa .Network )
8785 cobra .CheckErr (err )
8886 }
@@ -111,20 +109,21 @@ var (
111109 // Update manifest to clear the machine ID as it has been cancelled.
112110 machine .ID = ""
113111
114- if err = manifest .Save (); err != nil {
115- cobra .CheckErr (fmt .Errorf ("failed to update manifest: %w" , err ))
112+ if manifest != nil {
113+ if err = manifest .Save (); err != nil {
114+ cobra .CheckErr (fmt .Errorf ("failed to update manifest: %w" , err ))
115+ }
116116 }
117117 },
118118 }
119119
120120 changeAdminCmd = & cobra.Command {
121- Use : "change-admin [<machine-name>] <new-admin>" ,
121+ Use : "change-admin [<machine-name> | <provider-address>:<machine-id> ] <new-admin>" ,
122122 Short : "Change the machine administrator" ,
123123 Args : cobra .RangeArgs (1 , 2 ),
124124 Run : func (_ * cobra.Command , args []string ) {
125125 txCfg := common .GetTransactionConfig ()
126-
127- _ , deployment , npa := roflCommon .LoadManifestAndSetNPA (& roflCommon.ManifestOptions {
126+ machine , machineName , machineID , _ , _ , npa := resolveMachineManifestNpa (args , & roflCommon.ManifestOptions {
128127 NeedAppID : true ,
129128 NeedAdmin : false ,
130129 })
@@ -141,18 +140,16 @@ var (
141140 args = args [:1 ]
142141 }
143142
144- machine , machineName , machineID := resolveMachine (args , deployment )
145-
146143 // Resolve provider address.
147144 providerAddr , _ , err := common .ResolveLocalAccountOrAddress (npa .Network , machine .Provider )
148145 if err != nil {
149- cobra .CheckErr (fmt .Sprintf ( "Invalid provider address: %s " , err ))
146+ cobra .CheckErr (fmt .Errorf ( "invalid provider address: %w " , err ))
150147 }
151148
152149 // Resolve new admin address.
153150 newAdminAddr , _ , err := common .ResolveLocalAccountOrAddress (npa .Network , newAdminAddress )
154151 if err != nil {
155- cobra .CheckErr (fmt .Sprintf ( "Invalid admin address: %s " , err ))
152+ cobra .CheckErr (fmt .Errorf ( "invalid admin address: %w " , err ))
156153 }
157154
158155 // When not in offline mode, connect to the given network endpoint.
@@ -196,13 +193,13 @@ var (
196193 }
197194
198195 topUpCmd = & cobra.Command {
199- Use : "top-up [<machine-name>]" ,
196+ Use : "top-up [<machine-name> | <provider-address>:<machine-id> ]" ,
200197 Short : "Top-up payment for a machine" ,
201198 Args : cobra .MaximumNArgs (1 ),
202199 Run : func (_ * cobra.Command , args []string ) {
203200 txCfg := common .GetTransactionConfig ()
204201
205- _ , deployment , npa := roflCommon . LoadManifestAndSetNPA ( & roflCommon.ManifestOptions {
202+ machine , machineName , machineID , _ , _ , npa := resolveMachineManifestNpa ( args , & roflCommon.ManifestOptions {
206203 NeedAppID : true ,
207204 NeedAdmin : false ,
208205 })
@@ -213,12 +210,10 @@ var (
213210 ctx = context .WithValue (ctx , config .ContextKeyParaTimeCfg , npa .ParaTime )
214211 }
215212
216- machine , machineName , machineID := resolveMachine (args , deployment )
217-
218213 // Resolve provider address.
219214 providerAddr , _ , err := common .ResolveLocalAccountOrAddress (npa .Network , machine .Provider )
220215 if err != nil {
221- cobra .CheckErr (fmt .Sprintf ("invalid provider address: %s " , err ))
216+ cobra .CheckErr (fmt .Errorf ("invalid provider address: %w " , err ))
222217 }
223218
224219 // Parse machine payment term.
@@ -240,7 +235,7 @@ var (
240235 // Fetch chosen offer, so we can calculate price.
241236 offers , err := conn .Runtime (npa .ParaTime ).ROFLMarket .Offers (ctx , client .RoundLatest , * providerAddr )
242237 if err != nil {
243- cobra .CheckErr (fmt .Errorf ("failed to query provider: %s " , err ))
238+ cobra .CheckErr (fmt .Errorf ("failed to query provider: %w " , err ))
244239 }
245240
246241 for _ , of := range offers {
@@ -249,6 +244,18 @@ var (
249244 break
250245 }
251246 }
247+ if offer == nil {
248+ machineDsc , err := conn .Runtime (npa .ParaTime ).ROFLMarket .Instance (ctx , client .RoundLatest , * providerAddr , machineID )
249+ if err != nil {
250+ cobra .CheckErr (fmt .Errorf ("failed to query machine: %w" , err ))
251+ }
252+ for _ , of := range offers {
253+ if of .ID == machineDsc .Offer {
254+ offer = of
255+ break
256+ }
257+ }
258+ }
252259 if offer == nil {
253260 cobra .CheckErr (fmt .Errorf ("unable to find existing machine offer (%s) among market offers" , machine .Offer ))
254261 }
@@ -295,7 +302,56 @@ var (
295302 }
296303)
297304
298- func resolveMachine (args []string , deployment * buildRofl.Deployment ) (* buildRofl.Machine , string , roflmarket.InstanceID ) {
305+ func resolveMachineManifestNpa (args []string , manifestOpts * roflCommon.ManifestOptions ) (* buildRofl.Machine , string , roflmarket.InstanceID , * buildRofl.Manifest , * roflCmdBuild.AppExtraConfig , * common.NPASelection ) {
306+ var npa * common.NPASelection
307+ var manifest * buildRofl.Manifest
308+ var extraCfg * roflCmdBuild.AppExtraConfig
309+ machine , machineName , machineID := resolveMachineFromArgs (args )
310+ if machine != nil {
311+ cfg := cliConfig .Global ()
312+ npa = common .GetNPASelection (cfg )
313+ } else {
314+ var deployment * buildRofl.Deployment
315+ manifest , deployment , npa = roflCommon .LoadManifestAndSetNPA (manifestOpts )
316+
317+ machine , machineName , machineID = resolveMachineFromManifest (args , deployment )
318+
319+ var appID rofl.AppID
320+ if err := appID .UnmarshalText ([]byte (deployment .AppID )); err != nil {
321+ cobra .CheckErr (fmt .Errorf ("malformed app id: %w" , err ))
322+ }
323+
324+ var err error
325+ extraCfg , err = roflCmdBuild .ValidateApp (manifest , roflCmdBuild.ValidationOpts {
326+ Offline : true ,
327+ })
328+ if err != nil {
329+ cobra .CheckErr (fmt .Errorf ("failed to validate app: %w" , err ))
330+ }
331+ }
332+
333+ return machine , machineName , machineID , manifest , extraCfg , npa
334+ }
335+
336+ func resolveMachineFromArgs (args []string ) (* buildRofl.Machine , string , roflmarket.InstanceID ) {
337+ if len (args ) > 0 {
338+ parts := strings .Split (args [0 ], ":" )
339+ if len (parts ) == 2 {
340+ m := & buildRofl.Machine {
341+ Provider : parts [0 ],
342+ ID : parts [1 ],
343+ }
344+ var machineID roflmarket.InstanceID
345+ if err := machineID .UnmarshalText ([]byte (m .ID )); err != nil {
346+ cobra .CheckErr (fmt .Errorf ("malformed machine ID: %w" , err ))
347+ }
348+ return m , args [0 ], machineID
349+ }
350+ }
351+ return nil , "" , roflmarket.InstanceID {}
352+ }
353+
354+ func resolveMachineFromManifest (args []string , deployment * buildRofl.Deployment ) (* buildRofl.Machine , string , roflmarket.InstanceID ) {
299355 machineName := buildRofl .DefaultMachineName
300356 if len (args ) > 0 {
301357 machineName = args [0 ]
@@ -335,17 +391,15 @@ func resolveMachine(args []string, deployment *buildRofl.Deployment) (*buildRofl
335391func queueCommand (cliArgs []string , method string , args any , msgAfter string ) {
336392 txCfg := common .GetTransactionConfig ()
337393
338- _ , deployment , npa := roflCommon . LoadManifestAndSetNPA ( & roflCommon.ManifestOptions {
394+ machine , machineName , machineID , _ , _ , npa := resolveMachineManifestNpa ( cliArgs , & roflCommon.ManifestOptions {
339395 NeedAppID : true ,
340396 NeedAdmin : false ,
341397 })
342398
343- machine , machineName , machineID := resolveMachine (cliArgs , deployment )
344-
345399 // Resolve provider address.
346400 providerAddr , _ , err := common .ResolveLocalAccountOrAddress (npa .Network , machine .Provider )
347401 if err != nil {
348- cobra .CheckErr (fmt .Sprintf ( "Invalid provider address: %s " , err ))
402+ cobra .CheckErr (fmt .Errorf ( "invalid provider address: %w " , err ))
349403 }
350404
351405 // When not in offline mode, connect to the given network endpoint.
0 commit comments