Skip to content

Commit

Permalink
Merge branch 'hyperledger:main' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
rakshita-kaulgud committed Oct 15, 2021
2 parents 4987fc4 + 258c705 commit 6196c1e
Show file tree
Hide file tree
Showing 12 changed files with 377 additions and 31 deletions.
2 changes: 2 additions & 0 deletions cmd/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,8 @@ func init() {
initCmd.Flags().StringVarP(&blockchainProviderSelection, "blockchain-provider", "", "geth", fmt.Sprintf("Blockchain provider to use. Options are: %v", stacks.BlockchainProviderStrings))
initCmd.Flags().StringVarP(&tokensProviderSelection, "tokens-provider", "", "erc1155", fmt.Sprintf("Tokens provider to use. Options are: %v", stacks.TokensProviderStrings))
initCmd.Flags().IntVarP(&initOptions.ExternalProcesses, "external", "e", 0, "Manage a number of FireFly core processes outside of the docker-compose stack - useful for development and debugging")
initCmd.Flags().StringVarP(&initOptions.FireFlyVersion, "release", "r", "latest", "Select the FireFly release version to use")
initCmd.Flags().StringVarP(&initOptions.ManifestPath, "manifest", "m", "", "Path to a manifest.json file containing the versions of each FireFly microservice to use. Overrides the --release flag.")
initCmd.Flags().BoolVar(&promptNames, "prompt-names", false, "Prompt for org and node names instead of using the defaults")

rootCmd.AddCommand(initCmd)
Expand Down
74 changes: 74 additions & 0 deletions cmd/pull.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
// Copyright © 2021 Kaleido, Inc.
//
// SPDX-License-Identifier: Apache-2.0
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package cmd

import (
"errors"
"time"

"github.com/briandowns/spinner"
"github.com/hyperledger/firefly-cli/internal/log"
"github.com/hyperledger/firefly-cli/internal/stacks"
"github.com/spf13/cobra"
)

var pullOptions stacks.PullOptions

var pullCmd = &cobra.Command{
Use: "pull <stack_name>",
Short: "Pull a stack",
Long: `Pull a stack
Pull the images for a stack .
`,
RunE: func(cmd *cobra.Command, args []string) error {
var spin *spinner.Spinner
if fancyFeatures && !verbose {
spin = spinner.New(spinner.CharSets[11], 100*time.Millisecond)
spin.FinalMSG = "done"
logger = &log.SpinnerLogger{
Spinner: spin,
}
}

stackManager := stacks.NewStackManager(logger)
if len(args) == 0 {
return errors.New("no stack specified")
}
stackName := args[0]

if err := stackManager.LoadStack(stackName); err != nil {
return err
}
if spin != nil {
spin.Start()
}
if err := stackManager.PullStack(verbose, &pullOptions); err != nil {
return err
}
if spin != nil {
spin.Stop()
}
return nil
},
}

func init() {
pullCmd.Flags().IntVarP(&pullOptions.Retries, "retries", "r", 0, "Retry attempts to perform on image pull failure")

rootCmd.AddCommand(pullCmd)
}
3 changes: 1 addition & 2 deletions cmd/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ This command will start a stack and run it in the background.
if spin != nil {
spin.Start()
}
if err := stackManager.StartStack(fancyFeatures, verbose, &startOptions); err != nil {
if err := stackManager.StartStack(verbose, &startOptions); err != nil {
return err
}
if spin != nil {
Expand All @@ -86,7 +86,6 @@ This command will start a stack and run it in the background.
}

func init() {
startCmd.Flags().BoolVarP(&startOptions.NoPull, "no-pull", "n", false, "Do not pull latest images when starting")
startCmd.Flags().BoolVarP(&startOptions.NoRollback, "no-rollback", "b", false, "Do not automatically rollback changes if first time setup fails")
rootCmd.AddCommand(startCmd)
}
2 changes: 1 addition & 1 deletion internal/blockchain/ethereum/ethconnect/docker.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ func GetEthconnectServiceDefinitions(s *types.Stack) []*docker.ServiceDefinition
serviceDefinitions[i] = &docker.ServiceDefinition{
ServiceName: "ethconnect_" + member.ID,
Service: &docker.Service{
Image: "ghcr.io/hyperledger/firefly-ethconnect:latest",
Image: s.VersionManifest.Ethconnect.GetDockerImageString(),
ContainerName: fmt.Sprintf("%s_ethconnect_%v", s.Name, i),
Command: "rest -U http://127.0.0.1:8080 -I ./abis -r http://geth:8545 -E ./events -d 3",
DependsOn: map[string]map[string]string{"geth": {"condition": "service_started"}},
Expand Down
74 changes: 74 additions & 0 deletions internal/core/manifest.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
// Copyright © 2021 Kaleido, Inc.
//
// SPDX-License-Identifier: Apache-2.0
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package core

import (
"encoding/json"
"fmt"
"io/ioutil"

"github.com/hyperledger/firefly-cli/pkg/types"
)

func GetLatestReleaseManifest() (*types.VersionManifest, error) {
latestRelease, err := getLatestFireFlyRelease()
if err != nil {
return nil, err
}
return GetReleaseManifest(latestRelease.TagName)
}

func GetReleaseManifest(version string) (*types.VersionManifest, error) {
manifest := &types.VersionManifest{}
if err := request("GET", fmt.Sprintf("https://raw.githubusercontent.com/hyperledger/firefly/%s/manifest.json", version), nil, &manifest); err != nil {
return nil, err
}
if manifest.FireFly == nil {
// Fill in the FireFly version number
manifest.FireFly = &types.ManifestEntry{
Image: "ghcr.io/hyperledger/firefly",
Tag: version,
}
}
return manifest, nil
}

func getLatestFireFlyRelease() (*types.GitHubRelease, error) {
release := &types.GitHubRelease{}
if err := request("GET", "https://api.github.com/repos/hyperledger/firefly/releases/latest", nil, release); err != nil {
return nil, err
}
return release, nil
}

func ReadManifestFile(p string) (*types.VersionManifest, error) {
d, err := ioutil.ReadFile(p)
if err != nil {
return nil, err
}
var manifest *types.VersionManifest
err = json.Unmarshal(d, &manifest)

// If core is not specified in the manifest, use a locally built image called "firefly"
if manifest.FireFly == nil {
manifest.FireFly = &types.ManifestEntry{
Image: "hyperledger/firefly",
Local: true,
}
}
return manifest, err
}
52 changes: 52 additions & 0 deletions internal/core/manifest_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// Copyright © 2021 Kaleido, Inc.
//
// SPDX-License-Identifier: Apache-2.0
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package core

import (
"testing"

"github.com/stretchr/testify/assert"
)

func TestGetLatestFireFlyRelease(T *testing.T) {
gitHubRelease, err := getLatestFireFlyRelease()
assert.NoError(T, err)
assert.NotNil(T, gitHubRelease)
assert.NotEmpty(T, gitHubRelease.TagName)
}

func TestGetFireFlyManifest(T *testing.T) {
manifest, err := GetReleaseManifest("main")
assert.NoError(T, err)
assert.NotNil(T, manifest)
assert.NotNil(T, manifest.FireFly)
assert.NotNil(T, manifest.Ethconnect)
assert.NotNil(T, manifest.Fabconnect)
assert.NotNil(T, manifest.DataExchange)
assert.NotNil(T, manifest.Tokens)
}

func TestGetLatestReleaseManifest(T *testing.T) {
manifest, err := GetLatestReleaseManifest()
assert.NoError(T, err)
assert.NotNil(T, manifest)
assert.NotNil(T, manifest.FireFly)
assert.NotNil(T, manifest.Ethconnect)
assert.NotNil(T, manifest.Fabconnect)
assert.NotNil(T, manifest.DataExchange)
assert.NotNil(T, manifest.Tokens)
}
15 changes: 15 additions & 0 deletions internal/docker/docker.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,21 @@ func RemoveVolume(volumeName string, verbose bool) error {
return RunDockerCommand(".", verbose, verbose, "volume", "remove", volumeName)
}

func RunDockerCommandRetry(workingDir string, showCommand bool, pipeStdout bool, retries int, command ...string) error {
attempt := 0
for {
err := RunDockerCommand(workingDir, showCommand, pipeStdout, command...)
if err != nil && attempt < retries {
attempt++
continue
} else if err != nil {
return err
}
break
}
return nil
}

func RunDockerCommand(workingDir string, showCommand bool, pipeStdout bool, command ...string) error {
dockerCmd := exec.Command("docker", command...)
dockerCmd.Dir = workingDir
Expand Down
22 changes: 12 additions & 10 deletions internal/docker/docker_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,19 +69,21 @@ var StandardLogOptions = &LoggingConfig{
},
}

func CreateDockerCompose(stack *types.Stack) *DockerComposeConfig {
func CreateDockerCompose(s *types.Stack) *DockerComposeConfig {
compose := &DockerComposeConfig{
Version: "2.1",
Services: make(map[string]*Service),
Volumes: make(map[string]struct{}),
}

for _, member := range stack.Members {
for _, member := range s.Members {

// Look at the VersionManifest to see if a specific version of FireFly was provided, else use latest, assuming a locally built image

if !member.External {
compose.Services["firefly_core_"+member.ID] = &Service{
Image: "ghcr.io/hyperledger/firefly:latest",
ContainerName: fmt.Sprintf("%s_firefly_core_%s", stack.Name, member.ID),
Image: s.VersionManifest.FireFly.GetDockerImageString(),
ContainerName: fmt.Sprintf("%s_firefly_core_%s", s.Name, member.ID),
Ports: []string{
fmt.Sprintf("%d:%d", member.ExposedFireflyPort, member.ExposedFireflyPort),
fmt.Sprintf("%d:%d", member.ExposedFireflyAdminPort, member.ExposedFireflyAdminPort),
Expand All @@ -96,10 +98,10 @@ func CreateDockerCompose(stack *types.Stack) *DockerComposeConfig {
compose.Volumes[fmt.Sprintf("firefly_core_%s", member.ID)] = struct{}{}
}

if stack.Database == "postgres" {
if s.Database == "postgres" {
compose.Services["postgres_"+member.ID] = &Service{
Image: "postgres",
ContainerName: fmt.Sprintf("%s_postgres_%s", stack.Name, member.ID),
ContainerName: fmt.Sprintf("%s_postgres_%s", s.Name, member.ID),
Ports: []string{fmt.Sprintf("%d:5432", member.ExposedPostgresPort)},
Environment: map[string]string{
"POSTGRES_PASSWORD": "f1refly",
Expand All @@ -124,13 +126,13 @@ func CreateDockerCompose(stack *types.Stack) *DockerComposeConfig {

compose.Services["ipfs_"+member.ID] = &Service{
Image: "ipfs/go-ipfs",
ContainerName: fmt.Sprintf("%s_ipfs_%s", stack.Name, member.ID),
ContainerName: fmt.Sprintf("%s_ipfs_%s", s.Name, member.ID),
Ports: []string{
fmt.Sprintf("%d:5001", member.ExposedIPFSApiPort),
fmt.Sprintf("%d:8080", member.ExposedIPFSGWPort),
},
Environment: map[string]string{
"IPFS_SWARM_KEY": stack.SwarmKey,
"IPFS_SWARM_KEY": s.SwarmKey,
"LIBP2P_FORCE_PNET": "1",
},
Volumes: []string{
Expand All @@ -144,8 +146,8 @@ func CreateDockerCompose(stack *types.Stack) *DockerComposeConfig {
compose.Volumes[fmt.Sprintf("ipfs_data_%s", member.ID)] = struct{}{}

compose.Services["dataexchange_"+member.ID] = &Service{
Image: "ghcr.io/hyperledger/firefly-dataexchange-https:latest",
ContainerName: fmt.Sprintf("%s_dataexchange_%s", stack.Name, member.ID),
Image: s.VersionManifest.DataExchange.GetDockerImageString(),
ContainerName: fmt.Sprintf("%s_dataexchange_%s", s.Name, member.ID),
Ports: []string{fmt.Sprintf("%d:3000", member.ExposedDataexchangePort)},
Volumes: []string{fmt.Sprintf("dataexchange_%s:/data", member.ID)},
Logging: StandardLogOptions,
Expand Down
Loading

0 comments on commit 6196c1e

Please sign in to comment.