Skip to content

Commit

Permalink
[FAB-11334] Adds a 'peer node unjoin' CLI entrypoint to unjoin a peer…
Browse files Browse the repository at this point in the history
… from a channel (#2769)

This change adds a Viper cobra.Command to unjoin the peer from a specified channel.

Signed-off-by: Josh Kneubuhl <jkneubuh@us.ibm.com>
  • Loading branch information
jkneubuh authored and denyeart committed Jul 30, 2021
1 parent 87ea070 commit ea48474
Show file tree
Hide file tree
Showing 7 changed files with 139 additions and 2 deletions.
25 changes: 25 additions & 0 deletions docs/source/commands/peernode.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ The `peer node` command has the following subcommands:
* resume
* rollback
* start
* unjoin
* upgrade-dbs

## peer node pause
Expand Down Expand Up @@ -98,6 +99,19 @@ Flags:
```


## peer node unjoin
```
Unjoin the peer from a channel. When the command is executed, the peer must be offline.
Usage:
peer node unjoin [flags]
Flags:
-c, --channelID string Channel to unjoin.
-h, --help help for unjoin
```


## peer node upgrade-dbs
```
Upgrades databases by directly updating the database format or dropping the databases. Dropped databases will be rebuilt with new format upon peer restart. When the command is executed, the peer must be offline.
Expand Down Expand Up @@ -176,6 +190,17 @@ peer node start --peer-chaincodedev
starts a peer node in chaincode development mode. Normally chaincode containers are started
and maintained by peer. However in chaincode development mode, chaincode is built and started by the user. This mode is useful during chaincode development phase for iterative development.

### peer node unjoin example

The following command:

```
peer node unjoin -c mychannel
```

unjoins the peer from channel `mychannel`, removing all content from the ledger and transient storage. When unjoining a channel, the peer must be shut down.


### peer node upgrade-dbs example

The following command:
Expand Down
11 changes: 11 additions & 0 deletions docs/wrappers/peer_node_postscript.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,17 @@ peer node start --peer-chaincodedev
starts a peer node in chaincode development mode. Normally chaincode containers are started
and maintained by peer. However in chaincode development mode, chaincode is built and started by the user. This mode is useful during chaincode development phase for iterative development.

### peer node unjoin example

The following command:

```
peer node unjoin -c mychannel
```

unjoins the peer from channel `mychannel`, removing all content from the ledger and transient storage. When unjoining a channel, the peer must be shut down.


### peer node upgrade-dbs example

The following command:
Expand Down
1 change: 1 addition & 0 deletions docs/wrappers/peer_node_preamble.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,5 @@ The `peer node` command has the following subcommands:
* resume
* rollback
* start
* unjoin
* upgrade-dbs
3 changes: 2 additions & 1 deletion internal/peer/node/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import (

const (
nodeFuncName = "node"
nodeCmdDes = "Operate a peer node: start|reset|rollback|pause|resume|rebuild-dbs|upgrade-dbs."
nodeCmdDes = "Operate a peer node: start|reset|rollback|pause|resume|rebuild-dbs|unjoin|upgrade-dbs."
)

var logger = flogging.MustGetLogger("nodeCmd")
Expand All @@ -28,6 +28,7 @@ func Cmd() *cobra.Command {
nodeCmd.AddCommand(pauseCmd())
nodeCmd.AddCommand(resumeCmd())
nodeCmd.AddCommand(rebuildDBsCmd())
nodeCmd.AddCommand(unjoinCmd())
nodeCmd.AddCommand(upgradeDBsCmd())
return nodeCmd
}
Expand Down
62 changes: 62 additions & 0 deletions internal/peer/node/unjoin.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*
Copyright IBM Corp. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/

package node

import (
"path/filepath"

coreconfig "github.com/hyperledger/fabric/core/config"
"github.com/hyperledger/fabric/core/ledger/kvledger"
"github.com/hyperledger/fabric/core/transientstore"
"github.com/hyperledger/fabric/internal/peer/common"
"github.com/pkg/errors"
"github.com/spf13/cobra"
)

func unjoinCmd() *cobra.Command {
var channelID string

cmd := &cobra.Command{
Use: "unjoin",
Short: "Unjoin the peer from a channel.",
Long: "Unjoin the peer from a channel. When the command is executed, the peer must be offline.",
RunE: func(cmd *cobra.Command, args []string) error {
if channelID == common.UndefinedParamValue {
return errors.New("Must supply channel ID")
}

if err := unjoinChannel(channelID); err != nil {
return err
}

return nil
},
}
flags := cmd.Flags()
flags.StringVarP(&channelID, "channelID", "c", common.UndefinedParamValue, "Channel to unjoin.")

return cmd
}

// unjoin the peer from a channel.
func unjoinChannel(channelID string) error {
// transient storage must be scrubbed prior to removing the kvledger for the channel. Once the
// kvledger storage has been removed, a subsequent ledger removal will return a "no such ledger" error.
// By removing the transient storage prior to deleting the ledger, a crash may be recovered by re-running
// the peer unjoin.
transientStoragePath := filepath.Join(coreconfig.GetPath("peer.fileSystemPath"), "transientstore")
if err := transientstore.Drop(transientStoragePath, channelID); err != nil {
return err
}

config := ledgerConfig()
if err := kvledger.UnjoinChannel(config, channelID); err != nil {
return err
}

return nil
}
37 changes: 37 additions & 0 deletions internal/peer/node/unjoin_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
Copyright IBM Corp. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/

package node

import (
"os"
"testing"

"github.com/spf13/viper"
"github.com/stretchr/testify/require"
)

func TestUnjoinCmd(t *testing.T) {
t.Run("when the channelID is not specified", func(t *testing.T) {
cmd := unjoinCmd()
args := []string{}
cmd.SetArgs(args)
err := cmd.Execute()
require.EqualError(t, err, "Must supply channel ID")
})

t.Run("when the channel does not exist", func(t *testing.T) {
testPath := "/tmp/hyperledger/test"
os.RemoveAll(testPath)
viper.Set("peer.fileSystemPath", testPath)
defer os.RemoveAll(testPath)

cmd := unjoinCmd()
cmd.SetArgs([]string{"-c", "invalid_channel_does_not_exist"})
err := cmd.Execute()
require.EqualError(t, err, "unjoin channel [invalid_channel_does_not_exist]: cannot update ledger status, ledger [invalid_channel_does_not_exist] does not exist")
})
}
2 changes: 1 addition & 1 deletion scripts/help_docs.sh
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ generateOrCheck \
docs/wrappers/peer_channel_postscript.md \
"${commands[@]}"

commands=("peer node pause" "peer node rebuild-dbs" "peer node reset" "peer node resume" "peer node rollback" "peer node start" "peer node upgrade-dbs")
commands=("peer node pause" "peer node rebuild-dbs" "peer node reset" "peer node resume" "peer node rollback" "peer node start" "peer node unjoin" "peer node upgrade-dbs")
generateOrCheck \
docs/source/commands/peernode.md \
docs/wrappers/peer_node_preamble.md \
Expand Down

0 comments on commit ea48474

Please sign in to comment.