1
1
package rofl
2
2
3
3
import (
4
+ "bytes"
4
5
"context"
5
6
"errors"
6
7
"fmt"
7
8
"maps"
8
9
"os"
10
+ "sort"
9
11
10
12
"github.com/spf13/cobra"
11
13
flag "github.com/spf13/pflag"
@@ -27,12 +29,13 @@ import (
27
29
)
28
30
29
31
var (
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
36
39
37
40
deployCmd = & cobra.Command {
38
41
Use : "deploy" ,
@@ -106,10 +109,10 @@ var (
106
109
107
110
fmt .Printf ("Using provider: %s (%s)\n " , machine .Provider , providerAddr )
108
111
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
113
116
}
114
117
115
118
// Push ORC to OCI repository.
@@ -143,24 +146,17 @@ var (
143
146
// When machine is not set, we need to obtain one.
144
147
fmt .Printf ("No pre-existing machine configured, creating a new one...\n " )
145
148
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
- }
151
149
if deployOffer != "" {
152
150
machine .Offer = deployOffer
153
151
}
154
152
155
153
// 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 )
161
156
var offer * roflmarket.Offer
162
157
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 ]
164
160
offer = of
165
161
break
166
162
}
@@ -173,6 +169,11 @@ var (
173
169
174
170
fmt .Printf ("Taking offer: %s [%s]\n " , machine .Offer , offer .ID )
175
171
172
+ term := detectTerm (offer )
173
+ if deployTermCount < 1 {
174
+ cobra .CheckErr ("Number of terms must be at least 1." )
175
+ }
176
+
176
177
// Prepare transaction.
177
178
tx := roflmarket .NewInstanceCreateTx (nil , & roflmarket.InstanceCreate {
178
179
Provider : * providerAddr ,
@@ -249,11 +250,51 @@ var (
249
250
}
250
251
)
251
252
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 )
254
284
if err != nil {
285
+ err = fmt .Errorf ("failed to query provider: %s" , err )
255
286
return
256
287
}
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 )
257
298
258
299
fmt .Println ()
259
300
fmt .Printf ("Offers available from the selected provider:\n " )
@@ -295,12 +336,14 @@ func showProviderOffer(offer *roflmarket.Offer) {
295
336
296
337
func init () {
297
338
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" )
299
341
providerFlags .StringVar (& deployOffer , "offer" , "" , "set the provider's offer identifier" )
300
342
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" )
302
344
providerFlags .Uint64Var (& deployTermCount , "term-count" , 1 , "number of terms to pay for in advance" )
303
345
providerFlags .BoolVar (& deployForce , "force" , false , "force deployment" )
346
+ providerFlags .BoolVar (& deployShowOffers , "show-offers" , false , "show all provider offers and quit" )
304
347
305
348
deployCmd .Flags ().AddFlagSet (common .SelectorFlags )
306
349
deployCmd .Flags ().AddFlagSet (common .RuntimeTxFlags )
0 commit comments