cli: Add empty neofs-cli app structure

In the following release `neofs-cli` will be used to directly manage NeoFS Node.
All required definitions and interfaces are also moving from `neofs-api` to
`neofs-node` repository, so it's more convinient to have `neofs-cli` here.

Signed-off-by: Stanislav Bogatyrev <stanislav@nspcc.ru>
This commit is contained in:
Stanislav Bogatyrev 2020-08-04 17:46:12 +03:00 committed by Alex Vanin
parent f23d8a5f4a
commit 246a15de35
15 changed files with 410 additions and 6 deletions

21
Dockerfile.cli Normal file
View file

@ -0,0 +1,21 @@
FROM golang:1.14-alpine as basebuilder
RUN apk add --update make bash
FROM basebuilder as builder
ARG BUILD=now
ARG VERSION=dev
ARG REPO=repository
WORKDIR /src
COPY . /src
RUN make bin/neofs-cli
# Executable image
FROM scratch AS neofs-cli
WORKDIR /
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
COPY --from=builder /src/bin/neofs-cli /bin/neofs-cli
CMD ["neofs-cli"]

View file

@ -2,7 +2,9 @@
SHELL = bash SHELL = bash
REPO ?= $(shell go list -m) REPO ?= $(shell go list -m)
VERSION ?= "$(shell git describe --tags --dirty --always)" VERSION ?= $(shell git describe --tags --dirty --always)
BUILD ?= $(shell date -u --iso=seconds)
DEBUG ?= false
HUB_IMAGE ?= nspccdev/neofs HUB_IMAGE ?= nspccdev/neofs
HUB_TAG ?= "$(shell echo ${VERSION} | sed 's/^v//')" HUB_TAG ?= "$(shell echo ${VERSION} | sed 's/^v//')"
@ -10,8 +12,8 @@ HUB_TAG ?= "$(shell echo ${VERSION} | sed 's/^v//')"
BIN = bin BIN = bin
DIRS= $(BIN) DIRS= $(BIN)
# List of binaries to build. May be automated. # List of binaries to build.
CMDS = neofs-node neofs-ir CMDS = $(notdir $(basename $(wildcard cmd/*)))
CMS = $(addprefix $(BIN)/, $(CMDS)) CMS = $(addprefix $(BIN)/, $(CMDS))
BINS = $(addprefix $(BIN)/, $(CMDS)) BINS = $(addprefix $(BIN)/, $(CMDS))
@ -27,7 +29,9 @@ $(BINS): $(DIRS) dep
CGO_ENABLED=0 \ CGO_ENABLED=0 \
GO111MODULE=on \ GO111MODULE=on \
go build -v -trimpath \ go build -v -trimpath \
-ldflags "-X ${REPO}/misc.Version=$(VERSION) -X ${REPO}/misc.Build=${BUILD}" \ -ldflags "-X $(REPO)/misc.Version=$(VERSION) \
-X $(REPO)/misc.Build=$(BUILD) \
-X $(REPO)/misc.Debug=$(DEBUG)" \
-o $@ ./cmd/$(notdir $@) -o $@ ./cmd/$(notdir $@)
$(DIRS): $(DIRS):
@ -76,7 +80,7 @@ image-%:
-t $(HUB_IMAGE)-$*:$(HUB_TAG) . -t $(HUB_IMAGE)-$*:$(HUB_TAG) .
# Build all Docker images # Build all Docker images
images: image-storage image-ir images: image-storage image-ir image-cli
# Run all code formaters # Run all code formaters
fmts: fmt imports fmts: fmt imports

7
cmd/neofs-cli/main.go Normal file
View file

@ -0,0 +1,7 @@
package main
import cmd "github.com/nspcc-dev/neofs-node/cmd/neofs-cli/modules"
func main() {
cmd.Execute()
}

View file

@ -0,0 +1,31 @@
package cmd
import (
"fmt"
"github.com/spf13/cobra"
)
// accountingCmd represents the accounting command
var accountingCmd = &cobra.Command{
Use: "accounting",
Short: "Operations with accounts and balances",
Long: `Operations with accounts and balances`,
Run: func(cmd *cobra.Command, args []string) {
fmt.Println("accounting called")
},
}
func init() {
rootCmd.AddCommand(accountingCmd)
// Here you will define your flags and configuration settings.
// Cobra supports Persistent Flags which will work for this command
// and all subcommands, e.g.:
// accountingCmd.PersistentFlags().String("foo", "", "A help for foo")
// Cobra supports local flags which will only run when this command
// is called directly, e.g.:
// accountingCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
}

View file

@ -0,0 +1,31 @@
package cmd
import (
"fmt"
"github.com/spf13/cobra"
)
// aclCmd represents the acl command
var aclCmd = &cobra.Command{
Use: "acl",
Short: "Operations with Access Control Lists",
Long: `Operations with Access Control Lists`,
Run: func(cmd *cobra.Command, args []string) {
fmt.Println("acl called")
},
}
func init() {
rootCmd.AddCommand(aclCmd)
// Here you will define your flags and configuration settings.
// Cobra supports Persistent Flags which will work for this command
// and all subcommands, e.g.:
// aclCmd.PersistentFlags().String("foo", "", "A help for foo")
// Cobra supports local flags which will only run when this command
// is called directly, e.g.:
// aclCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
}

View file

@ -0,0 +1,62 @@
package cmd
import (
"os"
"github.com/spf13/cobra"
)
var completionCmd = &cobra.Command{
Use: "completion [bash|zsh|fish|powershell]",
Short: "Generate completion script",
Long: `To load completions:
Bash:
$ source <(neofs-cli completion bash)
# To load completions for each session, execute once:
Linux:
$ neofs-cli completion bash > /etc/bash_completion.d/neofs-cli
MacOS:
$ neofs-cli completion bash > /usr/local/etc/bash_completion.d/neofs-cli
Zsh:
# If shell completion is not already enabled in your environment you will need
# to enable it. You can execute the following once:
$ echo "autoload -U compinit; compinit" >> ~/.zshrc
# To load completions for each session, execute once:
$ neofs-cli completion zsh > "${fpath[1]}/_neofs-cli"
# You will need to start a new shell for this setup to take effect.
Fish:
$ neofs-cli completion fish | source
# To load completions for each session, execute once:
$ neofs-cli completion fish > ~/.config/fish/completions/neofs-cli.fish
`,
DisableFlagsInUseLine: true,
ValidArgs: []string{"bash", "zsh", "fish", "powershell"},
Args: cobra.ExactValidArgs(1),
Run: func(cmd *cobra.Command, args []string) {
switch args[0] {
case "bash":
_ = cmd.Root().GenBashCompletion(os.Stdout)
case "zsh":
_ = cmd.Root().GenZshCompletion(os.Stdout)
case "fish":
_ = cmd.Root().GenFishCompletion(os.Stdout, true)
case "powershell":
_ = cmd.Root().GenPowerShellCompletion(os.Stdout)
}
},
}
func init() {
rootCmd.AddCommand(completionCmd)
}

View file

@ -0,0 +1,31 @@
package cmd
import (
"fmt"
"github.com/spf13/cobra"
)
// containerCmd represents the container command
var containerCmd = &cobra.Command{
Use: "container",
Short: "Operations with Containers",
Long: `Operations with Containers`,
Run: func(cmd *cobra.Command, args []string) {
fmt.Println("container called")
},
}
func init() {
rootCmd.AddCommand(containerCmd)
// Here you will define your flags and configuration settings.
// Cobra supports Persistent Flags which will work for this command
// and all subcommands, e.g.:
// containerCmd.PersistentFlags().String("foo", "", "A help for foo")
// Cobra supports local flags which will only run when this command
// is called directly, e.g.:
// containerCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
}

View file

@ -0,0 +1,31 @@
package cmd
import (
"fmt"
"github.com/spf13/cobra"
)
// netmapCmd represents the netmap command
var netmapCmd = &cobra.Command{
Use: "netmap",
Short: "Operations with Network Map",
Long: `Operations with Network Map`,
Run: func(cmd *cobra.Command, args []string) {
fmt.Println("netmap called")
},
}
func init() {
rootCmd.AddCommand(netmapCmd)
// Here you will define your flags and configuration settings.
// Cobra supports Persistent Flags which will work for this command
// and all subcommands, e.g.:
// netmapCmd.PersistentFlags().String("foo", "", "A help for foo")
// Cobra supports local flags which will only run when this command
// is called directly, e.g.:
// netmapCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
}

View file

@ -0,0 +1,31 @@
package cmd
import (
"fmt"
"github.com/spf13/cobra"
)
// objectCmd represents the object command
var objectCmd = &cobra.Command{
Use: "object",
Short: "Operations with Objects",
Long: `Operations with Objects`,
Run: func(cmd *cobra.Command, args []string) {
fmt.Println("object called")
},
}
func init() {
rootCmd.AddCommand(objectCmd)
// Here you will define your flags and configuration settings.
// Cobra supports Persistent Flags which will work for this command
// and all subcommands, e.g.:
// objectCmd.PersistentFlags().String("foo", "", "A help for foo")
// Cobra supports local flags which will only run when this command
// is called directly, e.g.:
// objectCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
}

View file

@ -0,0 +1,74 @@
package cmd
import (
"fmt"
"os"
"github.com/spf13/cobra"
homedir "github.com/mitchellh/go-homedir"
"github.com/spf13/viper"
)
var cfgFile string
// rootCmd represents the base command when called without any subcommands
var rootCmd = &cobra.Command{
Use: "neofs-cli",
Short: "Command Line Tool to work with NeoFS",
Long: `NeoFS CLI provides all basic interactions with NeoFS and it's services.
It contains commands for interaction with NeoFS nodes using different versions
of neofs-api and some useful utilities for compiling ACL rules from JSON
notation, managing container access through protocol gates, querying network map
and much more!`,
}
// Execute adds all child commands to the root command and sets flags appropriately.
// This is called by main.main(). It only needs to happen once to the rootCmd.
func Execute() {
if err := rootCmd.Execute(); err != nil {
fmt.Println(err)
os.Exit(1)
}
}
func init() {
cobra.OnInitialize(initConfig)
// Here you will define your flags and configuration settings.
// Cobra supports persistent flags, which, if defined here,
// will be global for your application.
rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.config/neofs-cli/config.yaml)")
// Cobra also supports local flags, which will only run
// when this action is called directly.
// rootCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
}
// initConfig reads in config file and ENV variables if set.
func initConfig() {
if cfgFile != "" {
// Use config file from the flag.
viper.SetConfigFile(cfgFile)
} else {
// Find home directory.
home, err := homedir.Dir()
if err != nil {
fmt.Println(err)
os.Exit(1)
}
// Search config in home directory with name ".main" (without extension).
viper.AddConfigPath(home)
viper.SetConfigName(".config/neofs-cli")
}
viper.AutomaticEnv() // read in environment variables that match
// If a config file is found, read it in.
if err := viper.ReadInConfig(); err == nil {
fmt.Println("Using config file:", viper.ConfigFileUsed())
}
}

View file

@ -0,0 +1,31 @@
package cmd
import (
"fmt"
"github.com/spf13/cobra"
)
// storagegroupCmd represents the storagegroup command
var storagegroupCmd = &cobra.Command{
Use: "storagegroup",
Short: "Operations with Storage Groups",
Long: `Operations with Storage Groups`,
Run: func(cmd *cobra.Command, args []string) {
fmt.Println("storagegroup called")
},
}
func init() {
rootCmd.AddCommand(storagegroupCmd)
// Here you will define your flags and configuration settings.
// Cobra supports Persistent Flags which will work for this command
// and all subcommands, e.g.:
// storagegroupCmd.PersistentFlags().String("foo", "", "A help for foo")
// Cobra supports local flags which will only run when this command
// is called directly, e.g.:
// storagegroupCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
}

View file

@ -0,0 +1,47 @@
package cmd
import (
"encoding/json"
"fmt"
"github.com/nspcc-dev/neofs-node/misc"
"github.com/spf13/cobra"
)
var (
// versionCmd represents the version command
versionCmd = &cobra.Command{
Use: "version",
Short: "Print version and exit",
Run: versionRun,
}
)
var flagJSON bool
type VersionInfo struct {
Version string `json:"Version,omitempty"`
Build string `json:"Build,omitempty"`
Debug string `json:"Debug,omitempty"`
}
func init() {
rootCmd.AddCommand(versionCmd)
versionCmd.Flags().BoolVarP(&flagJSON, "json", "j", false, "Print version information in JSON")
}
func versionRun(cmd *cobra.Command, args []string) {
versionInfo := VersionInfo{Version: misc.Version, Build: misc.Build, Debug: misc.Debug}
if flagJSON {
bytes, _ := json.Marshal(versionInfo)
fmt.Printf("%s", string(bytes)+"\n")
return
}
fmt.Printf("Version: %s \nBuild: %s \nDebug: %s\n",
versionInfo.Version,
versionInfo.Build,
versionInfo.Debug)
}

2
go.mod
View file

@ -6,6 +6,7 @@ require (
bou.ke/monkey v1.0.2 bou.ke/monkey v1.0.2
github.com/golang/protobuf v1.4.2 github.com/golang/protobuf v1.4.2
github.com/google/uuid v1.1.1 github.com/google/uuid v1.1.1
github.com/mitchellh/go-homedir v1.1.0
github.com/mr-tron/base58 v1.1.3 github.com/mr-tron/base58 v1.1.3
github.com/multiformats/go-multiaddr v0.2.0 github.com/multiformats/go-multiaddr v0.2.0
github.com/multiformats/go-multiaddr-net v0.1.2 // v0.1.1 => v0.1.2 github.com/multiformats/go-multiaddr-net v0.1.2 // v0.1.1 => v0.1.2
@ -17,6 +18,7 @@ require (
github.com/pkg/errors v0.9.1 github.com/pkg/errors v0.9.1
github.com/prometheus/client_golang v1.6.0 github.com/prometheus/client_golang v1.6.0
github.com/soheilhy/cmux v0.1.4 github.com/soheilhy/cmux v0.1.4
github.com/spf13/cobra v1.0.0
github.com/spf13/pflag v1.0.5 // indirect github.com/spf13/pflag v1.0.5 // indirect
github.com/spf13/viper v1.7.0 github.com/spf13/viper v1.7.0
github.com/stretchr/testify v1.6.1 github.com/stretchr/testify v1.6.1

BIN
go.sum

Binary file not shown.

View file

@ -23,5 +23,6 @@ var (
Version = "dev" Version = "dev"
// Debug is an application debug mode flag. // Debug is an application debug mode flag.
Debug = "true" Debug = "false"
) )