Merge branch 'development' into wwlog-newlines

This commit is contained in:
Christian Goll
2022-10-13 14:46:03 +02:00
committed by GitHub
36 changed files with 1804 additions and 391 deletions

View File

@@ -6,6 +6,7 @@ on:
jobs:
publish:
if: ${{ github.repository_owner == 'hcpng' }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
@@ -51,10 +52,10 @@ jobs:
- name: Update website repo
run: |
git clone git@github.com:hpcng/warewulf-web.git ~/warewulf-web
mkdir -p ~/warewulf-web/src/static/docs
rm -rf ~/warewulf-web/src/static/docs/${GITHUB_REF##*/}
cp -r userdocs/_build/html ~/warewulf-web/src/static/docs/${GITHUB_REF##*/}
mkdir -p ~/warewulf-web/static/docs
rm -rf ~/warewulf-web/static/docs/${GITHUB_REF##*/}
cp -r userdocs/_build/html ~/warewulf-web/static/docs/${GITHUB_REF##*/}
cd ~/warewulf-web
git add src/static/docs/${GITHUB_REF##*/}
git add static/docs/${GITHUB_REF##*/}
git commit -m "Update ${GITHUB_REF##*/} docs"
git push

1
.gitignore vendored
View File

@@ -16,6 +16,7 @@
/wwapic
/wwapid
/wwapird
/print_defaults
# other created files
/man_pages

View File

@@ -5,6 +5,31 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
### Added
- Changed internal interacation between the on disk YAML format and the in memory
format. This enables the command line options to be autogenerated from the datastructures.
Also this keeps the options for profiles and node set/add commands in strict sync.
- Added `node edit/export/import` where the edit command exposes the YAML config for the
given nodes in an editor. Nodes can also be added with this command. The export command
simply drops the YAML config for the given nodes. With the import command nodes can be
imported as YAML or as a CSV file. The CSV file must havr a header in where the first field
must always be the nodename, the rest of the fields are the same as the long commandline
options. Network device must have the form net.$NETNAME.$NETOPTION, which would e.g. be
net.default.ipaddr
- The default value (like kernel args) are no read in from the configuration file
default.conf. If this file couldn't be read built in default values will be used.
- Template files for NetworkManager are now present in the wwinit overlay. A interface must
have the type ethernet or infiniband that these will be brought up by NetworkManager
- Listings of container via `wwctl container list` will now show the creation,modification
date and the size.
### Bug fixes
- For the connections of `wwctl ssh` the primary interface will be used
- Fixed kernel version in `wwctl container show`
- remove the container image and not only the rootfs dir on delete
- include and exclude handling for container were fixed
## [4.3.0] 2022-06-25
### Added
- All configurations files for the host (/etc/exports, /etc/dhcpd.conf, /etc/hosts) are now
populated from the (OVERLAYDIR/host/etc/{exports|dhcpd|hosts}.ww . Also other configuration
@@ -41,6 +66,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Fixed
- GID is no longer changed to `0` when unspecified during chown
- Proper handling of uid/gid arguments during `wwctl overlay chown`
- /etc/warewulf/excludes stored in the container definition is now
processed correctly, also excluding the contents of an excluded
directory automatically.
## [4.1.0] - 2021-07-29

View File

@@ -95,7 +95,7 @@ export GOPROXY
# built tags needed for wwbuild binary
WW_GO_BUILD_TAGS := containers_image_openpgp containers_image_ostree
all: config vendor wwctl wwclient bash_completion.d man_pages config_defaults wwapid wwapic wwapird
all: config vendor wwctl wwclient bash_completion.d man_pages config_defaults print_defaults wwapid wwapic wwapird
build: lint test-it vet all
@@ -174,6 +174,7 @@ files: all
test -f $(DESTDIR)$(SYSCONFDIR)/warewulf/wwapic.conf || install -m 644 etc/wwapic.conf $(DESTDIR)$(SYSCONFDIR)/warewulf/
test -f $(DESTDIR)$(SYSCONFDIR)/warewulf/wwapid.conf || install -m 644 etc/wwapid.conf $(DESTDIR)$(SYSCONFDIR)/warewulf/
test -f $(DESTDIR)$(SYSCONFDIR)/warewulf/wwapird.conf || install -m 644 etc/wwapird.conf $(DESTDIR)$(SYSCONFDIR)/warewulf/
test -f $(DESTDIR)$(SYSCONFDIR)/warewulf/defaults.conf || ./print_defaults > $(DESTDIR)$(SYSCONFDIR)/warewulf/defaults.conf
cp -r etc/examples $(DESTDIR)$(WWCONFIGDIR)/
cp -r etc/ipxe $(DESTDIR)$(WWCONFIGDIR)/
cp -r overlays/* $(DESTDIR)$(WWOVERLAYDIR)/
@@ -237,6 +238,9 @@ config_defaults: vendor cmd/config_defaults/config_defaults.go
-X 'github.com/hpcng/warewulf/internal/pkg/node.ConfigFile=./etc/nodes.conf'"\
-mod vendor -tags "$(WW_GO_BUILD_TAGS)" -o ../../config_defaults
print_defaults: vendor cmd/print_defaults/print_defaults.go
cd cmd/print_defaults && go build -ldflags="-X 'github.com/hpcng/warewulf/internal/pkg/warewulfconf.ConfigFile=./etc/warewulf.conf'" -o ../../print_defaults
update_configuration: vendor cmd/update_configuration/update_configuration.go
cd cmd/update_configuration && go build -ldflags="-X 'github.com/hpcng/warewulf/internal/pkg/warewulfconf.ConfigFile=./etc/warewulf.conf'\
-X 'github.com/hpcng/warewulf/internal/pkg/node.ConfigFile=./etc/nodes.conf'"\
@@ -297,6 +301,7 @@ clean:
rm -rf $(TOOLS_DIR)
rm -f config_defaults
rm -f update_configuration
rm -f print_defaults
install: files install_wwclient

View File

@@ -0,0 +1,17 @@
package main
import (
"fmt"
"github.com/hpcng/warewulf/internal/pkg/node"
)
/*
Print the build in defaults for the nodes.
Called via Makefile so that there is single upstream
source of the defaults which is FallBackConf
*/
func main() {
fmt.Println(node.FallBackConf)
}

View File

@@ -10,6 +10,9 @@ User=root
Group=root
ExecStart=@BINDIR@/wwctl server start
ExecReload=/usr/bin/wwctl server reload
ExecStop=/usr/bin/wwctl server stop
PIDFile=/var/run/warewulfd.pid
Restart=always

View File

@@ -2,8 +2,10 @@ package list
import (
"fmt"
"time"
"github.com/hpcng/warewulf/internal/pkg/api/container"
"github.com/hpcng/warewulf/internal/pkg/util"
"github.com/hpcng/warewulf/internal/pkg/wwlog"
"github.com/spf13/cobra"
)
@@ -16,12 +18,17 @@ func CobraRunE(cmd *cobra.Command, args []string) (err error) {
return
}
fmt.Printf("%-25s %-6s %-6s\n", "CONTAINER NAME", "NODES", "KERNEL VERSION")
fmt.Printf("%-16s %-6s %-16s %-20s %-20s %-8s\n", "CONTAINER NAME", "NODES", "KERNEL VERSION", "CREATION TIME", "MODIFICATION TIME", "SIZE")
for i := 0; i < len(containerInfo); i++ {
fmt.Printf("%-25s %-6d %-6s\n",
createTime := time.Unix(int64(containerInfo[i].CreateDate), 0)
modTime := time.Unix(int64(containerInfo[i].ModDate), 0)
fmt.Printf("%-16s %-6d %-16s %-20s %-20s %-8s\n",
containerInfo[i].Name,
containerInfo[i].NodeCount,
containerInfo[i].KernelVersion)
containerInfo[i].KernelVersion,
createTime.Format(time.RFC822),
modTime.Format(time.RFC822),
util.ByteToString(int64(containerInfo[i].Size)))
}
return
}

View File

@@ -0,0 +1,115 @@
package edit
import (
"crypto/sha256"
"encoding/hex"
"fmt"
"io"
"io/ioutil"
"os"
"strings"
apinode "github.com/hpcng/warewulf/internal/pkg/api/node"
"github.com/hpcng/warewulf/internal/pkg/api/routes/wwapiv1"
apiutil "github.com/hpcng/warewulf/internal/pkg/api/util"
"github.com/hpcng/warewulf/internal/pkg/node"
"github.com/hpcng/warewulf/internal/pkg/util"
"github.com/hpcng/warewulf/internal/pkg/wwlog"
"github.com/spf13/cobra"
"gopkg.in/yaml.v2"
)
func CobraRunE(cmd *cobra.Command, args []string) error {
canWrite := apiutil.CanWriteConfig()
if !canWrite.CanWriteConfig {
wwlog.Error("Can't write to config exiting")
os.Exit(1)
}
editor := os.Getenv("EDITOR")
if editor == "" {
editor = "/bin/vi"
}
if len(args) == 0 {
args = append(args, ".*")
}
filterList := wwapiv1.NodeList{
Output: args,
}
nodeListMsg := apinode.FilteredNodes(&filterList)
nodeMap := make(map[string]*node.NodeConf)
// got proper yaml back
_ = yaml.Unmarshal([]byte(nodeListMsg.NodeConfMapYaml), nodeMap)
file, err := ioutil.TempFile("/tmp", "ww4NodeEdit*.yaml")
if err != nil {
wwlog.Error("Could not create temp file:%s \n", err)
}
defer os.Remove(file.Name())
nodeConf := node.NewConf()
yamlTemplate := nodeConf.UnmarshalConf([]string{"tagsdel", "default", "profiles"})
for {
_ = file.Truncate(0)
_, _ = file.Seek(0, 0)
if !NoHeader {
_, _ = file.WriteString("#nodename:\n# " + strings.Join(yamlTemplate, "\n# ") + "\n")
}
_, _ = file.WriteString(nodeListMsg.NodeConfMapYaml)
_, _ = file.Seek(0, 0)
hasher := sha256.New()
if _, err := io.Copy(hasher, file); err != nil {
wwlog.Error("Problems getting checksum of file %s\n", err)
}
sum1 := hex.EncodeToString(hasher.Sum(nil))
err = util.ExecInteractive(editor, file.Name())
if err != nil {
wwlog.Error("Editor process existed with non-zero\n")
os.Exit(1)
}
_, _ = file.Seek(0, 0)
hasher.Reset()
if _, err := io.Copy(hasher, file); err != nil {
wwlog.Error("Problems getting checksum of file %s\n", err)
}
sum2 := hex.EncodeToString(hasher.Sum(nil))
wwlog.Debug("Hashes are before %s and after %s\n", sum1, sum2)
if sum1 != sum2 {
wwlog.Debug("Nodes were modified")
modifiedNodeMap := make(map[string]*node.NodeConf)
_, _ = file.Seek(0, 0)
// ignore error as only may occurs under strange circumstances
buffer, _ := io.ReadAll(file)
err = yaml.Unmarshal(buffer, modifiedNodeMap)
if err == nil {
nodeList := make([]string, len(nodeMap))
i := 0
for key := range nodeMap {
nodeList[i] = key
i++
}
yes := apiutil.ConfirmationPrompt(fmt.Sprintf("Are you sure you want to modify %d nodes", len(modifiedNodeMap)))
if !yes {
break
}
err = apinode.NodeDelete(&wwapiv1.NodeDeleteParameter{NodeNames: nodeList, Force: true})
if err != nil {
wwlog.Verbose("Problem deleting nodes before modification %s")
}
buffer, _ = yaml.Marshal(modifiedNodeMap)
err = apinode.NodeAddFromYaml(&wwapiv1.NodeYaml{NodeConfMapYaml: string(buffer)})
if err != nil {
wwlog.Error("Got following problem when writing back yaml: %s", err)
os.Exit(1)
}
break
} else {
yes := apiutil.ConfirmationPrompt(fmt.Sprintf("Got following error on parsing: %s, Retry", err))
if !yes {
break
}
}
} else {
break
}
}
return nil
}

View File

@@ -0,0 +1,39 @@
package edit
import (
"github.com/hpcng/warewulf/internal/pkg/node"
"github.com/spf13/cobra"
)
var (
baseCmd = &cobra.Command{
DisableFlagsInUseLine: true,
Use: "edit [OPTIONS] NODENAME",
Short: "Edit node(s) with editor",
Long: "This command opens an editor for the given nodes.",
RunE: CobraRunE,
ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
if len(args) != 0 {
return nil, cobra.ShellCompDirectiveNoFileComp
}
nodeDB, _ := node.New()
nodes, _ := nodeDB.FindAllNodes()
var node_names []string
for _, node := range nodes {
node_names = append(node_names, node.Id.Get())
}
return node_names, cobra.ShellCompDirectiveNoFileComp
},
}
NoHeader bool
)
func init() {
baseCmd.PersistentFlags().BoolVar(&NoHeader, "noheader", false, "Do not print header")
}
// GetRootCommand returns the root cobra.Command for the application.
func GetCommand() *cobra.Command {
return baseCmd
}

View File

@@ -0,0 +1,26 @@
package export
import (
"fmt"
apinode "github.com/hpcng/warewulf/internal/pkg/api/node"
"github.com/hpcng/warewulf/internal/pkg/api/routes/wwapiv1"
"github.com/spf13/cobra"
)
func CobraRunE(cmd *cobra.Command, args []string) error {
if len(args) == 0 {
args = append(args, ".*")
}
filterList := wwapiv1.NodeList{
Output: args,
}
nodeListMsg := apinode.FilteredNodes(&filterList)
/*
nodeMap := make(map[string]*node.NodeConf)
// got proper yaml back
_ = yaml.Unmarshal([]byte(nodeListMsg.NodeConfMapYaml), nodeMap)
*/
fmt.Println(nodeListMsg.NodeConfMapYaml)
return nil
}

View File

@@ -0,0 +1,38 @@
package export
import (
"github.com/hpcng/warewulf/internal/pkg/node"
"github.com/spf13/cobra"
)
var (
baseCmd = &cobra.Command{
DisableFlagsInUseLine: true,
Use: "export NODENAME",
Short: "Export nodes as yaml to stdout",
Long: "This command exports the given nodes as yaml to stdout.",
RunE: CobraRunE,
ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
if len(args) != 0 {
return nil, cobra.ShellCompDirectiveNoFileComp
}
nodeDB, _ := node.New()
nodes, _ := nodeDB.FindAllNodes()
var node_names []string
for _, node := range nodes {
node_names = append(node_names, node.Id.Get())
}
return node_names, cobra.ShellCompDirectiveNoFileComp
},
}
NoHeader bool
)
func init() {
}
// GetRootCommand returns the root cobra.Command for the application.
func GetCommand() *cobra.Command {
return baseCmd
}

View File

@@ -0,0 +1,98 @@
package imprt
import (
"bytes"
"encoding/csv"
"fmt"
"io"
"os"
apinode "github.com/hpcng/warewulf/internal/pkg/api/node"
"github.com/hpcng/warewulf/internal/pkg/api/routes/wwapiv1"
apiutil "github.com/hpcng/warewulf/internal/pkg/api/util"
"github.com/hpcng/warewulf/internal/pkg/node"
"github.com/hpcng/warewulf/internal/pkg/wwlog"
"github.com/spf13/cobra"
"gopkg.in/yaml.v2"
)
func CobraRunE(cmd *cobra.Command, args []string) error {
file, err := os.Open(args[0])
if err != nil {
wwlog.Error("Could not open file:%s \n", err)
os.Exit(1)
}
defer file.Close()
importMap := make(map[string]*node.NodeConf)
buffer, err := io.ReadAll(file)
if err != nil {
wwlog.Error("Could not read:%s\n", err)
os.Exit(1)
}
if !ImportCVS {
err = yaml.Unmarshal(buffer, importMap)
if err == nil {
yes := apiutil.ConfirmationPrompt(fmt.Sprintf("Are you sure you want to modify %d nodes", len(importMap)))
if yes {
err = apinode.NodeAddFromYaml(&wwapiv1.NodeYaml{NodeConfMapYaml: string(buffer)})
if err != nil {
wwlog.Error("Got following problem when writing back yaml: %s", err)
os.Exit(1)
}
}
} else {
wwlog.Error("Could not parse import file")
}
} else {
// reading from buffer is a bit overshot
csvReader := csv.NewReader(bytes.NewReader(buffer))
records, err := csvReader.ReadAll()
if err != nil {
wwlog.Error("Could not parse %s: %s\n", args[0], err)
os.Exit(1)
}
if len(records) < 1 || len(records[0]) < 1 {
wwlog.Error("Did not find any data in %s\n", args[0])
os.Exit(1)
}
if !(records[0][0] == "node" || records[0][0] == "nodename") {
Usage()
os.Exit(1)
}
argsLen := len(records[0])
for i, line := range records[1:] {
if len(line) != argsLen {
wwlog.Error("Wrong number of fields in lube %u\n", i+1)
os.Exit(1)
}
for j := range line {
if j == 0 {
continue
}
if importMap[line[0]] == nil {
importMap[line[0]] = new(node.NodeConf)
}
ok := importMap[line[0]].SetLopt(records[0][j], line[j])
if !(ok) {
wwlog.Debug("Could not import %s\n", line[j])
}
}
}
yes := apiutil.ConfirmationPrompt(fmt.Sprintf("Are you sure you want to import %d nodes", len(importMap)))
if yes {
// create second buffer an marshall nodeMap to it
buffer, err = yaml.Marshal(importMap)
if err != nil {
wwlog.Error("Got following problem when creating yaml: %s", err)
}
err = apinode.NodeAddFromYaml(&wwapiv1.NodeYaml{NodeConfMapYaml: string(buffer)})
if err != nil {
wwlog.Error("Got following problem when writing back yaml: %s", err)
os.Exit(1)
}
}
}
return nil
}

View File

@@ -0,0 +1,35 @@
package imprt
import (
"fmt"
"github.com/spf13/cobra"
)
var (
baseCmd = &cobra.Command{
DisableFlagsInUseLine: true,
Use: "import [OPTIONS] NODENAME",
Short: "Import node(s) from yaml file",
Long: "This command imports all the nodes defined in a file. It will overwrite nodes with same name.",
RunE: CobraRunE,
Args: cobra.MinimumNArgs(1),
Aliases: []string{"import"},
}
ImportCVS bool
)
func init() {
baseCmd.PersistentFlags().BoolVarP(&ImportCVS, "cvs", "c", false, "Import CVS file")
}
// GetRootCommand returns the root cobra.Command for the application.
func GetCommand() *cobra.Command {
return baseCmd
}
func Usage() {
fmt.Println(`The csv file must be structured in following way:
node,option1,option2,net.netname1.netopt
node01,value1,value2,net.netname1,netvalue`)
}

View File

@@ -4,6 +4,9 @@ import (
"github.com/hpcng/warewulf/internal/app/wwctl/node/add"
"github.com/hpcng/warewulf/internal/app/wwctl/node/console"
"github.com/hpcng/warewulf/internal/app/wwctl/node/delete"
"github.com/hpcng/warewulf/internal/app/wwctl/node/edit"
"github.com/hpcng/warewulf/internal/app/wwctl/node/export"
"github.com/hpcng/warewulf/internal/app/wwctl/node/imprt"
"github.com/hpcng/warewulf/internal/app/wwctl/node/list"
"github.com/hpcng/warewulf/internal/app/wwctl/node/sensors"
"github.com/hpcng/warewulf/internal/app/wwctl/node/set"
@@ -30,6 +33,9 @@ func init() {
baseCmd.AddCommand(delete.GetCommand())
baseCmd.AddCommand(console.GetCommand())
baseCmd.AddCommand(nodestatus.GetCommand())
baseCmd.AddCommand(edit.GetCommand())
baseCmd.AddCommand(imprt.GetCommand())
baseCmd.AddCommand(export.GetCommand())
}
// GetRootCommand returns the root cobra.Command for the application.

View File

@@ -1,15 +1,30 @@
package delete
import "github.com/spf13/cobra"
import (
"github.com/hpcng/warewulf/internal/pkg/node"
"github.com/spf13/cobra"
)
var (
baseCmd = &cobra.Command{
DisableFlagsInUseLine: true,
Use: "delete [OPTIONS] PROFILE",
Short: "Delete a node profile",
Long: "This command deletes the node PROFILE. You may use a pattern for PROFILE.",
RunE: CobraRunE,
Args: cobra.MinimumNArgs(1),
Use: "delete [OPTIONS] PROFILE",
Short: "Delete a node profile",
Long: "This command deletes the node PROFILE. You may use a pattern for PROFILE.",
RunE: CobraRunE,
Args: cobra.MinimumNArgs(1),
ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
if len(args) != 0 {
return nil, cobra.ShellCompDirectiveNoFileComp
}
nodeDB, _ := node.New()
profiles, _ := nodeDB.FindAllProfiles()
var p_names []string
for _, profile := range profiles {
p_names = append(p_names, profile.Id.Get())
}
return p_names, cobra.ShellCompDirectiveNoFileComp
},
}
SetYes bool
)

View File

@@ -0,0 +1,115 @@
package edit
import (
"crypto/sha256"
"encoding/hex"
"fmt"
"io"
"io/ioutil"
"os"
"strings"
apiprofile "github.com/hpcng/warewulf/internal/pkg/api/profile"
"github.com/hpcng/warewulf/internal/pkg/api/routes/wwapiv1"
apiutil "github.com/hpcng/warewulf/internal/pkg/api/util"
"github.com/hpcng/warewulf/internal/pkg/node"
"github.com/hpcng/warewulf/internal/pkg/util"
"github.com/hpcng/warewulf/internal/pkg/wwlog"
"github.com/spf13/cobra"
"gopkg.in/yaml.v2"
)
func CobraRunE(cmd *cobra.Command, args []string) error {
canWrite := apiutil.CanWriteConfig()
if !canWrite.CanWriteConfig {
wwlog.Error("Can't write to config exiting")
os.Exit(1)
}
editor := os.Getenv("EDITOR")
if editor == "" {
editor = "/bin/vi"
}
if len(args) == 0 {
args = append(args, ".*")
}
filterList := wwapiv1.NodeList{
Output: args,
}
profileListMsg := apiprofile.FilteredProfiles(&filterList)
profileMap := make(map[string]*node.NodeConf)
// got proper yaml back
_ = yaml.Unmarshal([]byte(profileListMsg.NodeConfMapYaml), profileMap)
file, err := ioutil.TempFile("/tmp", "ww4ProfileEdit*.yaml")
if err != nil {
wwlog.Error("Could not create temp file:%s \n", err)
}
defer os.Remove(file.Name())
nodeConf := node.NewConf()
yamlTemplate := nodeConf.UnmarshalConf([]string{"tagsdel"})
for {
_ = file.Truncate(0)
_, _ = file.Seek(0, 0)
if !NoHeader {
_, _ = file.WriteString("#profilename:\n# " + strings.Join(yamlTemplate, "\n# ") + "\n")
}
_, _ = file.WriteString(profileListMsg.NodeConfMapYaml)
_, _ = file.Seek(0, 0)
hasher := sha256.New()
if _, err := io.Copy(hasher, file); err != nil {
wwlog.Error("Problems getting checksum of file %s\n", err)
}
sum1 := hex.EncodeToString(hasher.Sum(nil))
err = util.ExecInteractive(editor, file.Name())
if err != nil {
wwlog.Error("Editor process existed with non-zero\n")
os.Exit(1)
}
_, _ = file.Seek(0, 0)
hasher.Reset()
if _, err := io.Copy(hasher, file); err != nil {
wwlog.Error("Problems getting checksum of file %s\n", err)
}
sum2 := hex.EncodeToString(hasher.Sum(nil))
wwlog.Debug("Hashes are before %s and after %s\n", sum1, sum2)
if sum1 != sum2 {
wwlog.Debug("Nodes were modified")
modifiedProfileMap := make(map[string]*node.NodeConf)
_, _ = file.Seek(0, 0)
// ignore error as only may occurs under strange circumstances
buffer, _ := io.ReadAll(file)
err = yaml.Unmarshal(buffer, modifiedProfileMap)
if err == nil {
nodeList := make([]string, len(profileMap))
i := 0
for key := range profileMap {
nodeList[i] = key
i++
}
yes := apiutil.ConfirmationPrompt(fmt.Sprintf("Are you sure you want to modify %d nodes", len(modifiedProfileMap)))
if !yes {
break
}
err = apiprofile.ProfileDelete(&wwapiv1.NodeDeleteParameter{NodeNames: nodeList, Force: true})
if err != nil {
wwlog.Verbose("Problem deleting nodes before modification %s")
}
buffer, _ = yaml.Marshal(modifiedProfileMap)
err = apiprofile.ProfileAddFromYaml(&wwapiv1.NodeYaml{NodeConfMapYaml: string(buffer)})
if err != nil {
wwlog.Error("Got following problem when writing back yaml: %s", err)
os.Exit(1)
}
break
} else {
yes := apiutil.ConfirmationPrompt(fmt.Sprintf("Got following error on parsing: %s, Retry", err))
if !yes {
break
}
}
} else {
break
}
}
return nil
}

View File

@@ -0,0 +1,38 @@
package edit
import (
"github.com/hpcng/warewulf/internal/pkg/node"
"github.com/spf13/cobra"
)
var (
baseCmd = &cobra.Command{
DisableFlagsInUseLine: true,
Use: "edit [OPTIONS] NODENAME",
Short: "Edit node(s) with editor",
Long: "This command opens an editor for the given profiles.",
RunE: CobraRunE,
ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
if len(args) != 0 {
return nil, cobra.ShellCompDirectiveNoFileComp
}
nodeDB, _ := node.New()
profiles, _ := nodeDB.FindAllProfiles()
var p_names []string
for _, profile := range profiles {
p_names = append(p_names, profile.Id.Get())
}
return p_names, cobra.ShellCompDirectiveNoFileComp
},
}
NoHeader bool
)
func init() {
baseCmd.PersistentFlags().BoolVar(&NoHeader, "noheader", false, "Do not print header")
}
// GetRootCommand returns the root cobra.Command for the application.
func GetCommand() *cobra.Command {
return baseCmd
}

View File

@@ -3,6 +3,7 @@ package profile
import (
"github.com/hpcng/warewulf/internal/app/wwctl/profile/add"
"github.com/hpcng/warewulf/internal/app/wwctl/profile/delete"
"github.com/hpcng/warewulf/internal/app/wwctl/profile/edit"
"github.com/hpcng/warewulf/internal/app/wwctl/profile/list"
"github.com/hpcng/warewulf/internal/app/wwctl/profile/set"
"github.com/spf13/cobra"
@@ -11,9 +12,10 @@ import (
var (
baseCmd = &cobra.Command{
DisableFlagsInUseLine: true,
Use: "profile COMMAND [OPTIONS]",
Short: "Node configuration profile management",
Long: "Management of node profile settings",
Use: "profile COMMAND [OPTIONS]",
Short: "Node configuration profile management",
Long: "Management of node profile settings",
Aliases: []string{"nodes"},
}
)
@@ -22,6 +24,7 @@ func init() {
baseCmd.AddCommand(set.GetCommand())
baseCmd.AddCommand(add.GetCommand())
baseCmd.AddCommand(delete.GetCommand())
baseCmd.AddCommand(edit.GetCommand())
}
// GetRootCommand returns the root cobra.Command for the application.

View File

@@ -38,23 +38,27 @@ func CobraRunE(cmd *cobra.Command, args []string) error {
cmd.Usage()
os.Exit(1)
}
for _, node := range nodes {
if _, ok := node.NetDevs["default"]; !ok {
fmt.Fprintf(os.Stderr, "%s: Default network device doesn't exist\n", node.Id.Get())
var primaryNet string
for netName := range node.NetDevs {
if node.NetDevs[netName].Primary.GetB() {
primaryNet = netName
break
}
}
if primaryNet == "" {
wwlog.Error("%s: Primary network device doesn't exist\n", node.Id.Get())
continue
}
if node.NetDevs["default"].Ipaddr.Get() == "" {
fmt.Fprintf(os.Stderr, "%s: Default network IP address not configured\n", node.Id.Get())
if node.NetDevs[primaryNet].Ipaddr.Get() == "" {
wwlog.Error("%s: Primary network IP address not configured\n", node.Id.Get())
continue
}
nodename := node.Id.Print()
var command []string
command = append(command, node.NetDevs["default"].Ipaddr.Get())
command = append(command, node.NetDevs[primaryNet].Ipaddr.Get())
command = append(command, args[1:]...)
batchpool.Submit(func() {

View File

@@ -294,11 +294,38 @@ func ContainerList() (containerInfo []*wwapiv1.ContainerInfo, err error) {
wwlog.Debug("Finding kernel version for: %s", source)
kernelVersion := container.KernelVersion(source)
creationTime, err := os.Stat(container.SourceDir(source))
if err != nil {
wwlog.Error("%s\n", err)
}
modTime, err := os.Stat(container.ImageFile(source))
if err != nil {
wwlog.Error("%s\n", err)
}
size, err := util.DirSize(container.SourceDir(source))
if err != nil {
wwlog.Error("%s\n", err)
}
imgSize, err := os.Stat(container.ImageFile(source))
if err != nil {
wwlog.Error("%s\n", err)
}
size += imgSize.Size()
imgSize, err = os.Stat(container.ImageFile(source) + ".gz")
if err != nil {
wwlog.Error("%s\n", err)
}
size += imgSize.Size()
containerInfo = append(containerInfo, &wwapiv1.ContainerInfo{
Name: source,
NodeCount: uint32(nodemap[source]),
KernelVersion: kernelVersion,
CreateDate: uint64(creationTime.ModTime().Unix()),
ModDate: uint64(modTime.ModTime().Unix()),
Size: uint64(size),
})
}
return
}

View File

@@ -0,0 +1,70 @@
package apinode
import (
"os"
"github.com/hpcng/warewulf/internal/pkg/api/routes/wwapiv1"
"github.com/hpcng/warewulf/internal/pkg/node"
"github.com/hpcng/warewulf/internal/pkg/wwlog"
"github.com/pkg/errors"
"gopkg.in/yaml.v2"
)
/*
Returns the nodes as a yaml string
*/
func FindAllNodeConfs() *wwapiv1.NodeYaml {
nodeDB, err := node.New()
if err != nil {
wwlog.Error("Could not open nodeDB: %s\n", err)
os.Exit(1)
}
nodeMap := nodeDB.Nodes
// ignore err as nodeDB should always be correct
buffer, _ := yaml.Marshal(nodeMap)
retVal := wwapiv1.NodeYaml{
NodeConfMapYaml: string(buffer),
}
return &retVal
}
/*
Returns filtered list of nodes
*/
func FilteredNodes(nodeList *wwapiv1.NodeList) *wwapiv1.NodeYaml {
nodeDB, err := node.New()
if err != nil {
wwlog.Error("Could not open nodeDB: %s\n", err)
os.Exit(1)
}
nodeMap := nodeDB.Nodes
nodeMap = node.FilterMapByName(nodeMap, nodeList.Output)
buffer, _ := yaml.Marshal(nodeMap)
retVal := wwapiv1.NodeYaml{
NodeConfMapYaml: string(buffer),
}
return &retVal
}
/*
Add nodes from yaml
*/
func NodeAddFromYaml(nodeList *wwapiv1.NodeYaml) (err error) {
nodeDB, err := node.New()
if err != nil {
return errors.Wrap(err, "Could not open NodeDB: %s\n")
}
nodeMap := make(map[string]*node.NodeConf)
err = yaml.Unmarshal([]byte(nodeList.NodeConfMapYaml), nodeMap)
if err != nil {
return errors.Wrap(err, "Could not unmarshall Yaml: %s\n")
}
for nodeName, node := range nodeMap {
nodeDB.Nodes[nodeName] = node
}
err = nodeDB.Persist()
if err != nil {
return errors.Wrap(err, "failed to persist nodedb")
}
return nil
}

View File

@@ -102,7 +102,7 @@ func NodeDelete(ndp *wwapiv1.NodeDeleteParameter) (err error) {
wwlog.Error("%s", err)
} else {
//count++
fmt.Printf("Deleting node: %s\n", n.Id.Print())
wwlog.Verbose("Deleting node: %s\n", n.Id.Print())
}
}

View File

@@ -0,0 +1,94 @@
package apiprofile
import (
"fmt"
"os"
"github.com/hpcng/warewulf/internal/pkg/api/routes/wwapiv1"
"github.com/hpcng/warewulf/internal/pkg/node"
"github.com/hpcng/warewulf/internal/pkg/warewulfd"
"github.com/hpcng/warewulf/internal/pkg/wwlog"
"github.com/hpcng/warewulf/pkg/hostlist"
"github.com/pkg/errors"
)
// ProfileDelete adds profile deletion for management by Warewulf.
func ProfileDelete(ndp *wwapiv1.NodeDeleteParameter) (err error) {
var profileList []node.NodeInfo
profileList, err = ProfileDeleteParameterCheck(ndp, false)
if err != nil {
return
}
nodeDB, err := node.New()
if err != nil {
wwlog.Error("Failed to open node database: %s\n", err)
return
}
for _, p := range profileList {
err := nodeDB.DelProfile(p.Id.Get())
if err != nil {
wwlog.Error("%s\n", err)
} else {
//count++
wwlog.Verbose("Deleting node: %s\n", p.Id.Print())
}
}
err = nodeDB.Persist()
if err != nil {
return errors.Wrap(err, "failed to persist nodedb")
}
err = warewulfd.DaemonReload()
if err != nil {
return errors.Wrap(err, "failed to reload warewulf daemon")
}
return
}
// ProfileDeleteParameterCheck does error checking on ProfileDeleteParameter.
// Output to the console if console is true.
// Returns the profiles to delete.
func ProfileDeleteParameterCheck(ndp *wwapiv1.NodeDeleteParameter, console bool) (profileList []node.NodeInfo, err error) {
if ndp == nil {
err = fmt.Errorf("ProfileDeleteParameter is nil")
return
}
nodeDB, err := node.New()
if err != nil {
wwlog.Error("Failed to open node database: %s\n", err)
return
}
profiles, err := nodeDB.FindAllProfiles()
if err != nil {
wwlog.Error("Could not get node list: %s\n", err)
return
}
node_args := hostlist.Expand(ndp.NodeNames)
for _, r := range node_args {
var match bool
for _, p := range profiles {
if p.Id.Get() == r {
profileList = append(profileList, p)
match = true
}
}
if !match {
fmt.Fprintf(os.Stderr, "ERROR: No match for node: %s\n", r)
}
}
if len(profileList) == 0 {
fmt.Printf("No s found\n")
}
return
}

View File

@@ -0,0 +1,70 @@
package apiprofile
import (
"os"
"github.com/hpcng/warewulf/internal/pkg/api/routes/wwapiv1"
"github.com/hpcng/warewulf/internal/pkg/node"
"github.com/hpcng/warewulf/internal/pkg/wwlog"
"github.com/pkg/errors"
"gopkg.in/yaml.v2"
)
/*
Returns the nodes as a yaml string
*/
func FindAllProfileConfs() *wwapiv1.NodeYaml {
nodeDB, err := node.New()
if err != nil {
wwlog.Error("Could not open nodeDB: %s\n", err)
os.Exit(1)
}
profileMap := nodeDB.NodeProfiles
// ignore err as nodeDB should always be correct
buffer, _ := yaml.Marshal(profileMap)
retVal := wwapiv1.NodeYaml{
NodeConfMapYaml: string(buffer),
}
return &retVal
}
/*
Returns filtered list of nodes
*/
func FilteredProfiles(profileList *wwapiv1.NodeList) *wwapiv1.NodeYaml {
nodeDB, err := node.New()
if err != nil {
wwlog.Error("Could not open nodeDB: %s\n", err)
os.Exit(1)
}
profileMap := nodeDB.NodeProfiles
profileMap = node.FilterMapByName(profileMap, profileList.Output)
buffer, _ := yaml.Marshal(profileMap)
retVal := wwapiv1.NodeYaml{
NodeConfMapYaml: string(buffer),
}
return &retVal
}
/*
Add profiles from yaml
*/
func ProfileAddFromYaml(nodeList *wwapiv1.NodeYaml) (err error) {
nodeDB, err := node.New()
if err != nil {
return errors.Wrap(err, "Could not open NodeDB: %s\n")
}
profileMap := make(map[string]*node.NodeConf)
err = yaml.Unmarshal([]byte(nodeList.NodeConfMapYaml), profileMap)
if err != nil {
return errors.Wrap(err, "Could not unmarshall Yaml: %s\n")
}
for profileName, profile := range profileMap {
nodeDB.NodeProfiles[profileName] = profile
}
err = nodeDB.Persist()
if err != nil {
return errors.Wrap(err, "failed to persist nodedb")
}
return nil
}

View File

@@ -43,6 +43,9 @@ message ContainerInfo {
string name = 1;
uint32 nodeCount = 2;
string kernelVersion = 3;
uint64 createDate = 4; // creation date in unix time
uint64 modDate = 5; // date of last modification in unix time
uint64 size = 6; // size of chroot and images in bytes
}
// ContainerListResponse has all information that ContainerList provides.
@@ -91,7 +94,6 @@ message NetDev {
// NodeInfo contains details about a node managed by Warewulf/
message NodeInfo {
map<string, NodeField> Fields = 1;
map<string, NetDev> NetDevs = 23;
map<string, NodeField> Tags = 24;
map<string, NodeField> Keys = 25; // TODO: We may not need this. Tags may be it. Ask Greg.
@@ -126,6 +128,12 @@ message NodeAddParameter {
repeated string nodeNames = 10;
}
// NodeYaml is just the updated YAML config which will be added
// to nodes.conf (is resused for profile edit)
message NodeYaml {
string nodeConfMapYaml = 1;
}
// NodeDeleteParameter contains input for removing nodes from Warewulf
// management.
message NodeDeleteParameter {
@@ -167,6 +175,11 @@ message VersionResponse {
string warewulfVersion = 3;
}
// Check if config is writeable
message CanWriteConfig {
bool canWriteConfig = 1;
}
// WWApi defines the wwapid service web interface.
service WWApi {

View File

@@ -307,6 +307,9 @@ type ContainerInfo struct {
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
NodeCount uint32 `protobuf:"varint,2,opt,name=nodeCount,proto3" json:"nodeCount,omitempty"`
KernelVersion string `protobuf:"bytes,3,opt,name=kernelVersion,proto3" json:"kernelVersion,omitempty"`
CreateDate uint64 `protobuf:"varint,4,opt,name=createDate,proto3" json:"createDate,omitempty"` // creation date in unix time
ModDate uint64 `protobuf:"varint,5,opt,name=modDate,proto3" json:"modDate,omitempty"` // date of last modification in unix time
Size uint64 `protobuf:"varint,6,opt,name=size,proto3" json:"size,omitempty"` // size of chroot and images in bytes
}
func (x *ContainerInfo) Reset() {
@@ -362,6 +365,27 @@ func (x *ContainerInfo) GetKernelVersion() string {
return ""
}
func (x *ContainerInfo) GetCreateDate() uint64 {
if x != nil {
return x.CreateDate
}
return 0
}
func (x *ContainerInfo) GetModDate() uint64 {
if x != nil {
return x.ModDate
}
return 0
}
func (x *ContainerInfo) GetSize() uint64 {
if x != nil {
return x.Size
}
return 0
}
// ContainerListResponse has all information that ContainerList provides.
type ContainerListResponse struct {
state protoimpl.MessageState
@@ -1026,6 +1050,55 @@ func (x *NodeAddParameter) GetNodeNames() []string {
return nil
}
// NodeYaml is just the updated YAML config which will be added
// to nodes.conf (is resused for profile edit)
type NodeYaml struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
NodeConfMapYaml string `protobuf:"bytes,1,opt,name=nodeConfMapYaml,proto3" json:"nodeConfMapYaml,omitempty"`
}
func (x *NodeYaml) Reset() {
*x = NodeYaml{}
if protoimpl.UnsafeEnabled {
mi := &file_routes_proto_msgTypes[16]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *NodeYaml) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*NodeYaml) ProtoMessage() {}
func (x *NodeYaml) ProtoReflect() protoreflect.Message {
mi := &file_routes_proto_msgTypes[16]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use NodeYaml.ProtoReflect.Descriptor instead.
func (*NodeYaml) Descriptor() ([]byte, []int) {
return file_routes_proto_rawDescGZIP(), []int{16}
}
func (x *NodeYaml) GetNodeConfMapYaml() string {
if x != nil {
return x.NodeConfMapYaml
}
return ""
}
// NodeDeleteParameter contains input for removing nodes from Warewulf
// management.
type NodeDeleteParameter struct {
@@ -1040,7 +1113,7 @@ type NodeDeleteParameter struct {
func (x *NodeDeleteParameter) Reset() {
*x = NodeDeleteParameter{}
if protoimpl.UnsafeEnabled {
mi := &file_routes_proto_msgTypes[16]
mi := &file_routes_proto_msgTypes[17]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -1053,7 +1126,7 @@ func (x *NodeDeleteParameter) String() string {
func (*NodeDeleteParameter) ProtoMessage() {}
func (x *NodeDeleteParameter) ProtoReflect() protoreflect.Message {
mi := &file_routes_proto_msgTypes[16]
mi := &file_routes_proto_msgTypes[17]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -1066,7 +1139,7 @@ func (x *NodeDeleteParameter) ProtoReflect() protoreflect.Message {
// Deprecated: Use NodeDeleteParameter.ProtoReflect.Descriptor instead.
func (*NodeDeleteParameter) Descriptor() ([]byte, []int) {
return file_routes_proto_rawDescGZIP(), []int{16}
return file_routes_proto_rawDescGZIP(), []int{17}
}
func (x *NodeDeleteParameter) GetForce() bool {
@@ -1101,7 +1174,7 @@ type NodeSetParameter struct {
func (x *NodeSetParameter) Reset() {
*x = NodeSetParameter{}
if protoimpl.UnsafeEnabled {
mi := &file_routes_proto_msgTypes[17]
mi := &file_routes_proto_msgTypes[18]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -1114,7 +1187,7 @@ func (x *NodeSetParameter) String() string {
func (*NodeSetParameter) ProtoMessage() {}
func (x *NodeSetParameter) ProtoReflect() protoreflect.Message {
mi := &file_routes_proto_msgTypes[17]
mi := &file_routes_proto_msgTypes[18]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -1127,7 +1200,7 @@ func (x *NodeSetParameter) ProtoReflect() protoreflect.Message {
// Deprecated: Use NodeSetParameter.ProtoReflect.Descriptor instead.
func (*NodeSetParameter) Descriptor() ([]byte, []int) {
return file_routes_proto_rawDescGZIP(), []int{17}
return file_routes_proto_rawDescGZIP(), []int{18}
}
func (x *NodeSetParameter) GetNodeConfYaml() string {
@@ -1188,7 +1261,7 @@ type NodeStatus struct {
func (x *NodeStatus) Reset() {
*x = NodeStatus{}
if protoimpl.UnsafeEnabled {
mi := &file_routes_proto_msgTypes[18]
mi := &file_routes_proto_msgTypes[19]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -1201,7 +1274,7 @@ func (x *NodeStatus) String() string {
func (*NodeStatus) ProtoMessage() {}
func (x *NodeStatus) ProtoReflect() protoreflect.Message {
mi := &file_routes_proto_msgTypes[18]
mi := &file_routes_proto_msgTypes[19]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -1214,7 +1287,7 @@ func (x *NodeStatus) ProtoReflect() protoreflect.Message {
// Deprecated: Use NodeStatus.ProtoReflect.Descriptor instead.
func (*NodeStatus) Descriptor() ([]byte, []int) {
return file_routes_proto_rawDescGZIP(), []int{18}
return file_routes_proto_rawDescGZIP(), []int{19}
}
func (x *NodeStatus) GetNodeName() string {
@@ -1264,7 +1337,7 @@ type NodeStatusResponse struct {
func (x *NodeStatusResponse) Reset() {
*x = NodeStatusResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_routes_proto_msgTypes[19]
mi := &file_routes_proto_msgTypes[20]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -1277,7 +1350,7 @@ func (x *NodeStatusResponse) String() string {
func (*NodeStatusResponse) ProtoMessage() {}
func (x *NodeStatusResponse) ProtoReflect() protoreflect.Message {
mi := &file_routes_proto_msgTypes[19]
mi := &file_routes_proto_msgTypes[20]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -1290,7 +1363,7 @@ func (x *NodeStatusResponse) ProtoReflect() protoreflect.Message {
// Deprecated: Use NodeStatusResponse.ProtoReflect.Descriptor instead.
func (*NodeStatusResponse) Descriptor() ([]byte, []int) {
return file_routes_proto_rawDescGZIP(), []int{19}
return file_routes_proto_rawDescGZIP(), []int{20}
}
func (x *NodeStatusResponse) GetNodeStatus() []*NodeStatus {
@@ -1314,7 +1387,7 @@ type VersionResponse struct {
func (x *VersionResponse) Reset() {
*x = VersionResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_routes_proto_msgTypes[20]
mi := &file_routes_proto_msgTypes[21]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -1327,7 +1400,7 @@ func (x *VersionResponse) String() string {
func (*VersionResponse) ProtoMessage() {}
func (x *VersionResponse) ProtoReflect() protoreflect.Message {
mi := &file_routes_proto_msgTypes[20]
mi := &file_routes_proto_msgTypes[21]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -1340,7 +1413,7 @@ func (x *VersionResponse) ProtoReflect() protoreflect.Message {
// Deprecated: Use VersionResponse.ProtoReflect.Descriptor instead.
func (*VersionResponse) Descriptor() ([]byte, []int) {
return file_routes_proto_rawDescGZIP(), []int{20}
return file_routes_proto_rawDescGZIP(), []int{21}
}
func (x *VersionResponse) GetApiPrefix() string {
@@ -1364,6 +1437,54 @@ func (x *VersionResponse) GetWarewulfVersion() string {
return ""
}
// Check if config is writeable
type CanWriteConfig struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
CanWriteConfig bool `protobuf:"varint,1,opt,name=canWriteConfig,proto3" json:"canWriteConfig,omitempty"`
}
func (x *CanWriteConfig) Reset() {
*x = CanWriteConfig{}
if protoimpl.UnsafeEnabled {
mi := &file_routes_proto_msgTypes[22]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *CanWriteConfig) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*CanWriteConfig) ProtoMessage() {}
func (x *CanWriteConfig) ProtoReflect() protoreflect.Message {
mi := &file_routes_proto_msgTypes[22]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use CanWriteConfig.ProtoReflect.Descriptor instead.
func (*CanWriteConfig) Descriptor() ([]byte, []int) {
return file_routes_proto_rawDescGZIP(), []int{22}
}
func (x *CanWriteConfig) GetCanWriteConfig() bool {
if x != nil {
return x.CanWriteConfig
}
return false
}
var File_routes_proto protoreflect.FileDescriptor
var file_routes_proto_rawDesc = []byte{
@@ -1397,222 +1518,234 @@ var file_routes_proto_rawDesc = []byte{
0x66, 0x61, 0x75, 0x6c, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x64, 0x65, 0x66,
0x61, 0x75, 0x6c, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x79, 0x6e, 0x63, 0x55, 0x73, 0x65, 0x72,
0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x73, 0x79, 0x6e, 0x63, 0x55, 0x73, 0x65, 0x72,
0x22, 0x67, 0x0a, 0x0d, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x6e, 0x66,
0x6f, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x6f, 0x64, 0x65, 0x43, 0x6f, 0x75,
0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x6e, 0x6f, 0x64, 0x65, 0x43, 0x6f,
0x75, 0x6e, 0x74, 0x12, 0x24, 0x0a, 0x0d, 0x6b, 0x65, 0x72, 0x6e, 0x65, 0x6c, 0x56, 0x65, 0x72,
0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6b, 0x65, 0x72, 0x6e,
0x65, 0x6c, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x50, 0x0a, 0x15, 0x43, 0x6f, 0x6e,
0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
0x73, 0x65, 0x12, 0x37, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73,
0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x77, 0x77, 0x61, 0x70, 0x69, 0x2e, 0x76,
0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52,
0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x22, 0x3e, 0x0a, 0x16, 0x43,
0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x68, 0x6f, 0x77, 0x50, 0x61, 0x72, 0x61,
0x6d, 0x65, 0x74, 0x65, 0x72, 0x12, 0x24, 0x0a, 0x0d, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e,
0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x63, 0x6f,
0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x7f, 0x0a, 0x15, 0x43,
0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x68, 0x6f, 0x77, 0x52, 0x65, 0x73, 0x70,
0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01,
0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x52, 0x6f, 0x6f, 0x74,
0x66, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x52, 0x6f, 0x6f, 0x74, 0x66, 0x73,
0x12, 0x14, 0x0a, 0x05, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52,
0x05, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x12, 0x24, 0x0a, 0x0d, 0x4b, 0x65, 0x72, 0x6e, 0x65, 0x6c,
0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x4b,
0x65, 0x72, 0x6e, 0x65, 0x6c, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x42, 0x0a, 0x1a,
0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x79, 0x6e, 0x63, 0x55, 0x73, 0x65,
0x72, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x12, 0x24, 0x0a, 0x0d, 0x63, 0x6f,
0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28,
0x09, 0x52, 0x0d, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65,
0x22, 0x29, 0x0a, 0x09, 0x4e, 0x6f, 0x64, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x1c, 0x0a,
0x09, 0x6e, 0x6f, 0x64, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09,
0x52, 0x09, 0x6e, 0x6f, 0x64, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x22, 0x4f, 0x0a, 0x09, 0x4e,
0x6f, 0x64, 0x65, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72,
0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65,
0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x18,
0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x22, 0x88, 0x02, 0x0a,
0x06, 0x4e, 0x65, 0x74, 0x44, 0x65, 0x76, 0x12, 0x31, 0x0a, 0x05, 0x46, 0x69, 0x65, 0x6c, 0x64,
0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x77, 0x77, 0x61, 0x70, 0x69, 0x2e, 0x76,
0x31, 0x2e, 0x4e, 0x65, 0x74, 0x44, 0x65, 0x76, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x45, 0x6e,
0x74, 0x72, 0x79, 0x52, 0x05, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x12, 0x2e, 0x0a, 0x04, 0x54, 0x61,
0x67, 0x73, 0x18, 0x09, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x77, 0x77, 0x61, 0x70, 0x69,
0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x65, 0x74, 0x44, 0x65, 0x76, 0x2e, 0x54, 0x61, 0x67, 0x73, 0x45,
0x6e, 0x74, 0x72, 0x79, 0x52, 0x04, 0x54, 0x61, 0x67, 0x73, 0x1a, 0x4d, 0x0a, 0x0a, 0x46, 0x69,
0x65, 0x6c, 0x64, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18,
0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x29, 0x0a, 0x05, 0x76, 0x61,
0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x77, 0x77, 0x61, 0x70,
0x69, 0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x52, 0x05,
0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x4c, 0x0a, 0x09, 0x54, 0x61, 0x67,
0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20,
0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x29, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75,
0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x77, 0x77, 0x61, 0x70, 0x69, 0x2e,
0x76, 0x31, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x52, 0x05, 0x76, 0x61,
0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x9b, 0x04, 0x0a, 0x08, 0x4e, 0x6f, 0x64, 0x65,
0x49, 0x6e, 0x66, 0x6f, 0x12, 0x36, 0x0a, 0x06, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x01,
0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x77, 0x77, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e,
0x4e, 0x6f, 0x64, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x45,
0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x12, 0x39, 0x0a, 0x07,
0x4e, 0x65, 0x74, 0x44, 0x65, 0x76, 0x73, 0x18, 0x17, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e,
0x77, 0x77, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x49, 0x6e, 0x66,
0x6f, 0x2e, 0x4e, 0x65, 0x74, 0x44, 0x65, 0x76, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07,
0x4e, 0x65, 0x74, 0x44, 0x65, 0x76, 0x73, 0x12, 0x30, 0x0a, 0x04, 0x54, 0x61, 0x67, 0x73, 0x18,
0x18, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x77, 0x77, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31,
0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x2e, 0x54, 0x61, 0x67, 0x73, 0x45, 0x6e,
0x74, 0x72, 0x79, 0x52, 0x04, 0x54, 0x61, 0x67, 0x73, 0x12, 0x30, 0x0a, 0x04, 0x4b, 0x65, 0x79,
0x73, 0x18, 0x19, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x77, 0x77, 0x61, 0x70, 0x69, 0x2e,
0x76, 0x31, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x2e, 0x4b, 0x65, 0x79, 0x73,
0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x04, 0x4b, 0x65, 0x79, 0x73, 0x1a, 0x4e, 0x0a, 0x0b, 0x46,
0x69, 0x65, 0x6c, 0x64, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65,
0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x29, 0x0a, 0x05,
0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x77, 0x77,
0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x46, 0x69, 0x65, 0x6c, 0x64,
0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x4c, 0x0a, 0x0c, 0x4e,
0x65, 0x74, 0x44, 0x65, 0x76, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b,
0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x26, 0x0a,
0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x77,
0x77, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x65, 0x74, 0x44, 0x65, 0x76, 0x52, 0x05,
0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x4c, 0x0a, 0x09, 0x54, 0x61, 0x67,
0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20,
0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x29, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75,
0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x77, 0x77, 0x61, 0x70, 0x69, 0x2e,
0x76, 0x31, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x52, 0x05, 0x76, 0x61,
0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x4c, 0x0a, 0x09, 0x4b, 0x65, 0x79, 0x73, 0x45,
0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28,
0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x29, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18,
0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x77, 0x77, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31,
0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75,
0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x3c, 0x0a, 0x10, 0x4e, 0x6f, 0x64, 0x65, 0x4c, 0x69, 0x73,
0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x28, 0x0a, 0x05, 0x6e, 0x6f, 0x64,
0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x77, 0x77, 0x61, 0x70, 0x69,
0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x05, 0x6e, 0x6f,
0x64, 0x65, 0x73, 0x22, 0x99, 0x01, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x4c,
0x69, 0x73, 0x74, 0x12, 0x32, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28,
0x0e, 0x32, 0x1e, 0x2e, 0x77, 0x77, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74,
0x4e, 0x6f, 0x64, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x79, 0x70,
0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x4e, 0x6f, 0x64, 0x65, 0x73,
0x18, 0x08, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x22, 0x40, 0x0a,
0x08, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0a, 0x0a, 0x06, 0x53, 0x69, 0x6d,
0x70, 0x6c, 0x65, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x49, 0x70, 0x6d, 0x69, 0x10, 0x01, 0x12,
0x0b, 0x0a, 0x07, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x10, 0x02, 0x12, 0x08, 0x0a, 0x04,
0x4c, 0x6f, 0x6e, 0x67, 0x10, 0x03, 0x12, 0x07, 0x0a, 0x03, 0x41, 0x6c, 0x6c, 0x10, 0x04, 0x22,
0x22, 0x0a, 0x08, 0x4e, 0x6f, 0x64, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x4f,
0x75, 0x74, 0x70, 0x75, 0x74, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x4f, 0x75, 0x74,
0x70, 0x75, 0x74, 0x22, 0x54, 0x0a, 0x10, 0x4e, 0x6f, 0x64, 0x65, 0x41, 0x64, 0x64, 0x50, 0x61,
0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x12, 0x22, 0x0a, 0x0c, 0x6e, 0x6f, 0x64, 0x65, 0x43,
0x6f, 0x6e, 0x66, 0x59, 0x61, 0x6d, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x6e,
0x6f, 0x64, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x59, 0x61, 0x6d, 0x6c, 0x12, 0x1c, 0x0a, 0x09, 0x6e,
0x6f, 0x64, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09,
0x6e, 0x6f, 0x64, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x22, 0x49, 0x0a, 0x13, 0x4e, 0x6f, 0x64,
0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72,
0x12, 0x14, 0x0a, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52,
0x22, 0xb5, 0x01, 0x0a, 0x0d, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x6e,
0x66, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x6f, 0x64, 0x65, 0x43, 0x6f,
0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x6e, 0x6f, 0x64, 0x65, 0x43,
0x6f, 0x75, 0x6e, 0x74, 0x12, 0x24, 0x0a, 0x0d, 0x6b, 0x65, 0x72, 0x6e, 0x65, 0x6c, 0x56, 0x65,
0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6b, 0x65, 0x72,
0x6e, 0x65, 0x6c, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x72,
0x65, 0x61, 0x74, 0x65, 0x44, 0x61, 0x74, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0a,
0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, 0x61, 0x74, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x6f,
0x64, 0x44, 0x61, 0x74, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x6d, 0x6f, 0x64,
0x44, 0x61, 0x74, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x06, 0x20, 0x01,
0x28, 0x04, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x22, 0x50, 0x0a, 0x15, 0x43, 0x6f, 0x6e, 0x74,
0x61, 0x69, 0x6e, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
0x65, 0x12, 0x37, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x18,
0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x77, 0x77, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31,
0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0a,
0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x22, 0x3e, 0x0a, 0x16, 0x43, 0x6f,
0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x68, 0x6f, 0x77, 0x50, 0x61, 0x72, 0x61, 0x6d,
0x65, 0x74, 0x65, 0x72, 0x12, 0x24, 0x0a, 0x0d, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65,
0x72, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x63, 0x6f, 0x6e,
0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x7f, 0x0a, 0x15, 0x43, 0x6f,
0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x68, 0x6f, 0x77, 0x52, 0x65, 0x73, 0x70, 0x6f,
0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28,
0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x52, 0x6f, 0x6f, 0x74, 0x66,
0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x52, 0x6f, 0x6f, 0x74, 0x66, 0x73, 0x12,
0x14, 0x0a, 0x05, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05,
0x4e, 0x6f, 0x64, 0x65, 0x73, 0x12, 0x24, 0x0a, 0x0d, 0x4b, 0x65, 0x72, 0x6e, 0x65, 0x6c, 0x56,
0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x4b, 0x65,
0x72, 0x6e, 0x65, 0x6c, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x42, 0x0a, 0x1a, 0x43,
0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x79, 0x6e, 0x63, 0x55, 0x73, 0x65, 0x72,
0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x12, 0x24, 0x0a, 0x0d, 0x63, 0x6f, 0x6e,
0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
0x52, 0x0d, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x22,
0x29, 0x0a, 0x09, 0x4e, 0x6f, 0x64, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x1c, 0x0a, 0x09,
0x6e, 0x6f, 0x64, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52,
0x09, 0x6e, 0x6f, 0x64, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x22, 0x4f, 0x0a, 0x09, 0x4e, 0x6f,
0x64, 0x65, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63,
0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12,
0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05,
0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x18, 0x03,
0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x22, 0x88, 0x02, 0x0a, 0x06,
0x4e, 0x65, 0x74, 0x44, 0x65, 0x76, 0x12, 0x31, 0x0a, 0x05, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x18,
0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x77, 0x77, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31,
0x2e, 0x4e, 0x65, 0x74, 0x44, 0x65, 0x76, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x45, 0x6e, 0x74,
0x72, 0x79, 0x52, 0x05, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x12, 0x2e, 0x0a, 0x04, 0x54, 0x61, 0x67,
0x73, 0x18, 0x09, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x77, 0x77, 0x61, 0x70, 0x69, 0x2e,
0x76, 0x31, 0x2e, 0x4e, 0x65, 0x74, 0x44, 0x65, 0x76, 0x2e, 0x54, 0x61, 0x67, 0x73, 0x45, 0x6e,
0x74, 0x72, 0x79, 0x52, 0x04, 0x54, 0x61, 0x67, 0x73, 0x1a, 0x4d, 0x0a, 0x0a, 0x46, 0x69, 0x65,
0x6c, 0x64, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01,
0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x29, 0x0a, 0x05, 0x76, 0x61, 0x6c,
0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x77, 0x77, 0x61, 0x70, 0x69,
0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x52, 0x05, 0x76,
0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x4c, 0x0a, 0x09, 0x54, 0x61, 0x67, 0x73,
0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01,
0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x29, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65,
0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x77, 0x77, 0x61, 0x70, 0x69, 0x2e, 0x76,
0x31, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x52, 0x05, 0x76, 0x61, 0x6c,
0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x9b, 0x04, 0x0a, 0x08, 0x4e, 0x6f, 0x64, 0x65, 0x49,
0x6e, 0x66, 0x6f, 0x12, 0x36, 0x0a, 0x06, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x01, 0x20,
0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x77, 0x77, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x4e,
0x6f, 0x64, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x45, 0x6e,
0x74, 0x72, 0x79, 0x52, 0x06, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x12, 0x39, 0x0a, 0x07, 0x4e,
0x65, 0x74, 0x44, 0x65, 0x76, 0x73, 0x18, 0x17, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x77,
0x77, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x49, 0x6e, 0x66, 0x6f,
0x2e, 0x4e, 0x65, 0x74, 0x44, 0x65, 0x76, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07, 0x4e,
0x65, 0x74, 0x44, 0x65, 0x76, 0x73, 0x12, 0x30, 0x0a, 0x04, 0x54, 0x61, 0x67, 0x73, 0x18, 0x18,
0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x77, 0x77, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e,
0x4e, 0x6f, 0x64, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x2e, 0x54, 0x61, 0x67, 0x73, 0x45, 0x6e, 0x74,
0x72, 0x79, 0x52, 0x04, 0x54, 0x61, 0x67, 0x73, 0x12, 0x30, 0x0a, 0x04, 0x4b, 0x65, 0x79, 0x73,
0x18, 0x19, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x77, 0x77, 0x61, 0x70, 0x69, 0x2e, 0x76,
0x31, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x2e, 0x4b, 0x65, 0x79, 0x73, 0x45,
0x6e, 0x74, 0x72, 0x79, 0x52, 0x04, 0x4b, 0x65, 0x79, 0x73, 0x1a, 0x4e, 0x0a, 0x0b, 0x46, 0x69,
0x65, 0x6c, 0x64, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79,
0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x29, 0x0a, 0x05, 0x76,
0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x77, 0x77, 0x61,
0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x52,
0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x4c, 0x0a, 0x0c, 0x4e, 0x65,
0x74, 0x44, 0x65, 0x76, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65,
0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x26, 0x0a, 0x05,
0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x77, 0x77,
0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x65, 0x74, 0x44, 0x65, 0x76, 0x52, 0x05, 0x76,
0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x4c, 0x0a, 0x09, 0x54, 0x61, 0x67, 0x73,
0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01,
0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x29, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65,
0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x77, 0x77, 0x61, 0x70, 0x69, 0x2e, 0x76,
0x31, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x52, 0x05, 0x76, 0x61, 0x6c,
0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x4c, 0x0a, 0x09, 0x4b, 0x65, 0x79, 0x73, 0x45, 0x6e,
0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x29, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02,
0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x77, 0x77, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e,
0x4e, 0x6f, 0x64, 0x65, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65,
0x3a, 0x02, 0x38, 0x01, 0x22, 0x3c, 0x0a, 0x10, 0x4e, 0x6f, 0x64, 0x65, 0x4c, 0x69, 0x73, 0x74,
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x28, 0x0a, 0x05, 0x6e, 0x6f, 0x64, 0x65,
0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x77, 0x77, 0x61, 0x70, 0x69, 0x2e,
0x76, 0x31, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x05, 0x6e, 0x6f, 0x64,
0x65, 0x73, 0x22, 0x99, 0x01, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x4c, 0x69,
0x73, 0x74, 0x12, 0x32, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0e,
0x32, 0x1e, 0x2e, 0x77, 0x77, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4e,
0x6f, 0x64, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65,
0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x18,
0x08, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x22, 0x40, 0x0a, 0x08,
0x4c, 0x69, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0a, 0x0a, 0x06, 0x53, 0x69, 0x6d, 0x70,
0x6c, 0x65, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x49, 0x70, 0x6d, 0x69, 0x10, 0x01, 0x12, 0x0b,
0x0a, 0x07, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x10, 0x02, 0x12, 0x08, 0x0a, 0x04, 0x4c,
0x6f, 0x6e, 0x67, 0x10, 0x03, 0x12, 0x07, 0x0a, 0x03, 0x41, 0x6c, 0x6c, 0x10, 0x04, 0x22, 0x22,
0x0a, 0x08, 0x4e, 0x6f, 0x64, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x4f, 0x75,
0x74, 0x70, 0x75, 0x74, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x4f, 0x75, 0x74, 0x70,
0x75, 0x74, 0x22, 0x54, 0x0a, 0x10, 0x4e, 0x6f, 0x64, 0x65, 0x41, 0x64, 0x64, 0x50, 0x61, 0x72,
0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x12, 0x22, 0x0a, 0x0c, 0x6e, 0x6f, 0x64, 0x65, 0x43, 0x6f,
0x6e, 0x66, 0x59, 0x61, 0x6d, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x6e, 0x6f,
0x64, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x59, 0x61, 0x6d, 0x6c, 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x6f,
0x64, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x6e,
0x6f, 0x64, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x22, 0x34, 0x0a, 0x08, 0x4e, 0x6f, 0x64, 0x65,
0x59, 0x61, 0x6d, 0x6c, 0x12, 0x28, 0x0a, 0x0f, 0x6e, 0x6f, 0x64, 0x65, 0x43, 0x6f, 0x6e, 0x66,
0x4d, 0x61, 0x70, 0x59, 0x61, 0x6d, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x6e,
0x6f, 0x64, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x4d, 0x61, 0x70, 0x59, 0x61, 0x6d, 0x6c, 0x22, 0x49,
0x0a, 0x13, 0x4e, 0x6f, 0x64, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x61, 0x72, 0x61,
0x6d, 0x65, 0x74, 0x65, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x18, 0x01,
0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x6e,
0x6f, 0x64, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09,
0x6e, 0x6f, 0x64, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x22, 0xc8, 0x01, 0x0a, 0x10, 0x4e, 0x6f,
0x64, 0x65, 0x53, 0x65, 0x74, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x12, 0x22,
0x0a, 0x0c, 0x6e, 0x6f, 0x64, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x59, 0x61, 0x6d, 0x6c, 0x18, 0x01,
0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x6e, 0x6f, 0x64, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x59, 0x61,
0x6d, 0x6c, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x18,
0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72,
0x12, 0x22, 0x0a, 0x0c, 0x6e, 0x65, 0x74, 0x64, 0x65, 0x76, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65,
0x18, 0x0e, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x6e, 0x65, 0x74, 0x64, 0x65, 0x76, 0x44, 0x65,
0x6c, 0x65, 0x74, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x61, 0x6c, 0x6c, 0x4e, 0x6f, 0x64, 0x65, 0x73,
0x18, 0x1b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x61, 0x6c, 0x6c, 0x4e, 0x6f, 0x64, 0x65, 0x73,
0x12, 0x14, 0x0a, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x18, 0x1f, 0x20, 0x01, 0x28, 0x08, 0x52,
0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x6f, 0x64, 0x65, 0x4e, 0x61,
0x6d, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x6f, 0x64, 0x65, 0x4e,
0x61, 0x6d, 0x65, 0x73, 0x22, 0xc8, 0x01, 0x0a, 0x10, 0x4e, 0x6f, 0x64, 0x65, 0x53, 0x65, 0x74,
0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x12, 0x22, 0x0a, 0x0c, 0x6e, 0x6f, 0x64,
0x65, 0x43, 0x6f, 0x6e, 0x66, 0x59, 0x61, 0x6d, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
0x0c, 0x6e, 0x6f, 0x64, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x59, 0x61, 0x6d, 0x6c, 0x12, 0x1c, 0x0a,
0x09, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
0x52, 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x22, 0x0a, 0x0c, 0x6e,
0x65, 0x74, 0x64, 0x65, 0x76, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x18, 0x0e, 0x20, 0x01, 0x28,
0x09, 0x52, 0x0c, 0x6e, 0x65, 0x74, 0x64, 0x65, 0x76, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12,
0x1a, 0x0a, 0x08, 0x61, 0x6c, 0x6c, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x18, 0x1b, 0x20, 0x01, 0x28,
0x08, 0x52, 0x08, 0x61, 0x6c, 0x6c, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x66,
0x6f, 0x72, 0x63, 0x65, 0x18, 0x1f, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x66, 0x6f, 0x72, 0x63,
0x65, 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x6f, 0x64, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x27,
0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x6f, 0x64, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x22,
0x86, 0x01, 0x0a, 0x0a, 0x4e, 0x6f, 0x64, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1a,
0x0a, 0x08, 0x6e, 0x6f, 0x64, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
0x52, 0x08, 0x6e, 0x6f, 0x64, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74,
0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x61, 0x67, 0x65,
0x12, 0x12, 0x0a, 0x04, 0x73, 0x65, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04,
0x73, 0x65, 0x6e, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x69, 0x70, 0x61, 0x64, 0x64, 0x72, 0x18, 0x04,
0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x69, 0x70, 0x61, 0x64, 0x64, 0x72, 0x12, 0x1a, 0x0a, 0x08,
0x6c, 0x61, 0x73, 0x74, 0x73, 0x65, 0x65, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08,
0x6c, 0x61, 0x73, 0x74, 0x73, 0x65, 0x65, 0x6e, 0x22, 0x4a, 0x0a, 0x12, 0x4e, 0x6f, 0x64, 0x65,
0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x34,
0x0a, 0x0a, 0x6e, 0x6f, 0x64, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x03,
0x28, 0x0b, 0x32, 0x14, 0x2e, 0x77, 0x77, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x6f,
0x64, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x0a, 0x6e, 0x6f, 0x64, 0x65, 0x53, 0x74,
0x61, 0x74, 0x75, 0x73, 0x22, 0x79, 0x0a, 0x0f, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52,
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x61, 0x70, 0x69, 0x50, 0x72,
0x65, 0x66, 0x69, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, 0x70, 0x69, 0x50,
0x72, 0x65, 0x66, 0x69, 0x78, 0x12, 0x1e, 0x0a, 0x0a, 0x61, 0x70, 0x69, 0x56, 0x65, 0x72, 0x73,
0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x61, 0x70, 0x69, 0x56, 0x65,
0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x28, 0x0a, 0x0f, 0x77, 0x61, 0x72, 0x65, 0x77, 0x75, 0x6c,
0x66, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f,
0x77, 0x61, 0x72, 0x65, 0x77, 0x75, 0x6c, 0x66, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x32,
0xa6, 0x08, 0x0a, 0x05, 0x57, 0x57, 0x41, 0x70, 0x69, 0x12, 0x73, 0x0a, 0x0e, 0x43, 0x6f, 0x6e,
0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x12, 0x21, 0x2e, 0x77, 0x77,
0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72,
0x42, 0x75, 0x69, 0x6c, 0x64, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x1a, 0x1f,
0x6d, 0x65, 0x73, 0x18, 0x27, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x6f, 0x64, 0x65, 0x4e,
0x61, 0x6d, 0x65, 0x73, 0x22, 0x86, 0x01, 0x0a, 0x0a, 0x4e, 0x6f, 0x64, 0x65, 0x53, 0x74, 0x61,
0x74, 0x75, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x6e, 0x6f, 0x64, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x18,
0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6e, 0x6f, 0x64, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12,
0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05,
0x73, 0x74, 0x61, 0x67, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x65, 0x6e, 0x74, 0x18, 0x03, 0x20,
0x01, 0x28, 0x09, 0x52, 0x04, 0x73, 0x65, 0x6e, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x69, 0x70, 0x61,
0x64, 0x64, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x69, 0x70, 0x61, 0x64, 0x64,
0x72, 0x12, 0x1a, 0x0a, 0x08, 0x6c, 0x61, 0x73, 0x74, 0x73, 0x65, 0x65, 0x6e, 0x18, 0x05, 0x20,
0x01, 0x28, 0x03, 0x52, 0x08, 0x6c, 0x61, 0x73, 0x74, 0x73, 0x65, 0x65, 0x6e, 0x22, 0x4a, 0x0a,
0x12, 0x4e, 0x6f, 0x64, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f,
0x6e, 0x73, 0x65, 0x12, 0x34, 0x0a, 0x0a, 0x6e, 0x6f, 0x64, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75,
0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x77, 0x77, 0x61, 0x70, 0x69, 0x2e,
0x76, 0x31, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x0a, 0x6e,
0x6f, 0x64, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x79, 0x0a, 0x0f, 0x56, 0x65, 0x72,
0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1c, 0x0a, 0x09,
0x61, 0x70, 0x69, 0x50, 0x72, 0x65, 0x66, 0x69, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
0x09, 0x61, 0x70, 0x69, 0x50, 0x72, 0x65, 0x66, 0x69, 0x78, 0x12, 0x1e, 0x0a, 0x0a, 0x61, 0x70,
0x69, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a,
0x61, 0x70, 0x69, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x28, 0x0a, 0x0f, 0x77, 0x61,
0x72, 0x65, 0x77, 0x75, 0x6c, 0x66, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20,
0x01, 0x28, 0x09, 0x52, 0x0f, 0x77, 0x61, 0x72, 0x65, 0x77, 0x75, 0x6c, 0x66, 0x56, 0x65, 0x72,
0x73, 0x69, 0x6f, 0x6e, 0x22, 0x38, 0x0a, 0x0e, 0x43, 0x61, 0x6e, 0x57, 0x72, 0x69, 0x74, 0x65,
0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x26, 0x0a, 0x0e, 0x63, 0x61, 0x6e, 0x57, 0x72, 0x69,
0x74, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e,
0x63, 0x61, 0x6e, 0x57, 0x72, 0x69, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x32, 0xa6,
0x08, 0x0a, 0x05, 0x57, 0x57, 0x41, 0x70, 0x69, 0x12, 0x73, 0x0a, 0x0e, 0x43, 0x6f, 0x6e, 0x74,
0x61, 0x69, 0x6e, 0x65, 0x72, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x12, 0x21, 0x2e, 0x77, 0x77, 0x61,
0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x42,
0x75, 0x69, 0x6c, 0x64, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x1a, 0x1f, 0x2e,
0x77, 0x77, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e,
0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1d,
0x82, 0xd3, 0xe4, 0x93, 0x02, 0x17, 0x22, 0x12, 0x2f, 0x76, 0x31, 0x2f, 0x63, 0x6f, 0x6e, 0x74,
0x61, 0x69, 0x6e, 0x65, 0x72, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x3a, 0x01, 0x2a, 0x12, 0x64, 0x0a,
0x0f, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65,
0x12, 0x22, 0x2e, 0x77, 0x77, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74,
0x61, 0x69, 0x6e, 0x65, 0x72, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d,
0x65, 0x74, 0x65, 0x72, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72,
0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x15, 0x82, 0xd3,
0xe4, 0x93, 0x02, 0x0f, 0x2a, 0x0d, 0x2f, 0x76, 0x31, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69,
0x6e, 0x65, 0x72, 0x12, 0x70, 0x0a, 0x0f, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72,
0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x22, 0x2e, 0x77, 0x77, 0x61, 0x70, 0x69, 0x2e, 0x76,
0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x6d, 0x70, 0x6f, 0x72,
0x74, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x1a, 0x1f, 0x2e, 0x77, 0x77, 0x61,
0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x4c,
0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x18, 0x82, 0xd3, 0xe4,
0x93, 0x02, 0x12, 0x22, 0x0d, 0x2f, 0x76, 0x31, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e,
0x65, 0x72, 0x3a, 0x01, 0x2a, 0x12, 0x5f, 0x0a, 0x0d, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e,
0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e,
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1f,
0x2e, 0x77, 0x77, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69,
0x6e, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
0x1d, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x17, 0x22, 0x12, 0x2f, 0x76, 0x31, 0x2f, 0x63, 0x6f, 0x6e,
0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x3a, 0x01, 0x2a, 0x12, 0x64,
0x0a, 0x0f, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x44, 0x65, 0x6c, 0x65, 0x74,
0x65, 0x12, 0x22, 0x2e, 0x77, 0x77, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e,
0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x61, 0x72, 0x61,
0x6d, 0x65, 0x74, 0x65, 0x72, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70,
0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x15, 0x82,
0xd3, 0xe4, 0x93, 0x02, 0x0f, 0x2a, 0x0d, 0x2f, 0x76, 0x31, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x61,
0x69, 0x6e, 0x65, 0x72, 0x12, 0x70, 0x0a, 0x0f, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65,
0x72, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x22, 0x2e, 0x77, 0x77, 0x61, 0x70, 0x69, 0x2e,
0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x6d, 0x70, 0x6f,
0x72, 0x74, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x1a, 0x1f, 0x2e, 0x77, 0x77,
0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72,
0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x18, 0x82, 0xd3,
0xe4, 0x93, 0x02, 0x12, 0x22, 0x0d, 0x2f, 0x76, 0x31, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69,
0x6e, 0x65, 0x72, 0x3a, 0x01, 0x2a, 0x12, 0x5f, 0x0a, 0x0d, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69,
0x6e, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a,
0x1f, 0x2e, 0x77, 0x77, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61,
0x69, 0x6e, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
0x22, 0x15, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0f, 0x12, 0x0d, 0x2f, 0x76, 0x31, 0x2f, 0x63, 0x6f,
0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x6d, 0x0a, 0x0d, 0x43, 0x6f, 0x6e, 0x74, 0x61,
0x69, 0x6e, 0x65, 0x72, 0x53, 0x68, 0x6f, 0x77, 0x12, 0x20, 0x2e, 0x77, 0x77, 0x61, 0x70, 0x69,
0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x68, 0x6f,
0x77, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x1a, 0x1f, 0x2e, 0x77, 0x77, 0x61,
0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53,
0x68, 0x6f, 0x77, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x19, 0x82, 0xd3, 0xe4,
0x93, 0x02, 0x13, 0x12, 0x11, 0x2f, 0x76, 0x31, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e,
0x65, 0x72, 0x73, 0x68, 0x6f, 0x77, 0x12, 0x56, 0x0a, 0x07, 0x4e, 0x6f, 0x64, 0x65, 0x41, 0x64,
0x64, 0x12, 0x1a, 0x2e, 0x77, 0x77, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x6f, 0x64,
0x65, 0x41, 0x64, 0x64, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x1a, 0x1a, 0x2e,
0x77, 0x77, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x4c, 0x69, 0x73,
0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x13, 0x82, 0xd3, 0xe4, 0x93, 0x02,
0x0d, 0x22, 0x08, 0x2f, 0x76, 0x31, 0x2f, 0x6e, 0x6f, 0x64, 0x65, 0x3a, 0x01, 0x2a, 0x12, 0x55,
0x0a, 0x0a, 0x4e, 0x6f, 0x64, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x1d, 0x2e, 0x77,
0x77, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x44, 0x65, 0x6c, 0x65,
0x74, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x1a, 0x16, 0x2e, 0x67, 0x6f,
0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d,
0x70, 0x74, 0x79, 0x22, 0x10, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0a, 0x2a, 0x08, 0x2f, 0x76, 0x31,
0x2f, 0x6e, 0x6f, 0x64, 0x65, 0x12, 0x4d, 0x0a, 0x08, 0x4e, 0x6f, 0x64, 0x65, 0x4c, 0x69, 0x73,
0x74, 0x12, 0x13, 0x2e, 0x77, 0x77, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x6f, 0x64,
0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x1a, 0x1a, 0x2e, 0x77, 0x77, 0x61, 0x70, 0x69, 0x2e, 0x76,
0x31, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
0x73, 0x65, 0x22, 0x10, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0a, 0x12, 0x08, 0x2f, 0x76, 0x31, 0x2f,
0x6e, 0x6f, 0x64, 0x65, 0x12, 0x59, 0x0a, 0x07, 0x4e, 0x6f, 0x64, 0x65, 0x53, 0x65, 0x74, 0x12,
0x1a, 0x2e, 0x77, 0x77, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x53,
0x65, 0x74, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x1a, 0x1a, 0x2e, 0x77, 0x77,
0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x52,
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x16, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x10, 0x22,
0x0b, 0x2f, 0x76, 0x31, 0x2f, 0x6e, 0x6f, 0x64, 0x65, 0x73, 0x65, 0x74, 0x3a, 0x01, 0x2a, 0x12,
0x57, 0x0a, 0x0a, 0x4e, 0x6f, 0x64, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x13, 0x2e,
0x77, 0x77, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x4e, 0x61, 0x6d,
0x65, 0x73, 0x1a, 0x1c, 0x2e, 0x77, 0x77, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x6f,
0x64, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
0x22, 0x16, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x10, 0x12, 0x0e, 0x2f, 0x76, 0x31, 0x2f, 0x6e, 0x6f,
0x64, 0x65, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x4e, 0x0a, 0x07, 0x56, 0x65, 0x72, 0x73,
0x69, 0x6f, 0x6e, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x19, 0x2e, 0x77, 0x77,
0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65,
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x10, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0a, 0x12, 0x08,
0x2f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x42, 0x29, 0x5a, 0x27, 0x69, 0x6e, 0x74, 0x65,
0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x72, 0x6f, 0x75,
0x74, 0x65, 0x73, 0x2f, 0x77, 0x77, 0x61, 0x70, 0x69, 0x76, 0x31, 0x3b, 0x77, 0x77, 0x61, 0x70,
0x69, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
0x15, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0f, 0x12, 0x0d, 0x2f, 0x76, 0x31, 0x2f, 0x63, 0x6f, 0x6e,
0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x6d, 0x0a, 0x0d, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69,
0x6e, 0x65, 0x72, 0x53, 0x68, 0x6f, 0x77, 0x12, 0x20, 0x2e, 0x77, 0x77, 0x61, 0x70, 0x69, 0x2e,
0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x68, 0x6f, 0x77,
0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x1a, 0x1f, 0x2e, 0x77, 0x77, 0x61, 0x70,
0x69, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x68,
0x6f, 0x77, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x19, 0x82, 0xd3, 0xe4, 0x93,
0x02, 0x13, 0x12, 0x11, 0x2f, 0x76, 0x31, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65,
0x72, 0x73, 0x68, 0x6f, 0x77, 0x12, 0x56, 0x0a, 0x07, 0x4e, 0x6f, 0x64, 0x65, 0x41, 0x64, 0x64,
0x12, 0x1a, 0x2e, 0x77, 0x77, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x6f, 0x64, 0x65,
0x41, 0x64, 0x64, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x1a, 0x1a, 0x2e, 0x77,
0x77, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x4c, 0x69, 0x73, 0x74,
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x13, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0d,
0x22, 0x08, 0x2f, 0x76, 0x31, 0x2f, 0x6e, 0x6f, 0x64, 0x65, 0x3a, 0x01, 0x2a, 0x12, 0x55, 0x0a,
0x0a, 0x4e, 0x6f, 0x64, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x1d, 0x2e, 0x77, 0x77,
0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74,
0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f,
0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70,
0x74, 0x79, 0x22, 0x10, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0a, 0x2a, 0x08, 0x2f, 0x76, 0x31, 0x2f,
0x6e, 0x6f, 0x64, 0x65, 0x12, 0x4d, 0x0a, 0x08, 0x4e, 0x6f, 0x64, 0x65, 0x4c, 0x69, 0x73, 0x74,
0x12, 0x13, 0x2e, 0x77, 0x77, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x6f, 0x64, 0x65,
0x4e, 0x61, 0x6d, 0x65, 0x73, 0x1a, 0x1a, 0x2e, 0x77, 0x77, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31,
0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
0x65, 0x22, 0x10, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0a, 0x12, 0x08, 0x2f, 0x76, 0x31, 0x2f, 0x6e,
0x6f, 0x64, 0x65, 0x12, 0x59, 0x0a, 0x07, 0x4e, 0x6f, 0x64, 0x65, 0x53, 0x65, 0x74, 0x12, 0x1a,
0x2e, 0x77, 0x77, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x53, 0x65,
0x74, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x1a, 0x1a, 0x2e, 0x77, 0x77, 0x61,
0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65,
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x16, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x10, 0x22, 0x0b,
0x2f, 0x76, 0x31, 0x2f, 0x6e, 0x6f, 0x64, 0x65, 0x73, 0x65, 0x74, 0x3a, 0x01, 0x2a, 0x12, 0x57,
0x0a, 0x0a, 0x4e, 0x6f, 0x64, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x13, 0x2e, 0x77,
0x77, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x4e, 0x61, 0x6d, 0x65,
0x73, 0x1a, 0x1c, 0x2e, 0x77, 0x77, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x6f, 0x64,
0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
0x16, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x10, 0x12, 0x0e, 0x2f, 0x76, 0x31, 0x2f, 0x6e, 0x6f, 0x64,
0x65, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x4e, 0x0a, 0x07, 0x56, 0x65, 0x72, 0x73, 0x69,
0x6f, 0x6e, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x19, 0x2e, 0x77, 0x77, 0x61,
0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73,
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x10, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0a, 0x12, 0x08, 0x2f,
0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x42, 0x29, 0x5a, 0x27, 0x69, 0x6e, 0x74, 0x65, 0x72,
0x6e, 0x61, 0x6c, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x72, 0x6f, 0x75, 0x74,
0x65, 0x73, 0x2f, 0x77, 0x77, 0x61, 0x70, 0x69, 0x76, 0x31, 0x3b, 0x77, 0x77, 0x61, 0x70, 0x69,
0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
@@ -1628,7 +1761,7 @@ func file_routes_proto_rawDescGZIP() []byte {
}
var file_routes_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
var file_routes_proto_msgTypes = make([]protoimpl.MessageInfo, 27)
var file_routes_proto_msgTypes = make([]protoimpl.MessageInfo, 29)
var file_routes_proto_goTypes = []interface{}{
(GetNodeList_ListType)(0), // 0: wwapi.v1.GetNodeList.ListType
(*ContainerBuildParameter)(nil), // 1: wwapi.v1.ContainerBuildParameter
@@ -1647,30 +1780,32 @@ var file_routes_proto_goTypes = []interface{}{
(*GetNodeList)(nil), // 14: wwapi.v1.GetNodeList
(*NodeList)(nil), // 15: wwapi.v1.NodeList
(*NodeAddParameter)(nil), // 16: wwapi.v1.NodeAddParameter
(*NodeDeleteParameter)(nil), // 17: wwapi.v1.NodeDeleteParameter
(*NodeSetParameter)(nil), // 18: wwapi.v1.NodeSetParameter
(*NodeStatus)(nil), // 19: wwapi.v1.NodeStatus
(*NodeStatusResponse)(nil), // 20: wwapi.v1.NodeStatusResponse
(*VersionResponse)(nil), // 21: wwapi.v1.VersionResponse
nil, // 22: wwapi.v1.NetDev.FieldEntry
nil, // 23: wwapi.v1.NetDev.TagsEntry
nil, // 24: wwapi.v1.NodeInfo.FieldsEntry
nil, // 25: wwapi.v1.NodeInfo.NetDevsEntry
nil, // 26: wwapi.v1.NodeInfo.TagsEntry
nil, // 27: wwapi.v1.NodeInfo.KeysEntry
(*empty.Empty)(nil), // 28: google.protobuf.Empty
(*NodeYaml)(nil), // 17: wwapi.v1.NodeYaml
(*NodeDeleteParameter)(nil), // 18: wwapi.v1.NodeDeleteParameter
(*NodeSetParameter)(nil), // 19: wwapi.v1.NodeSetParameter
(*NodeStatus)(nil), // 20: wwapi.v1.NodeStatus
(*NodeStatusResponse)(nil), // 21: wwapi.v1.NodeStatusResponse
(*VersionResponse)(nil), // 22: wwapi.v1.VersionResponse
(*CanWriteConfig)(nil), // 23: wwapi.v1.CanWriteConfig
nil, // 24: wwapi.v1.NetDev.FieldEntry
nil, // 25: wwapi.v1.NetDev.TagsEntry
nil, // 26: wwapi.v1.NodeInfo.FieldsEntry
nil, // 27: wwapi.v1.NodeInfo.NetDevsEntry
nil, // 28: wwapi.v1.NodeInfo.TagsEntry
nil, // 29: wwapi.v1.NodeInfo.KeysEntry
(*empty.Empty)(nil), // 30: google.protobuf.Empty
}
var file_routes_proto_depIdxs = []int32{
4, // 0: wwapi.v1.ContainerListResponse.containers:type_name -> wwapi.v1.ContainerInfo
22, // 1: wwapi.v1.NetDev.Field:type_name -> wwapi.v1.NetDev.FieldEntry
23, // 2: wwapi.v1.NetDev.Tags:type_name -> wwapi.v1.NetDev.TagsEntry
24, // 3: wwapi.v1.NodeInfo.Fields:type_name -> wwapi.v1.NodeInfo.FieldsEntry
25, // 4: wwapi.v1.NodeInfo.NetDevs:type_name -> wwapi.v1.NodeInfo.NetDevsEntry
26, // 5: wwapi.v1.NodeInfo.Tags:type_name -> wwapi.v1.NodeInfo.TagsEntry
27, // 6: wwapi.v1.NodeInfo.Keys:type_name -> wwapi.v1.NodeInfo.KeysEntry
24, // 1: wwapi.v1.NetDev.Field:type_name -> wwapi.v1.NetDev.FieldEntry
25, // 2: wwapi.v1.NetDev.Tags:type_name -> wwapi.v1.NetDev.TagsEntry
26, // 3: wwapi.v1.NodeInfo.Fields:type_name -> wwapi.v1.NodeInfo.FieldsEntry
27, // 4: wwapi.v1.NodeInfo.NetDevs:type_name -> wwapi.v1.NodeInfo.NetDevsEntry
28, // 5: wwapi.v1.NodeInfo.Tags:type_name -> wwapi.v1.NodeInfo.TagsEntry
29, // 6: wwapi.v1.NodeInfo.Keys:type_name -> wwapi.v1.NodeInfo.KeysEntry
12, // 7: wwapi.v1.NodeListResponse.nodes:type_name -> wwapi.v1.NodeInfo
0, // 8: wwapi.v1.GetNodeList.type:type_name -> wwapi.v1.GetNodeList.ListType
19, // 9: wwapi.v1.NodeStatusResponse.nodeStatus:type_name -> wwapi.v1.NodeStatus
20, // 9: wwapi.v1.NodeStatusResponse.nodeStatus:type_name -> wwapi.v1.NodeStatus
10, // 10: wwapi.v1.NetDev.FieldEntry.value:type_name -> wwapi.v1.NodeField
10, // 11: wwapi.v1.NetDev.TagsEntry.value:type_name -> wwapi.v1.NodeField
10, // 12: wwapi.v1.NodeInfo.FieldsEntry.value:type_name -> wwapi.v1.NodeField
@@ -1680,25 +1815,25 @@ var file_routes_proto_depIdxs = []int32{
1, // 16: wwapi.v1.WWApi.ContainerBuild:input_type -> wwapi.v1.ContainerBuildParameter
2, // 17: wwapi.v1.WWApi.ContainerDelete:input_type -> wwapi.v1.ContainerDeleteParameter
3, // 18: wwapi.v1.WWApi.ContainerImport:input_type -> wwapi.v1.ContainerImportParameter
28, // 19: wwapi.v1.WWApi.ContainerList:input_type -> google.protobuf.Empty
30, // 19: wwapi.v1.WWApi.ContainerList:input_type -> google.protobuf.Empty
6, // 20: wwapi.v1.WWApi.ContainerShow:input_type -> wwapi.v1.ContainerShowParameter
16, // 21: wwapi.v1.WWApi.NodeAdd:input_type -> wwapi.v1.NodeAddParameter
17, // 22: wwapi.v1.WWApi.NodeDelete:input_type -> wwapi.v1.NodeDeleteParameter
18, // 22: wwapi.v1.WWApi.NodeDelete:input_type -> wwapi.v1.NodeDeleteParameter
9, // 23: wwapi.v1.WWApi.NodeList:input_type -> wwapi.v1.NodeNames
18, // 24: wwapi.v1.WWApi.NodeSet:input_type -> wwapi.v1.NodeSetParameter
19, // 24: wwapi.v1.WWApi.NodeSet:input_type -> wwapi.v1.NodeSetParameter
9, // 25: wwapi.v1.WWApi.NodeStatus:input_type -> wwapi.v1.NodeNames
28, // 26: wwapi.v1.WWApi.Version:input_type -> google.protobuf.Empty
30, // 26: wwapi.v1.WWApi.Version:input_type -> google.protobuf.Empty
5, // 27: wwapi.v1.WWApi.ContainerBuild:output_type -> wwapi.v1.ContainerListResponse
28, // 28: wwapi.v1.WWApi.ContainerDelete:output_type -> google.protobuf.Empty
30, // 28: wwapi.v1.WWApi.ContainerDelete:output_type -> google.protobuf.Empty
5, // 29: wwapi.v1.WWApi.ContainerImport:output_type -> wwapi.v1.ContainerListResponse
5, // 30: wwapi.v1.WWApi.ContainerList:output_type -> wwapi.v1.ContainerListResponse
7, // 31: wwapi.v1.WWApi.ContainerShow:output_type -> wwapi.v1.ContainerShowResponse
13, // 32: wwapi.v1.WWApi.NodeAdd:output_type -> wwapi.v1.NodeListResponse
28, // 33: wwapi.v1.WWApi.NodeDelete:output_type -> google.protobuf.Empty
30, // 33: wwapi.v1.WWApi.NodeDelete:output_type -> google.protobuf.Empty
13, // 34: wwapi.v1.WWApi.NodeList:output_type -> wwapi.v1.NodeListResponse
13, // 35: wwapi.v1.WWApi.NodeSet:output_type -> wwapi.v1.NodeListResponse
20, // 36: wwapi.v1.WWApi.NodeStatus:output_type -> wwapi.v1.NodeStatusResponse
21, // 37: wwapi.v1.WWApi.Version:output_type -> wwapi.v1.VersionResponse
21, // 36: wwapi.v1.WWApi.NodeStatus:output_type -> wwapi.v1.NodeStatusResponse
22, // 37: wwapi.v1.WWApi.Version:output_type -> wwapi.v1.VersionResponse
27, // [27:38] is the sub-list for method output_type
16, // [16:27] is the sub-list for method input_type
16, // [16:16] is the sub-list for extension type_name
@@ -1905,7 +2040,7 @@ func file_routes_proto_init() {
}
}
file_routes_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*NodeDeleteParameter); i {
switch v := v.(*NodeYaml); i {
case 0:
return &v.state
case 1:
@@ -1917,7 +2052,7 @@ func file_routes_proto_init() {
}
}
file_routes_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*NodeSetParameter); i {
switch v := v.(*NodeDeleteParameter); i {
case 0:
return &v.state
case 1:
@@ -1929,7 +2064,7 @@ func file_routes_proto_init() {
}
}
file_routes_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*NodeStatus); i {
switch v := v.(*NodeSetParameter); i {
case 0:
return &v.state
case 1:
@@ -1941,7 +2076,7 @@ func file_routes_proto_init() {
}
}
file_routes_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*NodeStatusResponse); i {
switch v := v.(*NodeStatus); i {
case 0:
return &v.state
case 1:
@@ -1953,6 +2088,18 @@ func file_routes_proto_init() {
}
}
file_routes_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*NodeStatusResponse); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_routes_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*VersionResponse); i {
case 0:
return &v.state
@@ -1964,6 +2111,18 @@ func file_routes_proto_init() {
return nil
}
}
file_routes_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*CanWriteConfig); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
type x struct{}
out := protoimpl.TypeBuilder{
@@ -1971,7 +2130,7 @@ func file_routes_proto_init() {
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_routes_proto_rawDesc,
NumEnums: 1,
NumMessages: 27,
NumMessages: 29,
NumExtensions: 0,
NumServices: 1,
},

View File

@@ -1,6 +1,11 @@
package util
import (
"syscall"
"github.com/hpcng/warewulf/internal/pkg/api/routes/wwapiv1"
"github.com/hpcng/warewulf/internal/pkg/node"
"github.com/hpcng/warewulf/internal/pkg/wwlog"
"github.com/manifoldco/promptui"
)
@@ -18,4 +23,19 @@ func ConfirmationPrompt(label string) (yes bool) {
yes = true
}
return
}
}
/*
Simple check if the config can be written in case wwctl isn't run as root
*/
func CanWriteConfig() (canwrite *wwapiv1.CanWriteConfig) {
canwrite = new(wwapiv1.CanWriteConfig)
err := syscall.Access(node.ConfigFile, syscall.O_RDWR)
if err != nil {
wwlog.Warn("Couldn't open %s:%s", node.ConfigFile, err)
canwrite.CanWriteConfig = false
} else {
canwrite.CanWriteConfig = true
}
return canwrite
}

View File

@@ -2,7 +2,6 @@ package container
import (
"path"
"strings"
"github.com/pkg/errors"
@@ -27,20 +26,14 @@ func Build(name string, buildForce bool) error {
}
}
excludes_file := path.Join(rootfsPath, "./etc/warewulf/excludes")
ignore := []string{}
excludes_file := path.Join(rootfsPath, "./etc/warewulf/excludes")
if util.IsFile(excludes_file) {
ignore, err := util.ReadFile(excludes_file)
var err error
ignore, err = util.ReadFile(excludes_file)
if err != nil {
return errors.Wrapf(err, "Failed creating directory: %s", imagePath)
}
for i, pattern := range ignore {
if ( strings.HasPrefix(pattern, "/") ) {
ignore[i] = pattern[1:]
}
}
}
err := util.BuildFsImage(

View File

@@ -14,11 +14,34 @@ import (
)
var ConfigFile string
var DefaultConfig string
// used as fallback if DefaultConfig can't be read
var FallBackConf = `
defaultnode:
runtime overlay:
- generic
system overlay:
- wwinit
kernel:
args: quiet crashkernel=no vga=791 net.naming-scheme=v238
init: /sbin/init
root: initramfs
profiles:
- default
network devices:
dummy:
device: eth0
type: ethernet
netmask: 255.255.255.0`
func init() {
if ConfigFile == "" {
ConfigFile = path.Join(buildconfig.SYSCONFDIR(), "warewulf/nodes.conf")
}
if DefaultConfig == "" {
DefaultConfig = path.Join(buildconfig.SYSCONFDIR(), "warewulf/defaults.conf")
}
}
func New() (NodeYaml, error) {
@@ -54,6 +77,30 @@ func (config *NodeYaml) FindAllNodes() ([]NodeInfo, error) {
return ret, err
}
*/
var defConf map[string]*NodeConf
wwlog.Verbose("Opening defaults failed %s\n", DefaultConfig)
defData, err := ioutil.ReadFile(DefaultConfig)
if err != nil {
wwlog.Verbose("Couldn't read DefaultConfig :%s\n", err)
}
wwlog.Debug("Unmarshalling default config\n")
err = yaml.Unmarshal(defData, &defConf)
if err != nil {
wwlog.Verbose("Couldn't unmarshall defaults from file :%s\n", err)
wwlog.Verbose("Using building defaults")
err = yaml.Unmarshal([]byte(FallBackConf), &defConf)
if err != nil {
wwlog.Warn("Could not get any defaults")
}
}
var defConfNet *NetDevs
if _, ok := defConf["defaultnode"]; ok {
if _, ok := defConf["defaultnode"].NetDevs["dummy"]; ok {
defConfNet = defConf["defaultnode"].NetDevs["dummy"]
}
defConf["defaultnode"].NetDevs = nil
}
wwlog.Debug("Finding all nodes...")
for nodename, node := range config.Nodes {
var n NodeInfo
@@ -63,13 +110,7 @@ func (config *NodeYaml) FindAllNodes() ([]NodeInfo, error) {
n.Tags = make(map[string]*Entry)
n.Kernel = new(KernelEntry)
n.Ipmi = new(IpmiEntry)
n.SystemOverlay.SetDefault("wwinit")
n.RuntimeOverlay.SetDefault("generic")
n.Ipxe.SetDefault("default")
n.Init.SetDefault("/sbin/init")
n.Root.SetDefault("initramfs")
n.Kernel.Args.SetDefault("quiet crashkernel=no vga=791")
n.SetDefFrom(defConf["defaultnode"])
fullname := strings.SplitN(nodename, ".", 2)
if len(fullname) > 1 {
n.ClusterName.SetDefault(fullname[1])
@@ -80,14 +121,18 @@ func (config *NodeYaml) FindAllNodes() ([]NodeInfo, error) {
} else {
n.Profiles.SetSlice(node.Profiles)
}
// node explciti nodename field in NodeConf
// node explicitly nodename field in NodeConf
n.Id.Set(nodename)
// backward compatibilty
// backward compatibility
for keyname, key := range node.Keys {
node.Tags[keyname] = key
delete(node.Keys, keyname)
}
n.SetFrom(node)
// only now the netdevs start to exist so that default values can be set
for _, netdev := range n.NetDevs {
netdev.SetDefFrom(defConfNet)
}
// set default/primary network is just one network exist
if len(n.NetDevs) == 1 {
// only way to get the key

View File

@@ -1,14 +1,11 @@
package node
import (
"github.com/hpcng/warewulf/internal/pkg/util"
"github.com/hpcng/warewulf/internal/pkg/wwlog"
)
/******
* YAML data representations
******/
/*
Structure of which goes to disk
*/
type NodeYaml struct {
WWInternal int `yaml:"WW_INTERNAL"`
NodeProfiles map[string]*NodeConf
@@ -16,7 +13,7 @@ type NodeYaml struct {
}
/*
NodeConf is the datastructure which is stored on disk.
NodeConf is the datastructure describing a node and a profile which in disk format.
*/
type NodeConf struct {
Comment string `yaml:"comment,omitempty" lopt:"comment" comment:"Set arbitrary string comment"`
@@ -24,11 +21,11 @@ type NodeConf struct {
ContainerName string `yaml:"container name,omitempty" lopt:"container" sopt:"C" comment:"Set container name"`
Ipxe string `yaml:"ipxe template,omitempty" lopt:"ipxe" comment:"Set the iPXE template name"`
// Deprecated start
// Kernel settings here are deprecated and here for backward comptability
// Kernel settings here are deprecated and here for backward compatibility
KernelVersion string `yaml:"kernel version,omitempty"`
KernelOverride string `yaml:"kernel override,omitempty"`
KernelArgs string `yaml:"kernel args,omitempty"`
// Ipmi settings herer are deprecated and here for backward comptability
// Ipmi settings herer are deprecated and here for backward compatibility
IpmiUserName string `yaml:"ipmi username,omitempty"`
IpmiPassword string `yaml:"ipmi password,omitempty"`
IpmiIpaddr string `yaml:"ipmi ipaddr,omitempty"`
@@ -82,6 +79,7 @@ type NetDevs struct {
Prefix string `yaml:"prefix,omitempty"`
Netmask string `yaml:"netmask,omitempty" lopt:"netmask" sopt:"M" comment:"Set the networks netmask"`
Gateway string `yaml:"gateway,omitempty" lopt:"gateway" sopt:"G" comment:"Set the node's network device gateway"`
MTU string `yaml:"mtu,omitempty" lopt:"mtu" comment:"Set the mtu"`
Primary string `yaml:"primary,omitempty" lopt:"primary" comment:"Enable/disable network device as primary (yes/no)"`
Default string `yaml:"default,omitempty"` /* backward compatibility */
Tags map[string]string `yaml:"tags,omitempty" lopt:"nettagadd" comment:"network tags"`
@@ -156,6 +154,7 @@ type NetDevEntry struct {
Prefix Entry
Netmask Entry
Gateway Entry
MTU Entry
Primary Entry
Tags map[string]*Entry
}
@@ -163,6 +162,8 @@ type NetDevEntry struct {
// string which is printed if no value is set
const NoValue = "--"
/*
Has no real purpose as only New() needs it
func init() {
// Check that nodes.conf is found
if !util.IsFile(ConfigFile) {
@@ -171,3 +172,4 @@ func init() {
return
}
}
*/

View File

@@ -26,8 +26,7 @@ func FilterByName(set []NodeInfo, searchList []string) []NodeInfo {
if len(searchList) > 0 {
for _, search := range searchList {
for _, entry := range set {
b, _ := regexp.MatchString("^"+search+"$", entry.Id.Get())
if b {
if match, _ := regexp.MatchString("^"+search+"$", entry.Id.Get()); match {
unique[entry.Id.Get()] = entry
}
}
@@ -42,6 +41,24 @@ func FilterByName(set []NodeInfo, searchList []string) []NodeInfo {
return ret
}
/*
Filter a given map of NodeConf against given regular expression.
*/
func FilterMapByName(inputMap map[string]*NodeConf, searchList []string) (retMap map[string]*NodeConf) {
retMap = map[string]*NodeConf{}
if len(searchList) > 0 {
for _, search := range searchList {
for name, nConf := range inputMap {
if match, _ := regexp.MatchString("^"+search+"$", name); match {
retMap[name] = nConf
}
}
}
}
return retMap
}
/**********
*
* Sets

View File

@@ -2,8 +2,10 @@ package node
import (
"reflect"
"strings"
"github.com/hpcng/warewulf/internal/pkg/util"
"github.com/hpcng/warewulf/internal/pkg/wwlog"
"github.com/spf13/cobra"
)
@@ -186,6 +188,10 @@ func (nodeConf *NodeConf) getterFrom(nodeInfo NodeInfo,
}
}
}
/*
Create cmd line flags from the NodeConf fields
*/
func (nodeConf *NodeConf) CreateFlags(baseCmd *cobra.Command, excludeList []string) {
nodeInfoType := reflect.TypeOf(nodeConf)
nodeInfoVal := reflect.ValueOf(nodeConf)
@@ -303,6 +309,20 @@ func (node *NodeInfo) SetAltFrom(n *NodeConf, profileName string) {
node.setterFrom(n, profileName, (*Entry).SetAlt, (*Entry).SetAltSlice)
}
/*
Populates all fields of NodeInfo with SetDefault from the
values of NodeConf.
*/
func (node *NodeInfo) SetDefFrom(n *NodeConf) {
setWrap := func(entr *Entry, val string, nameArg string) {
entr.SetDefault(val)
}
setSliceWrap := func(entr *Entry, val []string, nameArg string) {
entr.SetDefaultSlice(val)
}
node.setterFrom(n, "", setWrap, setSliceWrap)
}
/*
Abstract function which populates a NodeInfo from a NodeConf via
setter functionns.
@@ -438,3 +458,213 @@ func (info *NodeConf) Flatten() {
}
}
}
/*
Populates all fields of NetDevEntry with Set from the
values of NetDevs.
Actually not used, just for completeness.
*/
func (netDev *NetDevEntry) SetFrom(netYaml *NetDevs) {
setWrap := func(entr *Entry, val string, nameArg string) {
entr.Set(val)
}
setSliceWrap := func(entr *Entry, val []string, nameArg string) {
entr.SetSlice(val)
}
netDev.setterFrom(netYaml, "", setWrap, setSliceWrap)
}
/*
Populates all fields of NetDevEntry with SetAlt from the
values of NetDevs. The string profileName is used to
destermine from which source/NodeInfo the entry came
from.
Actually not used, just for completeness.
*/
func (netDev *NetDevEntry) SetAltFrom(netYaml *NetDevs, profileName string) {
netDev.setterFrom(netYaml, profileName, (*Entry).SetAlt, (*Entry).SetAltSlice)
}
/*
Populates all fields of NodeInfo with SetDefault from the
values of NodeConf.
*/
func (netDev *NetDevEntry) SetDefFrom(netYaml *NetDevs) {
setWrap := func(entr *Entry, val string, nameArg string) {
entr.SetDefault(val)
}
setSliceWrap := func(entr *Entry, val []string, nameArg string) {
entr.SetDefaultSlice(val)
}
netDev.setterFrom(netYaml, "", setWrap, setSliceWrap)
}
/*
Abstract function for setting a NetDevEntry from a NetDevs
*/
func (netDev *NetDevEntry) setterFrom(netYaml *NetDevs, nameArg string,
setter func(*Entry, string, string),
setterSlice func(*Entry, []string, string)) {
netValues := reflect.ValueOf(netDev)
netInfoType := reflect.TypeOf(*netYaml)
netInfoVal := reflect.ValueOf(*netYaml)
for j := 0; j < netInfoType.NumField(); j++ {
netVal := netValues.Elem().FieldByName(netInfoType.Field(j).Name)
if netVal.IsValid() {
if netInfoVal.Field(j).Type().Kind() == reflect.String {
setter(netVal.Addr().Interface().((*Entry)), netInfoVal.Field(j).String(), nameArg)
} else if netVal.Type() == reflect.TypeOf(map[string]string{}) {
// danger zone following code is not tested
for key, val := range (netVal.Interface()).(map[string]string) {
//netTagMap := netInfoVal.Elem().Field(j).Interface().((map[string](*Entry)))
if _, ok := netInfoVal.Elem().Field(j).Interface().((map[string](*Entry)))[key]; !ok {
netInfoVal.Elem().Field(j).Interface().((map[string](*Entry)))[key] = new(Entry)
}
setter(netInfoVal.Elem().Field(j).Interface().((map[string](*Entry)))[key], val, nameArg)
}
}
}
}
}
/*
Create a string slice, where every element represents a yaml entry
*/
func (nodeConf *NodeConf) UnmarshalConf(excludeList []string) (lines []string) {
nodeInfoType := reflect.TypeOf(nodeConf)
nodeInfoVal := reflect.ValueOf(nodeConf)
// now iterate of every field
for i := 0; i < nodeInfoVal.Elem().NumField(); i++ {
if nodeInfoType.Elem().Field(i).Tag.Get("lopt") != "" {
if ymlStr, ok := getYamlString(nodeInfoType.Elem().Field(i), excludeList); ok {
lines = append(lines, ymlStr...)
}
} else if nodeInfoType.Elem().Field(i).Type.Kind() == reflect.Ptr {
nestType := reflect.TypeOf(nodeInfoVal.Elem().Field(i).Interface())
if ymlStr, ok := getYamlString(nodeInfoType.Elem().Field(i), excludeList); ok {
lines = append(lines, ymlStr...)
}
for j := 0; j < nestType.Elem().NumField(); j++ {
if nestType.Elem().Field(j).Tag.Get("lopt") != "" &&
!util.InSlice(excludeList, nestType.Elem().Field(j).Tag.Get("lopt")) {
if ymlStr, ok := getYamlString(nestType.Elem().Field(j), excludeList); ok {
for _, str := range ymlStr {
lines = append(lines, " "+str)
}
}
}
}
} else if nodeInfoType.Elem().Field(i).Type == reflect.TypeOf(map[string]*NetDevs(nil)) {
netMap := nodeInfoVal.Elem().Field(i).Interface().(map[string]*NetDevs)
// add a default network so that it can hold values
key := "default"
if len(netMap) == 0 {
netMap[key] = new(NetDevs)
} else {
for keyIt := range netMap {
key = keyIt
break
}
}
if ymlStr, ok := getYamlString(nodeInfoType.Elem().Field(i), excludeList); ok {
lines = append(lines, ymlStr[0]+":", " "+key+":")
netType := reflect.TypeOf(netMap[key])
for j := 0; j < netType.Elem().NumField(); j++ {
if ymlStr, ok := getYamlString(netType.Elem().Field(j), excludeList); ok {
for _, str := range ymlStr {
lines = append(lines, " "+str)
}
}
} // lines
} // this
} //not
} //do
return lines
}
/*
Get the string of the yaml tag
*/
func getYamlString(myType reflect.StructField, excludeList []string) ([]string, bool) {
ymlStr := myType.Tag.Get("yaml")
if len(strings.Split(ymlStr, ",")) > 1 {
ymlStr = strings.Split(ymlStr, ",")[0]
}
if util.InSlice(excludeList, ymlStr) {
return []string{""}, false
} else if myType.Tag.Get("lopt") == "" && myType.Type.Kind() == reflect.String {
return []string{""}, false
}
if myType.Type.Kind() == reflect.String {
ymlStr += ": string"
return []string{ymlStr}, true
} else if myType.Type == reflect.TypeOf([]string{}) {
return []string{ymlStr + ":", " - string"}, true
} else if myType.Type == reflect.TypeOf(map[string]string{}) {
return []string{ymlStr + ":", " key: value"}, true
} else if myType.Type.Kind() == reflect.Ptr {
return []string{ymlStr + ":"}, true
}
return []string{ymlStr}, true
}
/*
Set the field of the NodeConf with the given lopt name, returns true if the
field was found. String slices must be comma separated. Network must have the form
net.$NETNAME.lopt or netname.$NETNAME.lopt
*/
func (nodeConf *NodeConf) SetLopt(lopt string, value string) (found bool) {
found = false
nodeInfoType := reflect.TypeOf(nodeConf)
nodeInfoVal := reflect.ValueOf(nodeConf)
// try to find the normal fields, networks come later
for i := 0; i < nodeInfoVal.Elem().NumField(); i++ {
//fmt.Println(nodeInfoType.Elem().Field(i).Tag.Get("lopt"), lopt)
if nodeInfoType.Elem().Field(i).Tag.Get("lopt") == lopt {
if nodeInfoType.Elem().Field(i).Type.Kind() == reflect.String {
wwlog.Verbose("Found lopt %s mapping to %s, setting to %s\n",
lopt, nodeInfoType.Elem().Field(i).Name, value)
confVal := nodeInfoVal.Elem().Field(i).Addr().Interface().(*string)
*confVal = value
found = true
} else if nodeInfoType.Elem().Field(i).Type == reflect.TypeOf([]string{}) {
wwlog.Verbose("Found lopt %s mapping to %s, setting to %s\n",
lopt, nodeInfoType.Elem().Field(i).Name, value)
confVal := nodeInfoVal.Elem().Field(i).Addr().Interface().(*[]string)
*confVal = strings.Split(value, ",")
found = true
}
}
}
// check network
loptSlice := strings.Split(lopt, ".")
wwlog.Debug("Trying to get network out of %s\n", loptSlice)
if !found && len(loptSlice) == 3 && (loptSlice[0] == "net" || loptSlice[0] == "network" || loptSlice[0] == "netname") {
if nodeConf.NetDevs == nil {
nodeConf.NetDevs = make(map[string]*NetDevs)
}
if nodeConf.NetDevs[loptSlice[1]] == nil {
nodeConf.NetDevs[loptSlice[1]] = new(NetDevs)
}
netInfoType := reflect.TypeOf(nodeConf.NetDevs[loptSlice[1]])
netInfoVal := reflect.ValueOf(nodeConf.NetDevs[loptSlice[1]])
for i := 0; i < netInfoVal.Elem().NumField(); i++ {
if netInfoType.Elem().Field(i).Tag.Get("lopt") == loptSlice[2] {
if netInfoType.Elem().Field(i).Type.Kind() == reflect.String {
wwlog.Verbose("Found lopt %s for network %s mapping to %s, setting to %s\n",
lopt, loptSlice[1], netInfoType.Elem().Field(i).Name, value)
confVal := netInfoVal.Elem().Field(i).Addr().Interface().(*string)
*confVal = value
found = true
} else if netInfoType.Elem().Field(i).Type == reflect.TypeOf([]string{}) {
wwlog.Verbose("Found lopt %s for network %s mapping to %s, setting to %s\n",
lopt, loptSlice[1], netInfoType.Elem().Field(i).Name, value)
confVal := netInfoVal.Elem().Field(i).Addr().Interface().(*[]string)
*confVal = strings.Split(value, ",")
found = true
}
}
}
}
return found
}

View File

@@ -260,34 +260,17 @@ func FindFilterFiles(
defer func() {
err = FirstError(err, os.Chdir(cwd))
}()
err = os.Chdir(path)
if err != nil {
return ofiles, errors.Wrapf(err, "Failed to change path: %s", path)
}
files := []string{}
for _, pattern := range include {
_files, err := filepath.Glob(pattern)
if err != nil {
return ofiles, errors.Wrapf(err, "Failed to apply pattern: %s", pattern)
}
wwlog.Debug("Including pattern: %s -> %d matches", pattern, len(_files))
files = append(files, _files...)
}
for i, pattern := range(ignore) {
if strings.HasPrefix(pattern, "./") {
ignore[i] = pattern[2:]
}
for i := range(ignore) {
ignore[i] = strings.TrimLeft(ignore[i], "/")
ignore[i] = strings.TrimPrefix(ignore[i], "./")
wwlog.Debug("Ignore pattern (%d): %s", i, ignore[i])
}
if ignore_xdev {
wwlog.Debug("Ignoring cross-device (xdev) files")
}
@@ -299,66 +282,72 @@ func FindFilterFiles(
dev := path_stat.Sys().(*syscall.Stat_t).Dev
for _, ifile := range files {
stat, err := os.Stat(ifile)
includeDirs := []string{}
ignoreDirs := []string{}
err = filepath.Walk(".", func(location string, info os.FileInfo, err error) error {
if err != nil {
return ofiles, err
return err
}
if stat.IsDir() {
// recursivly include from the matched directory
if location == "." {
return nil
}
num_init := len(ofiles)
err = filepath.Walk(ifile, func(location string, info os.FileInfo, err error) error {
var file string
var file string
if info.IsDir() {
file = location + "/"
} else {
file = location
}
if err != nil {
return err
}
if location == "." {
return nil
}
if info.IsDir() {
file = location + "/"
} else {
file = location
}
if ignore_xdev && info.Sys().(*syscall.Stat_t).Dev != dev {
wwlog.Debug("Ignored (cross-device): %s", file)
return nil
}
for i, pattern := range(ignore) {
m, err := filepath.Match(pattern, location)
if err != nil {
return err
}
if m {
wwlog.Debug("Ignored (%d): %s", i, file)
return nil
}
}
ofiles = append(ofiles, file)
if ignore_xdev && info.Sys().(*syscall.Stat_t).Dev != dev {
wwlog.Debug("Ignored (cross-device): %s", file)
return nil
}
for _, ignoreDir := range(ignoreDirs) {
if strings.HasPrefix(location, ignoreDir) {
wwlog.Debug("Ignored (dir): %s", file)
return nil
})
num_final := len(ofiles)
wwlog.Debug("Included: %s -> %d files", ifile, num_final-num_init)
if err != nil {
return ofiles, err
}
}else{
wwlog.Debug("Included: %s", ifile)
ofiles = append(ofiles, ifile)
}
}
for i, pattern := range(ignore) {
m, err := filepath.Match(pattern, location)
if err != nil {
return err
} else if m {
wwlog.Debug("Ignored (%d): %s", i, file)
if info.IsDir() {
ignoreDirs = append(ignoreDirs, file)
}
return nil
}
}
for _, includeDir := range(includeDirs) {
if strings.HasPrefix(location, includeDir) {
wwlog.Debug("Included (dir): %s", file)
ofiles = append(ofiles, location)
return nil
}
}
for i, pattern := range(include) {
m, err := filepath.Match(pattern, location)
if err != nil {
return err
} else if m {
wwlog.Debug("Included (%d): %s", i, file)
ofiles = append(ofiles, location)
if info.IsDir() {
includeDirs = append(includeDirs, file)
}
return nil
}
}
return nil
})
return ofiles, err
}
@@ -715,3 +704,36 @@ func RunWWCTL(args ...string) (out []byte, err error) {
return out, err
}
/*
Get size of given directory in bytes
*/
func DirSize(path string) (int64, error) {
var size int64
err := filepath.Walk(path, func(_ string, info os.FileInfo, err error) error {
if err != nil {
return err
}
if !info.IsDir() {
size += info.Size()
}
return err
})
return size, err
}
/*
Convert bytes to human friendly format
*/
func ByteToString(b int64) string {
const base = 1024
if b < base {
return fmt.Sprintf("%d B", b)
}
div, exp := int64(base), 0
for n := b / base; n >= base; n /= base {
div *= base
exp++
}
return fmt.Sprintf("%.1f %ciB", float64(b)/float64(div), "KMGTPE"[exp])
}

View File

@@ -0,0 +1,48 @@
{{- $host := .BuildHost }}
{{- $time := .BuildTime }}
{{- $source := .BuildSource }}
{{- range $devname, $netdev := .NetDevs }}
{{- $filename := print "warewulf-" $devname ".conf" }}
{{- file $filename }}
# This file is autogenerated by warewulf
# Host: {{ $host }}
# Time: {{ $time }}
# Source: {{ $source }}
[connection]
id={{ $devname }}
interface-name={{ $netdev.Device }}
{{ if $netdev.Type -}}
type={{ $netdev.Type }}
{{ end -}}
autoconnect=true
{{ if $netdev.Hwaddr -}}
{{ if eq $netdev.Type "ethernet" -}}
[ethernet]
mac-address={{ $netdev.Hwaddr }}
{{ end -}}
{{ end -}}
{{ if eq $netdev.Type "infiniband" -}}
[infiniband]
transport-mode=datagram
{{ end -}}
{{ if $netdev.IpCIDR -}}
[ipv4]
address={{ $netdev.IpCIDR }}
{{ if $netdev.Gateway -}}
gateway={{ $netdev.Gateway }}
{{ end -}}
method=manual
{{ end -}}
{{/* always autoconfigure ipv6 */}}
[ipv6]
addr-gen-mode=stable-privacy
method=ignore
never-default=true
{{ if $netdev.Ipaddr6 -}}
ipaddr="{{ $netdev.Ipaddr6 }}"
{{ end -}}
{{ end -}}

View File

@@ -3,7 +3,7 @@
# Time: {{.BuildTime}}
# Source: {{.BuildSource}}
{{range $devname, $netdev := .NetDevs}}
{{- if $netdev.Primary}}
{{- if $netdev.Hwaddr }}
[Match]
MACAddress={{$netdev.Hwaddr}}
[Link]

View File

@@ -0,0 +1,9 @@
# This file is autogenerated by warewulf
# Host: {{.BuildHost}}
# Time: {{.BuildTime}}
# Source: {{.BuildSource}}
{{range $devname, $netdev := .NetDevs}}
{{- if $netdev.Hwaddr }}
SUBSYSTEM=="net", ACTION=="add", ATTR{address}=="{{ $netdev.Hwaddr }}", NAME="{{ $netdev.Device }}"
{{ end -}}
{{ end -}}