[#466] adm: Allow to download contracts from Gitea
All checks were successful
DCO action / DCO (pull_request) Successful in 2m25s
Vulncheck / Vulncheck (pull_request) Successful in 1m58s
Tests and linters / Staticcheck (pull_request) Successful in 5m31s
Tests and linters / Tests (1.21) (pull_request) Successful in 5m53s
Tests and linters / Tests (1.20) (pull_request) Successful in 6m6s
Tests and linters / Lint (pull_request) Successful in 6m22s
Tests and linters / Tests with -race (pull_request) Successful in 6m41s
Build / Build Components (1.21) (pull_request) Successful in 1m40s
Build / Build Components (1.20) (pull_request) Successful in 1m56s
All checks were successful
DCO action / DCO (pull_request) Successful in 2m25s
Vulncheck / Vulncheck (pull_request) Successful in 1m58s
Tests and linters / Staticcheck (pull_request) Successful in 5m31s
Tests and linters / Tests (1.21) (pull_request) Successful in 5m53s
Tests and linters / Tests (1.20) (pull_request) Successful in 6m6s
Tests and linters / Lint (pull_request) Successful in 6m22s
Tests and linters / Tests with -race (pull_request) Successful in 6m41s
Build / Build Components (1.21) (pull_request) Successful in 1m40s
Build / Build Components (1.20) (pull_request) Successful in 1m56s
Signed-off-by: Olga Konstantinova <kola43843@gmail.com>
This commit is contained in:
parent
805862f4b7
commit
80b581d499
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
|
Contracts map[string]*contractState
|
||||||
Command *cobra.Command
|
Command *cobra.Command
|
||||||
ContractPath string
|
ContractPath string
|
||||||
|
ContractURL string
|
||||||
}
|
}
|
||||||
|
|
||||||
var ErrTooManyAlphabetNodes = fmt.Errorf("too many alphabet nodes (maximum allowed is %d)", maxAlphabetNodes)
|
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
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var ctrURL string
|
||||||
|
if needContracts {
|
||||||
|
ctrURL, _ = cmd.Flags().GetString(contractsURLFlag)
|
||||||
|
}
|
||||||
|
|
||||||
if err := checkNotaryEnabled(c); err != nil {
|
if err := checkNotaryEnabled(c); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -176,6 +182,7 @@ func newInitializeContext(cmd *cobra.Command, v *viper.Viper) (*initializeContex
|
||||||
Command: cmd,
|
Command: cmd,
|
||||||
Contracts: make(map[string]*contractState),
|
Contracts: make(map[string]*contractState),
|
||||||
ContractPath: ctrPath,
|
ContractPath: ctrPath,
|
||||||
|
ContractURL: ctrURL,
|
||||||
}
|
}
|
||||||
|
|
||||||
if needContracts {
|
if needContracts {
|
||||||
|
|
|
@ -399,10 +399,14 @@ func (c *initializeContext) readContracts(names []string) error {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
var r io.ReadCloser
|
var r io.ReadCloser
|
||||||
if c.ContractPath == "" {
|
if c.ContractPath != "" {
|
||||||
return errors.New("contracts flag is missing")
|
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 {
|
if err != nil {
|
||||||
return fmt.Errorf("can't open contracts archive: %w", err)
|
return fmt.Errorf("can't open contracts archive: %w", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,9 @@ const (
|
||||||
storageGasCLIFlag = "initial-gas"
|
storageGasCLIFlag = "initial-gas"
|
||||||
storageGasConfigFlag = "storage.initial_gas"
|
storageGasConfigFlag = "storage.initial_gas"
|
||||||
contractsInitFlag = "contracts"
|
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"
|
maxObjectSizeInitFlag = "network.max_object_size"
|
||||||
maxObjectSizeCLIFlag = "max-object-size"
|
maxObjectSizeCLIFlag = "max-object-size"
|
||||||
epochDurationInitFlag = "network.epoch_duration"
|
epochDurationInitFlag = "network.epoch_duration"
|
||||||
|
@ -370,8 +373,9 @@ func initUpdateContractsCmd() {
|
||||||
RootCmd.AddCommand(updateContractsCmd)
|
RootCmd.AddCommand(updateContractsCmd)
|
||||||
updateContractsCmd.Flags().String(alphabetWalletsFlag, "", alphabetWalletsFlagDesc)
|
updateContractsCmd.Flags().String(alphabetWalletsFlag, "", alphabetWalletsFlagDesc)
|
||||||
updateContractsCmd.Flags().StringP(endpointFlag, endpointFlagShort, "", endpointFlagDesc)
|
updateContractsCmd.Flags().StringP(endpointFlag, endpointFlagShort, "", endpointFlagDesc)
|
||||||
updateContractsCmd.Flags().String(contractsInitFlag, "", "Path to archive with compiled FrostFS contracts")
|
updateContractsCmd.Flags().String(contractsInitFlag, "", contractsInitFlagDesc)
|
||||||
_ = updateContractsCmd.MarkFlagRequired(contractsInitFlag)
|
updateContractsCmd.Flags().String(contractsURLFlag, "", contractsURLFlagDesc)
|
||||||
|
updateContractsCmd.MarkFlagsMutuallyExclusive(contractsInitFlag, contractsURLFlag)
|
||||||
}
|
}
|
||||||
|
|
||||||
func initDumpBalancesCmd() {
|
func initDumpBalancesCmd() {
|
||||||
|
@ -441,8 +445,8 @@ func initInitCmd() {
|
||||||
RootCmd.AddCommand(initCmd)
|
RootCmd.AddCommand(initCmd)
|
||||||
initCmd.Flags().String(alphabetWalletsFlag, "", alphabetWalletsFlagDesc)
|
initCmd.Flags().String(alphabetWalletsFlag, "", alphabetWalletsFlagDesc)
|
||||||
initCmd.Flags().StringP(endpointFlag, endpointFlagShort, "", endpointFlagDesc)
|
initCmd.Flags().StringP(endpointFlag, endpointFlagShort, "", endpointFlagDesc)
|
||||||
initCmd.Flags().String(contractsInitFlag, "", "Path to archive with compiled FrostFS contracts")
|
initCmd.Flags().String(contractsInitFlag, "", contractsInitFlagDesc)
|
||||||
_ = initCmd.MarkFlagRequired(contractsInitFlag)
|
initCmd.Flags().String(contractsURLFlag, "", contractsURLFlagDesc)
|
||||||
initCmd.Flags().Uint(epochDurationCLIFlag, 240, "Amount of side chain blocks in one FrostFS epoch")
|
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().Uint(maxObjectSizeCLIFlag, 67108864, "Max single object size in bytes")
|
||||||
initCmd.Flags().Bool(homomorphicHashDisabledCLIFlag, false, "Disable object homomorphic hashing")
|
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().Uint64(containerAliasFeeCLIFlag, 500, "Container alias fee")
|
||||||
initCmd.Flags().String(protoConfigPath, "", "Path to the consensus node configuration")
|
initCmd.Flags().String(protoConfigPath, "", "Path to the consensus node configuration")
|
||||||
initCmd.Flags().String(localDumpFlag, "", "Path to the blocks dump file")
|
initCmd.Flags().String(localDumpFlag, "", "Path to the blocks dump file")
|
||||||
|
initCmd.MarkFlagsMutuallyExclusive(contractsInitFlag, contractsURLFlag)
|
||||||
}
|
}
|
||||||
|
|
||||||
func initGenerateAlphabetCmd() {
|
func initGenerateAlphabetCmd() {
|
||||||
|
|
4
go.mod
4
go.mod
|
@ -3,6 +3,7 @@ module git.frostfs.info/TrueCloudLab/frostfs-node
|
||||||
go 1.20
|
go 1.20
|
||||||
|
|
||||||
require (
|
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-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-contract v0.18.1-0.20240115082915-f2a82aa635aa
|
||||||
git.frostfs.info/TrueCloudLab/frostfs-observability v0.0.0-20231101111734-b3ad3335ff65
|
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/consensys/gnark-crypto v0.12.2-0.20231222162921-eb75782795d2 // indirect
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.3 // 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/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/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect
|
||||||
github.com/fsnotify/fsnotify v1.7.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/logr v1.4.1 // indirect
|
||||||
github.com/go-logr/stdr v1.2.2 // indirect
|
github.com/go-logr/stdr v1.2.2 // indirect
|
||||||
github.com/golang/protobuf v1.5.3 // 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/providers/prometheus v1.0.0 // indirect
|
||||||
github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.0.1 // 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/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/golang-lru v1.0.2 // indirect
|
||||||
github.com/hashicorp/hcl v1.0.0 // indirect
|
github.com/hashicorp/hcl v1.0.0 // indirect
|
||||||
github.com/holiman/uint256 v1.2.4 // 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