Skip to content

Commit aec1603

Browse files
authored
Merge pull request #650 from oasisprotocol/ptrus/feature/providers-show
cmd/rofl: Add providers list and show commands
2 parents 571f847 + ac6d03b commit aec1603

19 files changed

+878
-103
lines changed

cmd/common/json.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ func JSONMarshalKey(k interface{}) (keyJSON []byte, err error) {
4646
// Marshal string or Base64 otherwise.
4747
keyJSON, err = json.Marshal(k)
4848
}
49-
return
49+
return keyJSON, err
5050
}
5151

5252
// JSONPrettyPrintRoflAppConfig is a wrapper around rofl.AppConfig that implements custom JSON marshaling.

cmd/common/selector.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ func (npa *NPASelection) PrettyPrintNetwork() (out string) {
110110
if len(npa.Network.Description) > 0 {
111111
out += fmt.Sprintf(" (%s)", npa.Network.Description)
112112
}
113-
return
113+
return out
114114
}
115115

116116
// ConsensusDenomination returns the denomination used to represent the consensus layer token.
@@ -125,7 +125,7 @@ func (npa *NPASelection) ConsensusDenomination() (denom types.Denomination) {
125125
default:
126126
denom = types.Denomination(cfgDenom)
127127
}
128-
return
128+
return denom
129129
}
130130

131131
func init() {

cmd/rofl/common/flags.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ var (
1919
// TermFlags provide the term and count setting.
2020
TermFlags *flag.FlagSet
2121

22+
// ShowOffersFlag is the flag for showing all provider offers.
23+
ShowOffersFlag *flag.FlagSet
24+
2225
// DeploymentName is the name of the ROFL app deployment.
2326
DeploymentName string
2427

@@ -33,6 +36,9 @@ var (
3336

3437
// TermCount specific the rental base unit multiplier.
3538
TermCount uint64
39+
40+
// ShowOffers controls whether to display all offers for each provider.
41+
ShowOffers bool
3642
)
3743

3844
func init() {
@@ -48,4 +54,7 @@ func init() {
4854
TermFlags = flag.NewFlagSet("", flag.ContinueOnError)
4955
TermFlags.StringVar(&Term, "term", "", "term to pay for in advance [hour, month, year]")
5056
TermFlags.Uint64Var(&TermCount, "term-count", 1, "number of terms to pay for in advance")
57+
58+
ShowOffersFlag = flag.NewFlagSet("", flag.ContinueOnError)
59+
ShowOffersFlag.BoolVar(&ShowOffers, "show-offers", false, "show all offers for each provider")
5160
}

cmd/rofl/common/term.go

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,43 @@ func ParseMachineTerm(term string) roflmarket.Term {
3131
return 0
3232
}
3333
}
34+
35+
// FormatTerm formats a roflmarket.Term into a human-readable string.
36+
func FormatTerm(term roflmarket.Term) string {
37+
switch term {
38+
case roflmarket.TermHour:
39+
return TermHour
40+
case roflmarket.TermMonth:
41+
return TermMonth
42+
case roflmarket.TermYear:
43+
return TermYear
44+
default:
45+
return fmt.Sprintf("<unknown: %d>", term)
46+
}
47+
}
48+
49+
// FormatTermAdjectival formats a roflmarket.Term into an adjectival form (e.g., "hourly").
50+
func FormatTermAdjectival(term roflmarket.Term) string {
51+
switch term {
52+
case roflmarket.TermHour:
53+
return "hourly"
54+
case roflmarket.TermMonth:
55+
return "monthly"
56+
case roflmarket.TermYear:
57+
return "yearly"
58+
default:
59+
return fmt.Sprintf("term_%d", term)
60+
}
61+
}
62+
63+
// FormatTeeType formats a roflmarket.TeeType into a human-readable string.
64+
func FormatTeeType(tee roflmarket.TeeType) string {
65+
switch tee {
66+
case roflmarket.TeeTypeSGX:
67+
return "sgx"
68+
case roflmarket.TeeTypeTDX:
69+
return "tdx"
70+
default:
71+
return fmt.Sprintf("<unknown: %d>", tee)
72+
}
73+
}

cmd/rofl/deploy.go

Lines changed: 25 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import (
3232
"github.com/oasisprotocol/cli/cmd/common"
3333
roflCmdBuild "github.com/oasisprotocol/cli/cmd/rofl/build"
3434
roflCommon "github.com/oasisprotocol/cli/cmd/rofl/common"
35+
roflProvider "github.com/oasisprotocol/cli/cmd/rofl/provider"
3536
cliConfig "github.com/oasisprotocol/cli/config"
3637
)
3738

@@ -40,7 +41,6 @@ var (
4041
deployOffer string
4142
deployMachine string
4243
deployForce bool
43-
deployShowOffers bool
4444
deployReplaceMachine bool
4545

4646
deployCmd = &cobra.Command{
@@ -129,9 +129,17 @@ var (
129129

130130
fmt.Printf("Using provider: %s (%s)\n", machine.Provider, providerAddr)
131131

132-
if deployShowOffers {
132+
if roflCommon.ShowOffers {
133133
// Display all offers supported by the provider.
134-
showProviderOffers(ctx, npa, conn, *providerAddr)
134+
offers, err := fetchProviderOffers(ctx, npa, conn, *providerAddr)
135+
cobra.CheckErr(err)
136+
137+
fmt.Println()
138+
fmt.Printf("Offers available from the selected provider:\n")
139+
for _, offer := range offers {
140+
roflProvider.ShowOfferSummary(npa, offer)
141+
}
142+
fmt.Println()
135143
return
136144
}
137145

@@ -183,12 +191,17 @@ var (
183191
}
184192
}
185193
if offer == nil {
186-
showProviderOffers(ctx, npa, conn, *providerAddr)
194+
fmt.Println()
195+
fmt.Printf("Offers available from the selected provider:\n")
196+
for _, of := range offers {
197+
roflProvider.ShowOfferSummary(npa, of)
198+
}
199+
fmt.Println()
187200
return nil, nil, fmt.Errorf("offer '%s' not found for provider '%s'", machine.Offer, providerAddr)
188201
}
189202

190203
fmt.Printf("Taking offer:\n")
191-
showProviderOffer(ctx, offer)
204+
roflProvider.ShowOfferSummary(npa, offer)
192205

193206
term := detectTerm(offer)
194207
if roflCommon.TermCount < 1 {
@@ -203,7 +216,7 @@ var (
203216
}
204217
cobra.CheckErr(totalPrice.Mul(qTermCount))
205218
tp := types.NewBaseUnits(totalPrice, offer.Payment.Native.Denomination)
206-
fmt.Printf("Selected per-%s pricing term, total price is ", term2str(term))
219+
fmt.Printf("Selected per-%s pricing term, total price is ", roflCommon.FormatTerm(term))
207220
tp.PrettyPrint(ctx, "", os.Stdout)
208221
fmt.Println(".")
209222
// Warn the user about the non-refundable rental policy before first renting.
@@ -350,7 +363,7 @@ func pushBundleToOciRepository(orcFilename string, ociRepository string) (string
350363
func detectTerm(offer *roflmarket.Offer) (term roflmarket.Term) {
351364
if offer == nil {
352365
cobra.CheckErr(fmt.Errorf("no offers exist to determine payment term"))
353-
return // Linter complains otherwise.
366+
return term // Linter complains otherwise.
354367
}
355368
if offer.Payment.Native == nil {
356369
cobra.CheckErr(fmt.Errorf("no payment terms available for offer '%s'", offer.ID))
@@ -362,7 +375,7 @@ func detectTerm(offer *roflmarket.Offer) (term roflmarket.Term) {
362375
if _, ok := offer.Payment.Native.Terms[term]; !ok {
363376
cobra.CheckErr(fmt.Errorf("term '%s' is not available for offer '%s'", roflCommon.Term, offer.ID))
364377
}
365-
return
378+
return term
366379
}
367380

368381
// Take the longest payment period.
@@ -372,108 +385,20 @@ func detectTerm(offer *roflmarket.Offer) (term roflmarket.Term) {
372385
term = t
373386
}
374387
}
375-
return
388+
return term
376389
}
377390

378391
func fetchProviderOffers(ctx context.Context, npa *common.NPASelection, conn connection.Connection, provider types.Address) (offers []*roflmarket.Offer, err error) {
379392
offers, err = conn.Runtime(npa.ParaTime).ROFLMarket.Offers(ctx, client.RoundLatest, provider)
380393
if err != nil {
381394
err = fmt.Errorf("failed to query provider: %s", err)
382-
return
395+
return offers, err
383396
}
384397
// Order offers, newer first.
385398
sort.Slice(offers, func(i, j int) bool {
386399
return bytes.Compare(offers[i].ID[:], offers[j].ID[:]) > 0
387400
})
388-
return
389-
}
390-
391-
func showProviderOffers(ctx context.Context, npa *common.NPASelection, conn connection.Connection, provider types.Address) {
392-
offers, err := fetchProviderOffers(ctx, npa, conn, provider)
393-
cobra.CheckErr(err)
394-
395-
fmt.Println()
396-
fmt.Printf("Offers available from the selected provider:\n")
397-
for idx, offer := range offers {
398-
showProviderOffer(ctx, offer)
399-
if idx != len(offers)-1 {
400-
fmt.Println()
401-
}
402-
}
403-
fmt.Println()
404-
}
405-
406-
func showProviderOffer(ctx context.Context, offer *roflmarket.Offer) {
407-
name, ok := offer.Metadata[provider.SchedulerMetadataOfferKey]
408-
if !ok {
409-
name = "<unnamed>"
410-
}
411-
412-
var tee string
413-
switch offer.Resources.TEE {
414-
case roflmarket.TeeTypeSGX:
415-
tee = "sgx"
416-
case roflmarket.TeeTypeTDX:
417-
tee = "tdx"
418-
default:
419-
tee = "<unknown>"
420-
}
421-
422-
fmt.Printf("- %s [%s]\n", name, offer.ID)
423-
fmt.Printf(" TEE: %s | Memory: %d MiB | vCPUs: %d | Storage: %.2f GiB\n",
424-
tee,
425-
offer.Resources.Memory,
426-
offer.Resources.CPUCount,
427-
float64(offer.Resources.Storage)/1024.,
428-
)
429-
if _, ok := offer.Metadata[provider.NoteMetadataKey]; ok {
430-
fmt.Printf(" Note: %s\n", offer.Metadata[provider.NoteMetadataKey])
431-
}
432-
if _, ok := offer.Metadata[provider.DescriptionMetadataKey]; ok {
433-
fmt.Printf(" Description:\n %s\n", strings.ReplaceAll(offer.Metadata[provider.DescriptionMetadataKey], "\n", "\n "))
434-
}
435-
if offer.Payment.Native != nil {
436-
if len(offer.Payment.Native.Terms) == 0 {
437-
return
438-
}
439-
440-
// Specify sorting order for terms.
441-
terms := []roflmarket.Term{roflmarket.TermHour, roflmarket.TermMonth, roflmarket.TermYear}
442-
443-
// Go through provided payment terms and print price.
444-
fmt.Printf(" Price: ")
445-
var gotPrev bool
446-
for _, term := range terms {
447-
price, exists := offer.Payment.Native.Terms[term]
448-
if !exists {
449-
continue
450-
}
451-
452-
if gotPrev {
453-
fmt.Printf(" | ")
454-
}
455-
456-
bu := types.NewBaseUnits(price, offer.Payment.Native.Denomination)
457-
bu.PrettyPrint(ctx, "", os.Stdout)
458-
fmt.Printf("/%s", term2str(term))
459-
gotPrev = true
460-
}
461-
fmt.Println()
462-
}
463-
}
464-
465-
// Helper to convert roflmarket term into string.
466-
func term2str(term roflmarket.Term) string {
467-
switch term {
468-
case roflmarket.TermHour:
469-
return "hour"
470-
case roflmarket.TermMonth:
471-
return "month"
472-
case roflmarket.TermYear:
473-
return "year"
474-
default:
475-
return "<unknown>"
476-
}
401+
return offers, err
477402
}
478403

479404
func resolveAndMarshalPermissions(npa *common.NPASelection, permissions map[string][]string) (string, error) {
@@ -514,12 +439,12 @@ func init() {
514439
providerFlags.StringVar(&deployOffer, "offer", "", "set the provider's offer identifier")
515440
providerFlags.StringVar(&deployMachine, "machine", buildRofl.DefaultMachineName, "machine to deploy into")
516441
providerFlags.BoolVar(&deployForce, "force", false, "force deployment")
517-
providerFlags.BoolVar(&deployShowOffers, "show-offers", false, "show all provider offers and quit")
518442
providerFlags.BoolVar(&deployReplaceMachine, "replace-machine", false, "rent a new machine if the provided one expired")
519443

520444
deployCmd.Flags().AddFlagSet(common.AccountFlag)
521445
deployCmd.Flags().AddFlagSet(common.RuntimeTxFlags)
522446
deployCmd.Flags().AddFlagSet(providerFlags)
447+
deployCmd.Flags().AddFlagSet(roflCommon.ShowOffersFlag)
523448
deployCmd.Flags().AddFlagSet(roflCommon.DeploymentFlags)
524449
deployCmd.Flags().AddFlagSet(roflCommon.WipeFlags)
525450
deployCmd.Flags().AddFlagSet(roflCommon.TermFlags)

0 commit comments

Comments
 (0)