From ccc43dbb6fd331ea7f41ab6f58b16ac7a8a9967d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matev=C5=BE=20Jekovec?= Date: Tue, 6 May 2025 09:44:12 +0200 Subject: [PATCH 1/3] cmd/rofl/deploy: Set default Testnet provider address --- cmd/rofl/deploy.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cmd/rofl/deploy.go b/cmd/rofl/deploy.go index 5dcb2a00..467266a6 100644 --- a/cmd/rofl/deploy.go +++ b/cmd/rofl/deploy.go @@ -295,7 +295,8 @@ func showProviderOffer(offer *roflmarket.Offer) { func init() { providerFlags := flag.NewFlagSet("", flag.ContinueOnError) - providerFlags.StringVar(&deployProvider, "provider", "", "set the provider address") + // Default to Testnet playground provider. + providerFlags.StringVar(&deployProvider, "provider", "oasis1qp2ens0hsp7gh23wajxa4hpetkdek3swyyulyrmz", "set the provider address") providerFlags.StringVar(&deployOffer, "offer", "", "set the provider's offer identifier") providerFlags.StringVar(&deployMachine, "machine", buildRofl.DefaultMachineName, "machine to deploy into") providerFlags.StringVar(&deployTerm, "term", roflCommon.TermMonth, "term to pay for in advance") From 12929adc60b510a43ff46d04cc5748aa1bfa14ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matev=C5=BE=20Jekovec?= Date: Tue, 6 May 2025 09:45:07 +0200 Subject: [PATCH 2/3] cmd/rofl/deploy: Detect term based on the offer --- cmd/rofl/deploy.go | 42 +++++++++++++++++++++++++++++++++++------- 1 file changed, 35 insertions(+), 7 deletions(-) diff --git a/cmd/rofl/deploy.go b/cmd/rofl/deploy.go index 467266a6..21c411ce 100644 --- a/cmd/rofl/deploy.go +++ b/cmd/rofl/deploy.go @@ -106,12 +106,6 @@ var ( fmt.Printf("Using provider: %s (%s)\n", machine.Provider, providerAddr) - // Parse machine payment term. - term := roflCommon.ParseMachineTerm(deployTerm) - if deployTermCount < 1 { - cobra.CheckErr("Number of terms must be at least 1.") - } - // Push ORC to OCI repository. if deployment.OCIRepository == "" { // TODO: Support default OCI repository. @@ -173,6 +167,11 @@ var ( fmt.Printf("Taking offer: %s [%s]\n", machine.Offer, offer.ID) + term := detectTerm(offer) + if deployTermCount < 1 { + cobra.CheckErr("Number of terms must be at least 1.") + } + // Prepare transaction. tx := roflmarket.NewInstanceCreateTx(nil, &roflmarket.InstanceCreate{ Provider: *providerAddr, @@ -249,6 +248,35 @@ var ( } ) +// detectTerm returns the preferred (longest) period of the given offer. +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. + } + if offer.Payment.Native == nil { + cobra.CheckErr(fmt.Errorf("no payment terms available for offer '%s'", offer.ID)) + } + + if deployTerm != "" { + // Custom deploy term. + term = roflCommon.ParseMachineTerm(deployTerm) + if _, ok := offer.Payment.Native.Terms[term]; !ok { + cobra.CheckErr(fmt.Errorf("term '%s' is not available for offer '%s'", deployTerm, offer.ID)) + } + return + } + + // Take the longest payment period. + // TODO: Sort by actual periods (e.g. seconds) instead of internal roflmarket.Term index. + for t := range offer.Payment.Native.Terms { + if t > term { + term = t + } + } + return +} + func showProviderOffers(ctx context.Context, npa *common.NPASelection, conn connection.Connection, provider types.Address) { offers, err := conn.Runtime(npa.ParaTime).ROFLMarket.Offers(ctx, client.RoundLatest, provider) if err != nil { @@ -299,7 +327,7 @@ func init() { providerFlags.StringVar(&deployProvider, "provider", "oasis1qp2ens0hsp7gh23wajxa4hpetkdek3swyyulyrmz", "set the provider address") providerFlags.StringVar(&deployOffer, "offer", "", "set the provider's offer identifier") providerFlags.StringVar(&deployMachine, "machine", buildRofl.DefaultMachineName, "machine to deploy into") - providerFlags.StringVar(&deployTerm, "term", roflCommon.TermMonth, "term to pay for in advance") + providerFlags.StringVar(&deployTerm, "term", "", "term to pay for in advance") providerFlags.Uint64Var(&deployTermCount, "term-count", 1, "number of terms to pay for in advance") providerFlags.BoolVar(&deployForce, "force", false, "force deployment") From bfc4f223696997e7dcdad8d2081088f0e2a011d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matev=C5=BE=20Jekovec?= Date: Tue, 6 May 2025 10:11:10 +0200 Subject: [PATCH 3/3] cmd/rofl/deploy: Take the first offer automatically --- cmd/rofl/deploy.go | 52 +++++++++++++++++++++++++++++----------------- 1 file changed, 33 insertions(+), 19 deletions(-) diff --git a/cmd/rofl/deploy.go b/cmd/rofl/deploy.go index 21c411ce..9a20550c 100644 --- a/cmd/rofl/deploy.go +++ b/cmd/rofl/deploy.go @@ -1,11 +1,13 @@ package rofl import ( + "bytes" "context" "errors" "fmt" "maps" "os" + "sort" "github.com/spf13/cobra" flag "github.com/spf13/pflag" @@ -27,12 +29,13 @@ import ( ) var ( - deployProvider string - deployOffer string - deployMachine string - deployTerm string - deployTermCount uint64 - deployForce bool + deployProvider string + deployOffer string + deployMachine string + deployTerm string + deployTermCount uint64 + deployForce bool + deployShowOffers bool deployCmd = &cobra.Command{ Use: "deploy", @@ -106,6 +109,12 @@ var ( fmt.Printf("Using provider: %s (%s)\n", machine.Provider, providerAddr) + if deployShowOffers { + // Display all offers supported by the provider. + showProviderOffers(ctx, npa, conn, *providerAddr) + return + } + // Push ORC to OCI repository. if deployment.OCIRepository == "" { // TODO: Support default OCI repository. @@ -137,24 +146,17 @@ var ( // When machine is not set, we need to obtain one. fmt.Printf("No pre-existing machine configured, creating a new one...\n") - if machine.Offer == "" && deployOffer == "" { - // Display all offers supported by the provider. - showProviderOffers(ctx, npa, conn, *providerAddr) - cobra.CheckErr(fmt.Sprintf("Offer not configured for deployment '%s' machine '%s'. Please specify --offer.", deploymentName, deployMachine)) - } if deployOffer != "" { machine.Offer = deployOffer } // Resolve offer. - var offers []*roflmarket.Offer - offers, err = conn.Runtime(npa.ParaTime).ROFLMarket.Offers(ctx, client.RoundLatest, *providerAddr) - if err != nil { - cobra.CheckErr(fmt.Sprintf("Failed to query provider: %s", err)) - } + offers, err := fetchProviderOffers(ctx, npa, conn, *providerAddr) + cobra.CheckErr(err) var offer *roflmarket.Offer for _, of := range offers { - if of.Metadata[provider.SchedulerMetadataOfferKey] == machine.Offer { + if of.Metadata[provider.SchedulerMetadataOfferKey] == machine.Offer || machine.Offer == "" { + machine.Offer = of.Metadata[provider.SchedulerMetadataOfferKey] offer = of break } @@ -277,11 +279,22 @@ func detectTerm(offer *roflmarket.Offer) (term roflmarket.Term) { return } -func showProviderOffers(ctx context.Context, npa *common.NPASelection, conn connection.Connection, provider types.Address) { - offers, err := conn.Runtime(npa.ParaTime).ROFLMarket.Offers(ctx, client.RoundLatest, provider) +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 } + // 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") @@ -330,6 +343,7 @@ func init() { providerFlags.StringVar(&deployTerm, "term", "", "term to pay for in advance") providerFlags.Uint64Var(&deployTermCount, "term-count", 1, "number of terms to pay for in advance") providerFlags.BoolVar(&deployForce, "force", false, "force deployment") + providerFlags.BoolVar(&deployShowOffers, "show-offers", false, "show all provider offers and quit") deployCmd.Flags().AddFlagSet(common.SelectorFlags) deployCmd.Flags().AddFlagSet(common.RuntimeTxFlags)