Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion cmd/common/json.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ func JSONMarshalKey(k interface{}) (keyJSON []byte, err error) {
// Marshal string or Base64 otherwise.
keyJSON, err = json.Marshal(k)
}
return
return keyJSON, err
}

// JSONPrettyPrintRoflAppConfig is a wrapper around rofl.AppConfig that implements custom JSON marshaling.
Expand Down
4 changes: 2 additions & 2 deletions cmd/common/selector.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ func (npa *NPASelection) PrettyPrintNetwork() (out string) {
if len(npa.Network.Description) > 0 {
out += fmt.Sprintf(" (%s)", npa.Network.Description)
}
return
return out
}

// ConsensusDenomination returns the denomination used to represent the consensus layer token.
Expand All @@ -125,7 +125,7 @@ func (npa *NPASelection) ConsensusDenomination() (denom types.Denomination) {
default:
denom = types.Denomination(cfgDenom)
}
return
return denom
}

func init() {
Expand Down
9 changes: 9 additions & 0 deletions cmd/rofl/common/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ var (
// TermFlags provide the term and count setting.
TermFlags *flag.FlagSet

// ShowOffersFlag is the flag for showing all provider offers.
ShowOffersFlag *flag.FlagSet

// DeploymentName is the name of the ROFL app deployment.
DeploymentName string

Expand All @@ -33,6 +36,9 @@ var (

// TermCount specific the rental base unit multiplier.
TermCount uint64

// ShowOffers controls whether to display all offers for each provider.
ShowOffers bool
)

func init() {
Expand All @@ -48,4 +54,7 @@ func init() {
TermFlags = flag.NewFlagSet("", flag.ContinueOnError)
TermFlags.StringVar(&Term, "term", "", "term to pay for in advance [hour, month, year]")
TermFlags.Uint64Var(&TermCount, "term-count", 1, "number of terms to pay for in advance")

ShowOffersFlag = flag.NewFlagSet("", flag.ContinueOnError)
ShowOffersFlag.BoolVar(&ShowOffers, "show-offers", false, "show all offers for each provider")
}
40 changes: 40 additions & 0 deletions cmd/rofl/common/term.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,43 @@ func ParseMachineTerm(term string) roflmarket.Term {
return 0
}
}

// FormatTerm formats a roflmarket.Term into a human-readable string.
func FormatTerm(term roflmarket.Term) string {
switch term {
case roflmarket.TermHour:
return TermHour
case roflmarket.TermMonth:
return TermMonth
case roflmarket.TermYear:
return TermYear
default:
return fmt.Sprintf("<unknown: %d>", term)
}
}

// FormatTermAdjectival formats a roflmarket.Term into an adjectival form (e.g., "hourly").
func FormatTermAdjectival(term roflmarket.Term) string {
switch term {
case roflmarket.TermHour:
return "hourly"
case roflmarket.TermMonth:
return "monthly"
case roflmarket.TermYear:
return "yearly"
default:
return fmt.Sprintf("term_%d", term)
}
}

// FormatTeeType formats a roflmarket.TeeType into a human-readable string.
func FormatTeeType(tee roflmarket.TeeType) string {
switch tee {
case roflmarket.TeeTypeSGX:
return "sgx"
case roflmarket.TeeTypeTDX:
return "tdx"
default:
return fmt.Sprintf("<unknown: %d>", tee)
}
}
125 changes: 25 additions & 100 deletions cmd/rofl/deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import (
"github.com/oasisprotocol/cli/cmd/common"
roflCmdBuild "github.com/oasisprotocol/cli/cmd/rofl/build"
roflCommon "github.com/oasisprotocol/cli/cmd/rofl/common"
roflProvider "github.com/oasisprotocol/cli/cmd/rofl/provider"
cliConfig "github.com/oasisprotocol/cli/config"
)

Expand All @@ -40,7 +41,6 @@ var (
deployOffer string
deployMachine string
deployForce bool
deployShowOffers bool
deployReplaceMachine bool

deployCmd = &cobra.Command{
Expand Down Expand Up @@ -129,9 +129,17 @@ var (

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

if deployShowOffers {
if roflCommon.ShowOffers {
// Display all offers supported by the provider.
showProviderOffers(ctx, npa, conn, *providerAddr)
offers, err := fetchProviderOffers(ctx, npa, conn, *providerAddr)
cobra.CheckErr(err)

fmt.Println()
fmt.Printf("Offers available from the selected provider:\n")
for _, offer := range offers {
roflProvider.ShowOfferSummary(npa, offer)
}
fmt.Println()
return
}

Expand Down Expand Up @@ -183,12 +191,17 @@ var (
}
}
if offer == nil {
showProviderOffers(ctx, npa, conn, *providerAddr)
fmt.Println()
fmt.Printf("Offers available from the selected provider:\n")
for _, of := range offers {
roflProvider.ShowOfferSummary(npa, of)
}
fmt.Println()
return nil, nil, fmt.Errorf("offer '%s' not found for provider '%s'", machine.Offer, providerAddr)
}

fmt.Printf("Taking offer:\n")
showProviderOffer(ctx, offer)
roflProvider.ShowOfferSummary(npa, offer)

term := detectTerm(offer)
if roflCommon.TermCount < 1 {
Expand All @@ -203,7 +216,7 @@ var (
}
cobra.CheckErr(totalPrice.Mul(qTermCount))
tp := types.NewBaseUnits(totalPrice, offer.Payment.Native.Denomination)
fmt.Printf("Selected per-%s pricing term, total price is ", term2str(term))
fmt.Printf("Selected per-%s pricing term, total price is ", roflCommon.FormatTerm(term))
tp.PrettyPrint(ctx, "", os.Stdout)
fmt.Println(".")
// Warn the user about the non-refundable rental policy before first renting.
Expand Down Expand Up @@ -350,7 +363,7 @@ func pushBundleToOciRepository(orcFilename string, ociRepository string) (string
func detectTerm(offer *roflmarket.Offer) (term roflmarket.Term) {
if offer == nil {
cobra.CheckErr(fmt.Errorf("no offers exist to determine payment term"))
return // Linter complains otherwise.
return term // Linter complains otherwise.
}
if offer.Payment.Native == nil {
cobra.CheckErr(fmt.Errorf("no payment terms available for offer '%s'", offer.ID))
Expand All @@ -362,7 +375,7 @@ func detectTerm(offer *roflmarket.Offer) (term roflmarket.Term) {
if _, ok := offer.Payment.Native.Terms[term]; !ok {
cobra.CheckErr(fmt.Errorf("term '%s' is not available for offer '%s'", roflCommon.Term, offer.ID))
}
return
return term
}

// Take the longest payment period.
Expand All @@ -372,108 +385,20 @@ func detectTerm(offer *roflmarket.Offer) (term roflmarket.Term) {
term = t
}
}
return
return term
}

func fetchProviderOffers(ctx context.Context, npa *common.NPASelection, conn connection.Connection, provider types.Address) (offers []*roflmarket.Offer, err error) {
offers, err = conn.Runtime(npa.ParaTime).ROFLMarket.Offers(ctx, client.RoundLatest, provider)
if err != nil {
err = fmt.Errorf("failed to query provider: %s", err)
return
return offers, err
}
// Order offers, newer first.
sort.Slice(offers, func(i, j int) bool {
return bytes.Compare(offers[i].ID[:], offers[j].ID[:]) > 0
})
return
}

func showProviderOffers(ctx context.Context, npa *common.NPASelection, conn connection.Connection, provider types.Address) {
offers, err := fetchProviderOffers(ctx, npa, conn, provider)
cobra.CheckErr(err)

fmt.Println()
fmt.Printf("Offers available from the selected provider:\n")
for idx, offer := range offers {
showProviderOffer(ctx, offer)
if idx != len(offers)-1 {
fmt.Println()
}
}
fmt.Println()
}

func showProviderOffer(ctx context.Context, offer *roflmarket.Offer) {
name, ok := offer.Metadata[provider.SchedulerMetadataOfferKey]
if !ok {
name = "<unnamed>"
}

var tee string
switch offer.Resources.TEE {
case roflmarket.TeeTypeSGX:
tee = "sgx"
case roflmarket.TeeTypeTDX:
tee = "tdx"
default:
tee = "<unknown>"
}

fmt.Printf("- %s [%s]\n", name, offer.ID)
fmt.Printf(" TEE: %s | Memory: %d MiB | vCPUs: %d | Storage: %.2f GiB\n",
tee,
offer.Resources.Memory,
offer.Resources.CPUCount,
float64(offer.Resources.Storage)/1024.,
)
if _, ok := offer.Metadata[provider.NoteMetadataKey]; ok {
fmt.Printf(" Note: %s\n", offer.Metadata[provider.NoteMetadataKey])
}
if _, ok := offer.Metadata[provider.DescriptionMetadataKey]; ok {
fmt.Printf(" Description:\n %s\n", strings.ReplaceAll(offer.Metadata[provider.DescriptionMetadataKey], "\n", "\n "))
}
if offer.Payment.Native != nil {
if len(offer.Payment.Native.Terms) == 0 {
return
}

// Specify sorting order for terms.
terms := []roflmarket.Term{roflmarket.TermHour, roflmarket.TermMonth, roflmarket.TermYear}

// Go through provided payment terms and print price.
fmt.Printf(" Price: ")
var gotPrev bool
for _, term := range terms {
price, exists := offer.Payment.Native.Terms[term]
if !exists {
continue
}

if gotPrev {
fmt.Printf(" | ")
}

bu := types.NewBaseUnits(price, offer.Payment.Native.Denomination)
bu.PrettyPrint(ctx, "", os.Stdout)
fmt.Printf("/%s", term2str(term))
gotPrev = true
}
fmt.Println()
}
}

// Helper to convert roflmarket term into string.
func term2str(term roflmarket.Term) string {
switch term {
case roflmarket.TermHour:
return "hour"
case roflmarket.TermMonth:
return "month"
case roflmarket.TermYear:
return "year"
default:
return "<unknown>"
}
return offers, err
}

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

deployCmd.Flags().AddFlagSet(common.AccountFlag)
deployCmd.Flags().AddFlagSet(common.RuntimeTxFlags)
deployCmd.Flags().AddFlagSet(providerFlags)
deployCmd.Flags().AddFlagSet(roflCommon.ShowOffersFlag)
deployCmd.Flags().AddFlagSet(roflCommon.DeploymentFlags)
deployCmd.Flags().AddFlagSet(roflCommon.WipeFlags)
deployCmd.Flags().AddFlagSet(roflCommon.TermFlags)
Expand Down
Loading
Loading