11package rofl
22
33import (
4+ "bytes"
45 "context"
56 "errors"
67 "fmt"
78 "maps"
89 "os"
10+ "sort"
911
1012 "github.com/spf13/cobra"
1113 flag "github.com/spf13/pflag"
@@ -27,12 +29,13 @@ import (
2729)
2830
2931var (
30- deployProvider string
31- deployOffer string
32- deployMachine string
33- deployTerm string
34- deployTermCount uint64
35- deployForce bool
32+ deployProvider string
33+ deployOffer string
34+ deployMachine string
35+ deployTerm string
36+ deployTermCount uint64
37+ deployForce bool
38+ deployShowOffers bool
3639
3740 deployCmd = & cobra.Command {
3841 Use : "deploy" ,
@@ -106,10 +109,10 @@ var (
106109
107110 fmt .Printf ("Using provider: %s (%s)\n " , machine .Provider , providerAddr )
108111
109- // Parse machine payment term.
110- term := roflCommon . ParseMachineTerm ( deployTerm )
111- if deployTermCount < 1 {
112- cobra . CheckErr ( "Number of terms must be at least 1." )
112+ if deployShowOffers {
113+ // Display all offers supported by the provider.
114+ showProviderOffers ( ctx , npa , conn , * providerAddr )
115+ return
113116 }
114117
115118 // Push ORC to OCI repository.
@@ -143,24 +146,17 @@ var (
143146 // When machine is not set, we need to obtain one.
144147 fmt .Printf ("No pre-existing machine configured, creating a new one...\n " )
145148
146- if machine .Offer == "" && deployOffer == "" {
147- // Display all offers supported by the provider.
148- showProviderOffers (ctx , npa , conn , * providerAddr )
149- cobra .CheckErr (fmt .Sprintf ("Offer not configured for deployment '%s' machine '%s'. Please specify --offer." , deploymentName , deployMachine ))
150- }
151149 if deployOffer != "" {
152150 machine .Offer = deployOffer
153151 }
154152
155153 // Resolve offer.
156- var offers []* roflmarket.Offer
157- offers , err = conn .Runtime (npa .ParaTime ).ROFLMarket .Offers (ctx , client .RoundLatest , * providerAddr )
158- if err != nil {
159- cobra .CheckErr (fmt .Sprintf ("Failed to query provider: %s" , err ))
160- }
154+ offers , err := fetchProviderOffers (ctx , npa , conn , * providerAddr )
155+ cobra .CheckErr (err )
161156 var offer * roflmarket.Offer
162157 for _ , of := range offers {
163- if of .Metadata [provider .SchedulerMetadataOfferKey ] == machine .Offer {
158+ if of .Metadata [provider .SchedulerMetadataOfferKey ] == machine .Offer || machine .Offer == "" {
159+ machine .Offer = of .Metadata [provider .SchedulerMetadataOfferKey ]
164160 offer = of
165161 break
166162 }
@@ -173,6 +169,11 @@ var (
173169
174170 fmt .Printf ("Taking offer: %s [%s]\n " , machine .Offer , offer .ID )
175171
172+ term := detectTerm (offer )
173+ if deployTermCount < 1 {
174+ cobra .CheckErr ("Number of terms must be at least 1." )
175+ }
176+
176177 // Prepare transaction.
177178 tx := roflmarket .NewInstanceCreateTx (nil , & roflmarket.InstanceCreate {
178179 Provider : * providerAddr ,
@@ -249,11 +250,51 @@ var (
249250 }
250251)
251252
252- func showProviderOffers (ctx context.Context , npa * common.NPASelection , conn connection.Connection , provider types.Address ) {
253- offers , err := conn .Runtime (npa .ParaTime ).ROFLMarket .Offers (ctx , client .RoundLatest , provider )
253+ // detectTerm returns the preferred (longest) period of the given offer.
254+ func detectTerm (offer * roflmarket.Offer ) (term roflmarket.Term ) {
255+ if offer == nil {
256+ cobra .CheckErr (fmt .Errorf ("no offers exist to determine payment term" ))
257+ return // Linter complains otherwise.
258+ }
259+ if offer .Payment .Native == nil {
260+ cobra .CheckErr (fmt .Errorf ("no payment terms available for offer '%s'" , offer .ID ))
261+ }
262+
263+ if deployTerm != "" {
264+ // Custom deploy term.
265+ term = roflCommon .ParseMachineTerm (deployTerm )
266+ if _ , ok := offer .Payment .Native .Terms [term ]; ! ok {
267+ cobra .CheckErr (fmt .Errorf ("term '%s' is not available for offer '%s'" , deployTerm , offer .ID ))
268+ }
269+ return
270+ }
271+
272+ // Take the longest payment period.
273+ // TODO: Sort by actual periods (e.g. seconds) instead of internal roflmarket.Term index.
274+ for t := range offer .Payment .Native .Terms {
275+ if t > term {
276+ term = t
277+ }
278+ }
279+ return
280+ }
281+
282+ func fetchProviderOffers (ctx context.Context , npa * common.NPASelection , conn connection.Connection , provider types.Address ) (offers []* roflmarket.Offer , err error ) {
283+ offers , err = conn .Runtime (npa .ParaTime ).ROFLMarket .Offers (ctx , client .RoundLatest , provider )
254284 if err != nil {
285+ err = fmt .Errorf ("failed to query provider: %s" , err )
255286 return
256287 }
288+ // Order offers, newer first.
289+ sort .Slice (offers , func (i , j int ) bool {
290+ return bytes .Compare (offers [i ].ID [:], offers [j ].ID [:]) > 0
291+ })
292+ return
293+ }
294+
295+ func showProviderOffers (ctx context.Context , npa * common.NPASelection , conn connection.Connection , provider types.Address ) {
296+ offers , err := fetchProviderOffers (ctx , npa , conn , provider )
297+ cobra .CheckErr (err )
257298
258299 fmt .Println ()
259300 fmt .Printf ("Offers available from the selected provider:\n " )
@@ -295,12 +336,14 @@ func showProviderOffer(offer *roflmarket.Offer) {
295336
296337func init () {
297338 providerFlags := flag .NewFlagSet ("" , flag .ContinueOnError )
298- providerFlags .StringVar (& deployProvider , "provider" , "" , "set the provider address" )
339+ // Default to Testnet playground provider.
340+ providerFlags .StringVar (& deployProvider , "provider" , "oasis1qp2ens0hsp7gh23wajxa4hpetkdek3swyyulyrmz" , "set the provider address" )
299341 providerFlags .StringVar (& deployOffer , "offer" , "" , "set the provider's offer identifier" )
300342 providerFlags .StringVar (& deployMachine , "machine" , buildRofl .DefaultMachineName , "machine to deploy into" )
301- providerFlags .StringVar (& deployTerm , "term" , roflCommon . TermMonth , "term to pay for in advance" )
343+ providerFlags .StringVar (& deployTerm , "term" , "" , "term to pay for in advance" )
302344 providerFlags .Uint64Var (& deployTermCount , "term-count" , 1 , "number of terms to pay for in advance" )
303345 providerFlags .BoolVar (& deployForce , "force" , false , "force deployment" )
346+ providerFlags .BoolVar (& deployShowOffers , "show-offers" , false , "show all provider offers and quit" )
304347
305348 deployCmd .Flags ().AddFlagSet (common .SelectorFlags )
306349 deployCmd .Flags ().AddFlagSet (common .RuntimeTxFlags )
0 commit comments