adm: Allow to download contracts from Gitea #958
6 changed files with 108 additions and 7 deletions
81
cmd/frostfs-adm/internal/modules/morph/download.go
Normal file
81
cmd/frostfs-adm/internal/modules/morph/download.go
Normal file
|
@ -0,0 +1,81 @@
|
|||
package morph
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"code.gitea.io/sdk/gitea"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func downloadContracts(cmd *cobra.Command, url string) (io.ReadCloser, error) {
|
||||
cmd.Printf("Downloading contracts archive from '%s'\n", url)
|
||||
|
||||
// HTTP client with connect timeout
|
||||
client := http.Client{
|
||||
Transport: &http.Transport{
|
||||
DialContext: (&net.Dialer{
|
||||
Timeout: 10 * time.Second,
|
||||
}).DialContext,
|
||||
},
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithTimeout(cmd.Context(), 60*time.Second)
|
||||
defer cancel()
|
||||
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("can't create request: %w", err)
|
||||
}
|
||||
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("can't fetch contracts archive: %w", err)
|
||||
}
|
||||
return resp.Body, nil
|
||||
}
|
||||
|
||||
func downloadContractsFromRepository(cmd *cobra.Command) (io.ReadCloser, error) {
|
||||
client, err := gitea.NewClient("https://git.frostfs.info")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("can't initialize repository client: %w", err)
|
||||
}
|
||||
|
||||
releases, _, err := client.ListReleases("TrueCloudLab", "frostfs-contract", gitea.ListReleasesOptions{})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("can't fetch release information: %w", err)
|
||||
}
|
||||
|
||||
var latestRelease *gitea.Release
|
||||
for _, r := range releases {
|
||||
if !r.IsDraft && !r.IsPrerelease {
|
||||
latestRelease = r
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if latestRelease == nil {
|
||||
return nil, fmt.Errorf("attempt to fetch contracts archive from the offitial repository failed: no releases found")
|
||||
}
|
||||
|
||||
cmd.Printf("Found release %s (%s)\n", latestRelease.TagName, latestRelease.Title)
|
||||
|
||||
var url string
|
||||
for _, a := range latestRelease.Attachments {
|
||||
if strings.HasPrefix(a.Name, "frostfs-contract") {
|
||||
url = a.DownloadURL
|
||||
break
|
||||
}
|
||||
}
|
||||
if url == "" {
|
||||
return nil, errors.New("can't find contracts archive in the latest release")
|
||||
}
|
||||
|
||||
return downloadContracts(cmd, url)
|
||||
}
|
|
@ -50,6 +50,7 @@ type initializeContext struct {
|
|||
Contracts map[string]*contractState
|
||||
Command *cobra.Command
|
||||
ContractPath string
|
||||
ContractURL string
|
||||
}
|
||||
|
||||
var ErrTooManyAlphabetNodes = fmt.Errorf("too many alphabet nodes (maximum allowed is %d)", maxAlphabetNodes)
|
||||
|
@ -152,6 +153,11 @@ func newInitializeContext(cmd *cobra.Command, v *viper.Viper) (*initializeContex
|
|||
return nil, err
|
||||
}
|
||||
|
||||
var ctrURL string
|
||||
if needContracts {
|
||||
ctrURL, _ = cmd.Flags().GetString(contractsURLFlag)
|
||||
}
|
||||
|
||||
if err := checkNotaryEnabled(c); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -176,6 +182,7 @@ func newInitializeContext(cmd *cobra.Command, v *viper.Viper) (*initializeContex
|
|||
Command: cmd,
|
||||
Contracts: make(map[string]*contractState),
|
||||
ContractPath: ctrPath,
|
||||
ContractURL: ctrURL,
|
||||
}
|
||||
|
||||
if needContracts {
|
||||
|
|
|
@ -399,10 +399,14 @@ func (c *initializeContext) readContracts(names []string) error {
|
|||
}
|
||||
} else {
|
||||
var r io.ReadCloser
|
||||
if c.ContractPath == "" {
|
||||
return errors.New("contracts flag is missing")
|
||||
if c.ContractPath != "" {
|
||||
r, err = os.Open(c.ContractPath)
|
||||
} else if c.ContractURL != "" {
|
||||
r, err = downloadContracts(c.Command, c.ContractURL)
|
||||
} else {
|
||||
r, err = downloadContractsFromRepository(c.Command)
|
||||
}
|
||||
r, err = os.Open(c.ContractPath)
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("can't open contracts archive: %w", err)
|
||||
}
|
||||
|
|
|
@ -17,6 +17,9 @@ const (
|
|||
storageGasCLIFlag = "initial-gas"
|
||||
storageGasConfigFlag = "storage.initial_gas"
|
||||
contractsInitFlag = "contracts"
|
||||
contractsInitFlagDesc = "Path to archive with compiled FrostFS contracts (the default is to fetch the latest release from the official repository)"
|
||||
contractsURLFlag = "contracts-url"
|
||||
contractsURLFlagDesc = "URL to archive with compiled FrostFS contracts"
|
||||
maxObjectSizeInitFlag = "network.max_object_size"
|
||||
maxObjectSizeCLIFlag = "max-object-size"
|
||||
epochDurationInitFlag = "network.epoch_duration"
|
||||
|
@ -370,8 +373,9 @@ func initUpdateContractsCmd() {
|
|||
RootCmd.AddCommand(updateContractsCmd)
|
||||
updateContractsCmd.Flags().String(alphabetWalletsFlag, "", alphabetWalletsFlagDesc)
|
||||
updateContractsCmd.Flags().StringP(endpointFlag, endpointFlagShort, "", endpointFlagDesc)
|
||||
updateContractsCmd.Flags().String(contractsInitFlag, "", "Path to archive with compiled FrostFS contracts")
|
||||
_ = updateContractsCmd.MarkFlagRequired(contractsInitFlag)
|
||||
updateContractsCmd.Flags().String(contractsInitFlag, "", contractsInitFlagDesc)
|
||||
updateContractsCmd.Flags().String(contractsURLFlag, "", contractsURLFlagDesc)
|
||||
updateContractsCmd.MarkFlagsMutuallyExclusive(contractsInitFlag, contractsURLFlag)
|
||||
}
|
||||
|
||||
func initDumpBalancesCmd() {
|
||||
|
@ -441,8 +445,8 @@ func initInitCmd() {
|
|||
RootCmd.AddCommand(initCmd)
|
||||
initCmd.Flags().String(alphabetWalletsFlag, "", alphabetWalletsFlagDesc)
|
||||
initCmd.Flags().StringP(endpointFlag, endpointFlagShort, "", endpointFlagDesc)
|
||||
initCmd.Flags().String(contractsInitFlag, "", "Path to archive with compiled FrostFS contracts")
|
||||
_ = initCmd.MarkFlagRequired(contractsInitFlag)
|
||||
initCmd.Flags().String(contractsInitFlag, "", contractsInitFlagDesc)
|
||||
initCmd.Flags().String(contractsURLFlag, "", contractsURLFlagDesc)
|
||||
initCmd.Flags().Uint(epochDurationCLIFlag, 240, "Amount of side chain blocks in one FrostFS epoch")
|
||||
initCmd.Flags().Uint(maxObjectSizeCLIFlag, 67108864, "Max single object size in bytes")
|
||||
initCmd.Flags().Bool(homomorphicHashDisabledCLIFlag, false, "Disable object homomorphic hashing")
|
||||
|
@ -451,6 +455,7 @@ func initInitCmd() {
|
|||
initCmd.Flags().Uint64(containerAliasFeeCLIFlag, 500, "Container alias fee")
|
||||
initCmd.Flags().String(protoConfigPath, "", "Path to the consensus node configuration")
|
||||
initCmd.Flags().String(localDumpFlag, "", "Path to the blocks dump file")
|
||||
initCmd.MarkFlagsMutuallyExclusive(contractsInitFlag, contractsURLFlag)
|
||||
}
|
||||
|
||||
func initGenerateAlphabetCmd() {
|
||||
|
|
4
go.mod
4
go.mod
|
@ -3,6 +3,7 @@ module git.frostfs.info/TrueCloudLab/frostfs-node
|
|||
go 1.20
|
||||
|
||||
require (
|
||||
code.gitea.io/sdk/gitea v0.17.1
|
||||
git.frostfs.info/TrueCloudLab/frostfs-api-go/v2 v2.16.1-0.20240112150928-72885aae835c
|
||||
git.frostfs.info/TrueCloudLab/frostfs-contract v0.18.1-0.20240115082915-f2a82aa635aa
|
||||
git.frostfs.info/TrueCloudLab/frostfs-observability v0.0.0-20231101111734-b3ad3335ff65
|
||||
|
@ -61,8 +62,10 @@ require (
|
|||
github.com/consensys/gnark-crypto v0.12.2-0.20231222162921-eb75782795d2 // indirect
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.3 // indirect
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
||||
github.com/davidmz/go-pageant v1.0.2 // indirect
|
||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect
|
||||
github.com/fsnotify/fsnotify v1.7.0 // indirect
|
||||
github.com/go-fed/httpsig v1.1.0 // indirect
|
||||
github.com/go-logr/logr v1.4.1 // indirect
|
||||
github.com/go-logr/stdr v1.2.2 // indirect
|
||||
github.com/golang/protobuf v1.5.3 // indirect
|
||||
|
@ -71,6 +74,7 @@ require (
|
|||
github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.0 // indirect
|
||||
github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.0.1 // indirect
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.0 // indirect
|
||||
github.com/hashicorp/go-version v1.6.0 // indirect
|
||||
github.com/hashicorp/golang-lru v1.0.2 // indirect
|
||||
github.com/hashicorp/hcl v1.0.0 // indirect
|
||||
github.com/holiman/uint256 v1.2.4 // indirect
|
||||
|
|
BIN
go.sum
BIN
go.sum
Binary file not shown.
Loading…
Reference in a new issue