diff --git a/CHANGELOG.md b/CHANGELOG.md index ccec5f09..ae70a0e6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -39,6 +39,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ### Changed +- Renamed "container" to "image" throughout wwctl and overlay templates. #1385 - Locally defined `tr` has been dropped, templates updated to use Sprig replace. - Bump github.com/opencontainers/image-spec to 1.1.0 - Bump google.golang.org/grpc 1.62.1 diff --git a/README.md b/README.md index 170b6f35..71a269b5 100644 --- a/README.md +++ b/README.md @@ -55,9 +55,7 @@ many thousands of compute nodes. Generally speaking, operating system state introduce a surface for potential discrepancies and version creep between nodes and thus Warewulf has always gone with the "single system image" approach to clustered operating system management. This -means that you can have a single management node "image". For the last -20 years, we've been calling this a Virtual Node File System (VNFS), -but in hindsight, this is a container. +means that you can have a single node "image". At its core, Warewulf v4 focuses on what has made Warewulf so widely loved: simplicity, ultra scalable, lightweight, and an easy to manage diff --git a/dracut/modules.d/90wwinit/load-wwinit.sh b/dracut/modules.d/90wwinit/load-wwinit.sh index 3b191dea..b434dacd 100755 --- a/dracut/modules.d/90wwinit/load-wwinit.sh +++ b/dracut/modules.d/90wwinit/load-wwinit.sh @@ -3,7 +3,7 @@ info "Mounting tmpfs at $NEWROOT" mount -t tmpfs -o mpol=interleave ${wwinit_tmpfs_size_option} tmpfs "$NEWROOT" -for archive in "${wwinit_container}" "${wwinit_system}" "${wwinit_runtime}" +for archive in "${wwinit_image}" "${wwinit_system}" "${wwinit_runtime}" do if [ -n "${archive}" ] then diff --git a/dracut/modules.d/90wwinit/parse-wwinit.sh b/dracut/modules.d/90wwinit/parse-wwinit.sh index 28d0df23..b9e7446f 100755 --- a/dracut/modules.d/90wwinit/parse-wwinit.sh +++ b/dracut/modules.d/90wwinit/parse-wwinit.sh @@ -9,7 +9,7 @@ then uuid=$(dmidecode -s system-uuid) assetkey=$(dmidecode -s chassis-asset-tag | sed -E -e 's/(^ +| +$)//g' -e 's/^(Unknown|Not Specified)$//g' -e 's/ /_/g') wwinit_uri="$(getarg wwinit.uri)?assetkey=${assetkey}&uuid=${uuid}" - export wwinit_container="${wwinit_uri}&stage=container&compress=gz"; info "wwinit_container=${wwinit_container}" + export wwinit_image="${wwinit_uri}&stage=image&compress=gz"; info "wwinit_image=${wwinit_image}" export wwinit_system="${wwinit_uri}&stage=system&compress=gz"; info "wwinit_system=${wwinit_system}" export wwinit_runtime="${wwinit_uri}&stage=runtime&compress=gz"; info "wwinit_runtime=${wwinit_runtime}" @@ -20,11 +20,11 @@ then export wwinit_tmpfs_size_option="-o size=${wwinit_tmpfs_size}" fi - if [ -n "${wwinit_container}" ] + if [ -n "${wwinit_image}" ] then - info "Found root=${root} and a Warewulf container image. Will boot from Warewulf." + info "Found root=${root} and a Warewulf image. Will boot from Warewulf." rootok=1 else - die "Found root=${root} but no container image. Cannot boot from Warewulf." + die "Found root=${root} but no image. Cannot boot from Warewulf." fi fi diff --git a/etc/grub/chainload.ww b/etc/grub/chainload.ww index 7622a1b7..3938132e 100644 --- a/etc/grub/chainload.ww +++ b/etc/grub/chainload.ww @@ -12,7 +12,7 @@ menuentry "Load specific configfile" { conf="(http,{{.Ipaddr}}:{{.Warewulf.Port}})/efiboot/grub.cfg?assetkey=${assetkey}" configfile $conf } -menuentry "Chainload shim of container" { +menuentry "Chainload shim from image" { shim="(http,{{.Ipaddr}}:{{.Warewulf.Port}})/efiboot/shim.efi?assetkey=${assetkey}" chainloader ${shim} } diff --git a/etc/grub/grub.cfg.ww b/etc/grub/grub.cfg.ww index ae6c39f3..6f464d5b 100644 --- a/etc/grub/grub.cfg.ww +++ b/etc/grub/grub.cfg.ww @@ -1,4 +1,4 @@ -{{ if .ContainerName }} +{{ if .ImageName }} echo "================================================================================" echo "Warewulf v4 now http booting grub: {{.Fqdn}} ({{.Hwaddr}})" echo "================================================================================" @@ -10,7 +10,7 @@ smbios --type 3 --get-string 8 --set assetkey uri="(http,{{.Ipaddr}}:{{.Port}})/provision/${net_default_mac}?assetkey=${assetkey}" kernel="${uri}&stage=kernel" -container="${uri}&stage=container&compress=gz" +image="${uri}&stage=image&compress=gz" system="${uri}&stage=system&compress=gz" runtime="${uri}&stage=runtime&compress=gz" @@ -21,13 +21,13 @@ menuentry "Network boot node: {{.Id}}" --id ww4 { {{if .KernelVersion }} echo "Kernel: {{.KernelVersion}}" {{else}} - echo "Kernel: {{.ContainerName}} (container default)" + echo "Kernel: {{.ImageName}} (image default)" {{end}} echo "KernelArgs: {{.KernelArgs}}" linux $kernel wwid=${net_default_mac} {{.KernelArgs}} if [ x$? = x0 ] ; then - echo "Loading Container: {{.ContainerName}}" - initrd $container $system $runtime + echo "Loading Image: {{.ImageName}}" + initrd $image $system $runtime boot else echo "MESSAGE: This node seems to be unconfigured. Please have your system administrator add a" @@ -47,7 +47,7 @@ menuentry "Network boot node with dracut: {{.Id}}" --id dracut { {{if .KernelVersion }} echo "Kernel: {{.KernelVersion}}" {{else}} - echo "Kernel: {{.ContainerName}} (container default)" + echo "Kernel: {{.ImageName}} (image default)" {{end}} echo "KernelArgs: {{.KernelArgs}}" @@ -56,7 +56,7 @@ menuentry "Network boot node with dracut: {{.Id}}" --id dracut { linux $kernel wwid=${net_default_mac} {{.KernelArgs}} $net_args $wwinit_args if [ x$? = x0 ] ; then - echo "Loading Container: {{.ContainerName}}" + echo "Loading Image: {{.ImageName}}" initrd $initramfs boot else @@ -90,7 +90,7 @@ menuentry "System shutdown" { {{ else }} echo "================================================================================" echo " Warewulf v4:" -echo " No node image/container defined for this node ({{.Fqdn}})." +echo " No node image defined for this node ({{.Fqdn}})." echo " Rebooting in 30s." echo "================================================================================" sleep 30 diff --git a/etc/ipxe/default.ipxe b/etc/ipxe/default.ipxe index 9d3eb608..9977e702 100644 --- a/etc/ipxe/default.ipxe +++ b/etc/ipxe/default.ipxe @@ -1,14 +1,14 @@ #!ipxe -{{ if .ContainerName }} +{{ if .ImageName }} echo echo ================================================================================ echo Warewulf v4 now booting: {{.Fqdn}} ({{.Hwaddr}}) echo -echo Container: {{.ContainerName}} +echo Image: {{.ImageName}} {{if .KernelVersion }} echo Kernel: {{.KernelVersion}} {{else}} -echo Kernel: {{.ContainerName}} (container default) +echo Kernel: {{.ImageName}} (image default) {{end}} echo KernelArgs: {{.KernelArgs}} echo @@ -30,8 +30,8 @@ iseq ${platform} efi && goto efi || goto noefi # try extracting compressed images first # NOTE: system overlay tends to be the smallest, so failure here is the cheapest -echo Downloading Container Image: -imgextract --name container ${uri_base}&stage=container&compress=gz || goto nocompress +echo Downloading Image: +imgextract --name image ${uri_base}&stage=image&compress=gz || goto nocompress echo Downloading System Overlay: imgextract --name system ${uri_base}&stage=system&compress=gz || goto reboot @@ -46,8 +46,8 @@ goto imoktogo echo echo Image extract not supported in this iPXE, using standard initrd mode -echo Downloading Container Image: -initrd --name container ${uri_base}&stage=container || goto reboot +echo Downloading Image: +initrd --name image ${uri_base}&stage=image || goto reboot echo Downloading System Overlay: initrd --name system ${uri_base}&stage=system || goto reboot @@ -62,8 +62,8 @@ goto imoktogo echo echo Use legacy initrd mode with compressed images -echo Downloading Container Image: -initrd --name container ${uri_base}&stage=container&compress=gz || goto reboot +echo Downloading Image: +initrd --name image ${uri_base}&stage=image&compress=gz || goto reboot echo Downloading System Overlay: initrd --name system ${uri_base}&stage=system&compress=gz || goto reboot @@ -74,8 +74,8 @@ initrd --name runtime ${uri_base}&stage=runtime&compress=gz && set runtime_i :imoktogo -echo boot kernel initrd=container initrd=system ${runtime_initrd} wwid={{.Hwaddr}} {{.KernelArgs}} -boot kernel initrd=container initrd=system ${runtime_initrd} wwid={{.Hwaddr}} {{.KernelArgs}} || goto reboot +echo boot kernel initrd=image initrd=system ${runtime_initrd} wwid={{.Hwaddr}} {{.KernelArgs}} +boot kernel initrd=image initrd=system ${runtime_initrd} wwid={{.Hwaddr}} {{.KernelArgs}} || goto reboot :reboot echo @@ -86,7 +86,7 @@ reboot {{ else }} echo ================================================================================ echo Warewulf v4: -echo No node image/container defined for this node ({{.Fqdn}}). +echo No image defined for this node ({{.Fqdn}}). echo Rebooting in 30s. echo ================================================================================ sleep 30 diff --git a/etc/ipxe/dracut.ipxe b/etc/ipxe/dracut.ipxe index 2f8d3f0a..e7b09e50 100644 --- a/etc/ipxe/dracut.ipxe +++ b/etc/ipxe/dracut.ipxe @@ -1,14 +1,14 @@ #!ipxe -{{ if .ContainerName }} +{{ if .ImageName }} echo echo ================================================================================ echo Warewulf v4 now booting via dracut: {{.Fqdn}} ({{.Hwaddr}}) echo -echo Container: {{.ContainerName}} +echo Image: {{.ImageName}} {{if .KernelVersion }} echo Kernel: {{.KernelVersion}} {{else}} -echo Kernel: {{.ContainerName}} (container default) +echo Kernel: {{.ImageName}} (image default) {{end}} echo KernelArgs: {{.KernelArgs}} echo @@ -39,7 +39,7 @@ reboot {{ else }} echo ================================================================================ echo Warewulf v4: -echo No node image/container defined for this node ({{.Fqdn}}). +echo No image defined for this node ({{.Fqdn}}). echo Rebooting in 30s. echo ================================================================================ sleep 30 diff --git a/etc/warewulf.conf b/etc/warewulf.conf index 39e52f23..740b2e7b 100644 --- a/etc/warewulf.conf +++ b/etc/warewulf.conf @@ -27,7 +27,7 @@ nfs: - path: /opt export options: ro,sync,no_root_squash systemd name: nfs-server -container mounts: +image mounts: - source: /etc/resolv.conf dest: /etc/resolv.conf readonly: true diff --git a/include/firewalld/warewulf.xml b/include/firewalld/warewulf.xml index b7e85244..67700756 100644 --- a/include/firewalld/warewulf.xml +++ b/include/firewalld/warewulf.xml @@ -1,6 +1,6 @@ warewulf - Warewulf is a stateless and diskless container operating system provisioning system for large clusters of bare metal and/or virtual systems. + Warewulf is a stateless and diskless provisioning system for large clusters of bare metal and/or virtual systems. diff --git a/internal/app/api/API.md b/internal/app/api/API.md index 2b94cf88..81bb39f6 100644 --- a/internal/app/api/API.md +++ b/internal/app/api/API.md @@ -14,12 +14,12 @@ wwctl node delete wwctl node list wwctl node set wwctl node status -wwctl container build -wwctl container delete -wwctl container import -wwctl container list -wwctl container show -wwctl container copy +wwctl image build +wwctl image delete +wwctl image import +wwctl image list +wwctl image show +wwctl image copy Some notes on the files: diff --git a/internal/app/api/wwapid/README.md b/internal/app/api/wwapid/README.md index 0c0a18dc..d36803fd 100644 --- a/internal/app/api/wwapid/README.md +++ b/internal/app/api/wwapid/README.md @@ -1,7 +1,7 @@ # Warewulf API Daemon -wwapid is a grpc service serving the Warewulf API. For v1, the intent is to serve the same interface as wwctl serves. For this preview PR, we are serving much of ```wwctl node``` and ```wwctl container```. +wwapid is a grpc service serving the Warewulf API. For v1, the intent is to serve the same interface as wwctl serves. For this preview PR, we are serving much of ```wwctl node``` and ```wwctl image```. Initial security is by mTLS. For development we are generating our own keys. A good tutorial for this is here: https://www.handracs.info/blog/grpcmtlsgo/ -The configuration file is wwapid.conf. \ No newline at end of file +The configuration file is wwapid.conf. diff --git a/internal/app/api/wwapid/wwapid.go b/internal/app/api/wwapid/wwapid.go index 055cff77..3fecc544 100644 --- a/internal/app/api/wwapid/wwapid.go +++ b/internal/app/api/wwapid/wwapid.go @@ -12,7 +12,7 @@ import ( "path" "github.com/warewulf/warewulf/internal/pkg/api/apiconfig" - "github.com/warewulf/warewulf/internal/pkg/api/container" + "github.com/warewulf/warewulf/internal/pkg/api/image" apinode "github.com/warewulf/warewulf/internal/pkg/api/node" "github.com/warewulf/warewulf/internal/pkg/api/routes/wwapiv1" warewulfconf "github.com/warewulf/warewulf/internal/pkg/config" @@ -121,92 +121,92 @@ func insecureMode() { // Api implementation. -// ContainerBuild builds one or more containers. -func (s *apiServer) ContainerBuild(ctx context.Context, request *wwapiv1.ContainerBuildParameter) (response *wwapiv1.ContainerListResponse, err error) { +// ImageBuild builds one or more images. +func (s *apiServer) ImageBuild(ctx context.Context, request *wwapiv1.ImageBuildParameter) (response *wwapiv1.ImageListResponse, err error) { // Parameter checks. if request == nil { return response, status.Errorf(codes.InvalidArgument, "nil request") } - if request.ContainerNames == nil { - return response, status.Errorf(codes.InvalidArgument, "nil request.ContainerNames") + if request.ImageNames == nil { + return response, status.Errorf(codes.InvalidArgument, "nil request.ImageNames") } - // Build the container. - err = container.ContainerBuild(request) + // Build the image. + err = image.ImageBuild(request) if err != nil { return } - // Return the built containers. (A REST POST returns what is modified.) - var containers []*wwapiv1.ContainerInfo - containers, err = container.ContainerList() + // Return the built images. (A REST POST returns what is modified.) + var images []*wwapiv1.ImageInfo + images, err = image.ImageList() if err != nil { return } - response = &wwapiv1.ContainerListResponse{} - for i := 0; i < len(containers); i++ { - for j := 0; j < len(request.ContainerNames); j++ { - if containers[i].Name == request.ContainerNames[j] { - response.Containers = append(response.Containers, containers[i]) + response = &wwapiv1.ImageListResponse{} + for i := 0; i < len(images); i++ { + for j := 0; j < len(request.ImageNames); j++ { + if images[i].Name == request.ImageNames[j] { + response.Images = append(response.Images, images[i]) } } } return } -// ContainerCopy duplicates a container. -func (s *apiServer) ContainerCopy(ctx context.Context, request *wwapiv1.ContainerCopyParameter) (response *emptypb.Empty, err error) { +// ImageCopy duplicates an image. +func (s *apiServer) ImageCopy(ctx context.Context, request *wwapiv1.ImageCopyParameter) (response *emptypb.Empty, err error) { // Parameter checks. if request == nil { return response, status.Errorf(codes.InvalidArgument, "nil request") } - err = container.ContainerCopy(request) + err = image.ImageCopy(request) return } -// ContainerDelete deletes one or more containers from Warewulf. -func (s *apiServer) ContainerDelete(ctx context.Context, request *wwapiv1.ContainerDeleteParameter) (response *emptypb.Empty, err error) { +// ImageDelete deletes one or more images from Warewulf. +func (s *apiServer) ImageDelete(ctx context.Context, request *wwapiv1.ImageDeleteParameter) (response *emptypb.Empty, err error) { // Parameter checks. if request == nil { return response, status.Errorf(codes.InvalidArgument, "nil request") } - if request.ContainerNames == nil { - return response, status.Errorf(codes.InvalidArgument, "nil request.ContainerNames") + if request.ImageNames == nil { + return response, status.Errorf(codes.InvalidArgument, "nil request.ImageNames") } - err = container.ContainerDelete(request) + err = image.ImageDelete(request) return } -func (s *apiServer) ContainerImport(ctx context.Context, request *wwapiv1.ContainerImportParameter) (response *wwapiv1.ContainerListResponse, err error) { +func (s *apiServer) ImageImport(ctx context.Context, request *wwapiv1.ImageImportParameter) (response *wwapiv1.ImageListResponse, err error) { - // Import the container. - var containerName string - containerName, err = container.ContainerImport(request) + // Import the image. + var imageName string + imageName, err = image.ImageImport(request) if err != nil { return } - // Return the imported container to the client. - var containers []*wwapiv1.ContainerInfo - containers, err = container.ContainerList() + // Return the imported image to the client. + var images []*wwapiv1.ImageInfo + images, err = image.ImageList() if err != nil { return } - // Container name may have been shimmed in during import, - // which is why ContainerImport returns it. - for i := 0; i < len(containers); i++ { - if containerName == containers[i].Name { - response = &wwapiv1.ContainerListResponse{ - Containers: []*wwapiv1.ContainerInfo{containers[i]}, + // Image name may have been shimmed in during import, + // which is why ImageImport returns it. + for i := 0; i < len(images); i++ { + if imageName == images[i].Name { + response = &wwapiv1.ImageListResponse{ + Images: []*wwapiv1.ImageInfo{images[i]}, } return } @@ -214,30 +214,30 @@ func (s *apiServer) ContainerImport(ctx context.Context, request *wwapiv1.Contai return } -// ContainerList returns details about containers. -func (s *apiServer) ContainerList(ctx context.Context, request *emptypb.Empty) (response *wwapiv1.ContainerListResponse, err error) { +// ImageList returns details about images. +func (s *apiServer) ImageList(ctx context.Context, request *emptypb.Empty) (response *wwapiv1.ImageListResponse, err error) { - var containers []*wwapiv1.ContainerInfo - containers, err = container.ContainerList() + var images []*wwapiv1.ImageInfo + images, err = image.ImageList() if err != nil { return } - response = &wwapiv1.ContainerListResponse{ - Containers: containers, + response = &wwapiv1.ImageListResponse{ + Images: images, } return } -// ContainerShow returns details about containers. -func (s *apiServer) ContainerShow(ctx context.Context, request *wwapiv1.ContainerShowParameter) (response *wwapiv1.ContainerShowResponse, err error) { +// ImageShow returns details about images. +func (s *apiServer) ImageShow(ctx context.Context, request *wwapiv1.ImageShowParameter) (response *wwapiv1.ImageShowResponse, err error) { // Parameter checks. if request == nil { return response, status.Errorf(codes.InvalidArgument, "nil request") } - return container.ContainerShow(request) + return image.ImageShow(request) } // NodeAdd adds one or more nodes for management by Warewulf and returns the added nodes. diff --git a/internal/app/api/wwapird/README.md b/internal/app/api/wwapird/README.md index 6c75ca0e..492f0abd 100644 --- a/internal/app/api/wwapird/README.md +++ b/internal/app/api/wwapird/README.md @@ -1,9 +1,9 @@ # Warewulf API Rest Daemon -wwapird is a client of wwapid serving a REST interface for the Warewulf API. For v1, the intent is to serve the same interface as wwctl serves. For this preview PR, we are serving much of ```wwctl node``` and ```wwctl container```. +wwapird is a client of wwapid serving a REST interface for the Warewulf API. For v1, the intent is to serve the same interface as wwctl serves. For this preview PR, we are serving much of ```wwctl node``` and ```wwctl image```. Initial security is by mTLS. For development we are generating our own keys. A good tutorial for this is here: https://www.handracs.info/blog/grpcmtlsgo/ The configuration file is wwapird.conf. -Sample cURLs with and without mTLS are in curl.sh. This file is just a scratchpad for examples. \ No newline at end of file +Sample cURLs with and without mTLS are in curl.sh. This file is just a scratchpad for examples. diff --git a/internal/app/api/wwapird_curls/curls.sh b/internal/app/api/wwapird_curls/curls.sh index 8736fc9e..a8596780 100644 --- a/internal/app/api/wwapird_curls/curls.sh +++ b/internal/app/api/wwapird_curls/curls.sh @@ -11,17 +11,17 @@ curl --cacert /usr/local/etc/warewulf/keys/cacert.pem \ --cert /usr/local/etc/warewulf/keys/client.pem \ https://localhost:9871/version -# container list all -curl http://localhost:9871/v1/container +# image list all +curl http://localhost:9871/v1/image -# container import -curl -d '{"source": "docker://ghcr.io/warewulf/warewulf-rockylinux:8", "name": "rocky-8", "update": true, "default": true}' -H "Content-Type: application/json" -X POST http://localhost:9871/v1/container +# image import +curl -d '{"source": "docker://ghcr.io/warewulf/warewulf-rockylinux:8", "name": "rocky-8", "update": true, "default": true}' -H "Content-Type: application/json" -X POST http://localhost:9871/v1/image -# container delete -curl -X DELETE http://localhost:9871/v1/container?containerNames=rocky-8 +# image delete +curl -X DELETE http://localhost:9871/v1/image?imageNames=rocky-8 -# container build -curl -d '{"containerNames": ["rocky-8"], "force": true}' -H "Content-Type: application/json" -X POST http://localhost:9871/v1/containerbuild +# image build +curl -d '{"imageNames": ["rocky-8"], "force": true}' -H "Content-Type: application/json" -X POST http://localhost:9871/v1/imagebuild # node list all curl http://localhost:9871/v1/node diff --git a/internal/app/wwctl/completions/completions.go b/internal/app/wwctl/completions/completions.go index d2383fd2..2dfbb2fa 100644 --- a/internal/app/wwctl/completions/completions.go +++ b/internal/app/wwctl/completions/completions.go @@ -3,8 +3,8 @@ package completions import ( "github.com/spf13/cobra" - "github.com/warewulf/warewulf/internal/pkg/container" "github.com/warewulf/warewulf/internal/pkg/hostlist" + "github.com/warewulf/warewulf/internal/pkg/image" "github.com/warewulf/warewulf/internal/pkg/kernel" "github.com/warewulf/warewulf/internal/pkg/node" ) @@ -19,8 +19,8 @@ func NodeKernelVersion(cmd *cobra.Command, args []string, toComplete string) ([] for _, id := range nodes { if node_, err := registry.GetNode(id); err != nil { continue - } else if node_.ContainerName != "" { - kernels := kernel.FindKernels(node_.ContainerName) + } else if node_.ImageName != "" { + kernels := kernel.FindKernels(node_.ImageName) for _, kernel_ := range kernels { kernelVersions = append(kernelVersions, kernel_.Version(), kernel_.Path) } @@ -38,8 +38,8 @@ func ProfileKernelVersion(cmd *cobra.Command, args []string, toComplete string) for _, id := range args { if profile, err := registry.GetProfile(id); err != nil { continue - } else if profile.ContainerName != "" { - kernels := kernel.FindKernels(profile.ContainerName) + } else if profile.ImageName != "" { + kernels := kernel.FindKernels(profile.ImageName) for _, kernel_ := range kernels { kernelVersions = append(kernelVersions, kernel_.Version(), kernel_.Path) } @@ -48,7 +48,7 @@ func ProfileKernelVersion(cmd *cobra.Command, args []string, toComplete string) return kernelVersions, cobra.ShellCompDirectiveNoFileComp } -func Containers(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - sources, _ := container.ListSources() +func Images(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + sources, _ := image.ListSources() return sources, cobra.ShellCompDirectiveNoFileComp } diff --git a/internal/app/wwctl/container/build/build_test.go b/internal/app/wwctl/container/build/build_test.go deleted file mode 100644 index 8da2b3f1..00000000 --- a/internal/app/wwctl/container/build/build_test.go +++ /dev/null @@ -1,20 +0,0 @@ -package build - -import ( - "testing" -) - -// TestArgsContainerBuild is a regression test for 215. -func TestArgsContainerBuild(t *testing.T) { - command := GetCommand() - - err := command.Args(command, []string{}) - if err != nil { - t.Errorf("no arguments to container build should succeed.") - } - - err = command.Args(command, []string{"container1", "container2"}) - if err != nil { - t.Errorf("multiple arguments to container build should succeed.") - } -} diff --git a/internal/app/wwctl/container/build/main.go b/internal/app/wwctl/container/build/main.go deleted file mode 100644 index c9b059d9..00000000 --- a/internal/app/wwctl/container/build/main.go +++ /dev/null @@ -1,16 +0,0 @@ -package build - -import ( - "github.com/spf13/cobra" - "github.com/warewulf/warewulf/internal/pkg/api/container" - "github.com/warewulf/warewulf/internal/pkg/api/routes/wwapiv1" -) - -func CobraRunE(cmd *cobra.Command, args []string) error { - cbp := &wwapiv1.ContainerBuildParameter{ - ContainerNames: args, - Force: BuildForce, - All: BuildAll, - } - return container.ContainerBuild(cbp) -} diff --git a/internal/app/wwctl/container/copy/main.go b/internal/app/wwctl/container/copy/main.go deleted file mode 100644 index 1f23909d..00000000 --- a/internal/app/wwctl/container/copy/main.go +++ /dev/null @@ -1,50 +0,0 @@ -package copy - -import ( - "fmt" - - "github.com/spf13/cobra" - "github.com/warewulf/warewulf/internal/pkg/api/routes/wwapiv1" - "github.com/warewulf/warewulf/internal/pkg/container" - "github.com/warewulf/warewulf/internal/pkg/wwlog" -) - -func CobraRunE(cmd *cobra.Command, args []string) (err error) { - - if len(args) > 2 { - wwlog.Warn("copy only requires 2 arguments but you provided %d arguments. Hence, they will be ignored.", len(args)) - } - - cdp := &wwapiv1.ContainerCopyParameter{ - ContainerSource: args[0], - ContainerDestination: args[1], - Build: Build, - } - - if !container.DoesSourceExist(cdp.ContainerSource) { - return fmt.Errorf("container's source doesn't exists: %s", cdp.ContainerSource) - } - - if !container.ValidName(cdp.ContainerDestination) { - return fmt.Errorf("container name contains illegal characters : %s", cdp.ContainerDestination) - } - - if container.DoesSourceExist(cdp.ContainerDestination) { - return fmt.Errorf("an other container with name: %s already exists in sources", cdp.ContainerDestination) - } - - err = container.Duplicate(cdp.ContainerSource, cdp.ContainerDestination) - if err != nil { - return fmt.Errorf("could not duplicate image: %s", err.Error()) - } - - if cdp.Build { - err = container.Build(cdp.ContainerDestination, true) - if err != nil { - return err - } - } - - wwlog.Info("Container %s successfully duplicated as %s", cdp.ContainerSource, cdp.ContainerDestination) - return -} diff --git a/internal/app/wwctl/container/list/main.go b/internal/app/wwctl/container/list/main.go deleted file mode 100644 index de4b4816..00000000 --- a/internal/app/wwctl/container/list/main.go +++ /dev/null @@ -1,84 +0,0 @@ -package list - -import ( - "strconv" - "time" - - "github.com/spf13/cobra" - - "github.com/warewulf/warewulf/internal/app/wwctl/table" - apicontainer "github.com/warewulf/warewulf/internal/pkg/api/container" - "github.com/warewulf/warewulf/internal/pkg/container" - "github.com/warewulf/warewulf/internal/pkg/util" -) - -var containerList = apicontainer.ContainerList - -func CobraRunE(vars *variables) func(cmd *cobra.Command, args []string) (err error) { - return func(cmd *cobra.Command, args []string) (err error) { - t := table.New(cmd.OutOrStdout()) - showSize := vars.size || vars.chroot || vars.compressed - if showSize || vars.full || vars.kernel { - containerInfo, err := containerList() - if err != nil { - return err - } - if vars.full { - t.AddHeader("CONTAINER NAME", "NODES", "KERNEL VERSION", "CREATION TIME", "MODIFICATION TIME", "SIZE") - for i := 0; i < len(containerInfo); i++ { - createTime := time.Unix(int64(containerInfo[i].CreateDate), 0) - modTime := time.Unix(int64(containerInfo[i].ModDate), 0) - sz := util.ByteToString(int64(containerInfo[i].ImgSize)) - if vars.compressed { - sz = util.ByteToString(int64(containerInfo[i].ImgSizeComp)) - } - if vars.chroot { - sz = util.ByteToString(int64(containerInfo[i].Size)) - } - t.AddLine( - containerInfo[i].Name, - strconv.FormatUint(uint64(containerInfo[i].NodeCount), 10), - containerInfo[i].KernelVersion, - createTime.Format(time.RFC822), - modTime.Format(time.RFC822), - sz, - ) - } - } else if vars.kernel { - t.AddHeader("CONTAINER NAME", "NODES", "KERNEL VERSION") - for i := 0; i < len(containerInfo); i++ { - t.AddLine( - containerInfo[i].Name, - strconv.FormatUint(uint64(containerInfo[i].NodeCount), 10), - containerInfo[i].KernelVersion, - ) - } - } else if showSize { - t.AddHeader("CONTAINER NAME", "NODES", "SIZE") - for i := 0; i < len(containerInfo); i++ { - sz := util.ByteToString(int64(containerInfo[i].ImgSize)) - if vars.compressed { - sz = util.ByteToString(int64(containerInfo[i].ImgSizeComp)) - } - if vars.chroot { - sz = util.ByteToString(int64(containerInfo[i].Size)) - } - - t.AddLine( - containerInfo[i].Name, - strconv.FormatUint(uint64(containerInfo[i].NodeCount), 10), - sz, - ) - } - } - } else { - t.AddHeader("CONTAINER NAME") - list, _ := container.ListSources() - for _, cont := range list { - t.AddLine(cont) - } - } - t.Print() - return - } -} diff --git a/internal/app/wwctl/container/rename/main.go b/internal/app/wwctl/container/rename/main.go deleted file mode 100644 index 3d6ec583..00000000 --- a/internal/app/wwctl/container/rename/main.go +++ /dev/null @@ -1,44 +0,0 @@ -package rename - -import ( - "fmt" - - "github.com/spf13/cobra" - api "github.com/warewulf/warewulf/internal/pkg/api/container" - "github.com/warewulf/warewulf/internal/pkg/api/routes/wwapiv1" - "github.com/warewulf/warewulf/internal/pkg/container" - "github.com/warewulf/warewulf/internal/pkg/wwlog" -) - -func CobraRunE(cmd *cobra.Command, args []string) (err error) { - if len(args) != 2 { - return fmt.Errorf("rename requires 2 arguments: %d provided", len(args)) - } - - crp := &wwapiv1.ContainerRenameParameter{ - ContainerName: args[0], - TargetName: args[1], - Build: SetBuild, - } - - if !container.DoesSourceExist(crp.ContainerName) { - return fmt.Errorf("%s source dir does not exist", crp.ContainerName) - } - - if container.DoesSourceExist(crp.TargetName) { - return fmt.Errorf("an other container with the name %s already exists", crp.TargetName) - } - - if !container.ValidName(crp.TargetName) { - return fmt.Errorf("container name contains illegal characters : %s", crp.TargetName) - } - - err = api.ContainerRename(crp) - if err != nil { - err = fmt.Errorf("could not rename image: %s", err.Error()) - return - } - - wwlog.Info("Container %s successfully renamed as %s", crp.ContainerName, crp.TargetName) - return -} diff --git a/internal/app/wwctl/container/root.go b/internal/app/wwctl/container/root.go deleted file mode 100644 index d806c28b..00000000 --- a/internal/app/wwctl/container/root.go +++ /dev/null @@ -1,45 +0,0 @@ -package container - -import ( - "github.com/spf13/cobra" - "github.com/warewulf/warewulf/internal/app/wwctl/container/build" - "github.com/warewulf/warewulf/internal/app/wwctl/container/copy" - "github.com/warewulf/warewulf/internal/app/wwctl/container/delete" - "github.com/warewulf/warewulf/internal/app/wwctl/container/exec" - "github.com/warewulf/warewulf/internal/app/wwctl/container/imprt" - "github.com/warewulf/warewulf/internal/app/wwctl/container/kernels" - "github.com/warewulf/warewulf/internal/app/wwctl/container/list" - "github.com/warewulf/warewulf/internal/app/wwctl/container/rename" - "github.com/warewulf/warewulf/internal/app/wwctl/container/shell" - "github.com/warewulf/warewulf/internal/app/wwctl/container/show" - "github.com/warewulf/warewulf/internal/app/wwctl/container/syncuser" -) - -var baseCmd = &cobra.Command{ - DisableFlagsInUseLine: true, - Use: "container COMMAND [OPTIONS]", - Short: "Container / VNFS image management", - Long: "Starting with version 4, Warewulf uses containers to build the bootable VNFS\n" + - "node images. These commands will help you import, manage, and transform\n" + - "containers into bootable Warewulf VNFS images.", - Aliases: []string{"vnfs"}, -} - -func init() { - baseCmd.AddCommand(build.GetCommand()) - baseCmd.AddCommand(list.GetCommand()) - baseCmd.AddCommand(imprt.GetCommand()) - baseCmd.AddCommand(exec.GetCommand()) - baseCmd.AddCommand(shell.GetCommand()) - baseCmd.AddCommand(delete.GetCommand()) - baseCmd.AddCommand(show.GetCommand()) - baseCmd.AddCommand(syncuser.GetCommand()) - baseCmd.AddCommand(copy.GetCommand()) - baseCmd.AddCommand(rename.GetCommand()) - baseCmd.AddCommand(kernels.GetCommand()) -} - -// GetRootCommand returns the root cobra.Command for the application. -func GetCommand() *cobra.Command { - return baseCmd -} diff --git a/internal/app/wwctl/container/syncuser/main.go b/internal/app/wwctl/container/syncuser/main.go deleted file mode 100644 index 92bf4ea2..00000000 --- a/internal/app/wwctl/container/syncuser/main.go +++ /dev/null @@ -1,40 +0,0 @@ -package syncuser - -import ( - "fmt" - - "github.com/spf13/cobra" - container_build "github.com/warewulf/warewulf/internal/pkg/api/container" - "github.com/warewulf/warewulf/internal/pkg/api/routes/wwapiv1" - "github.com/warewulf/warewulf/internal/pkg/container" - "github.com/warewulf/warewulf/internal/pkg/wwlog" -) - -func CobraRunE(cmd *cobra.Command, args []string) error { - containerName := args[0] - if !container.ValidName(containerName) { - return fmt.Errorf("%s is not a valid container", containerName) - } - err := container.SyncUids(containerName, write) - if err != nil { - return fmt.Errorf("error in synchronize: %s", err) - } - - if write && !build { - // when write = true and build = false, we will print a warnning, this is the default case - wwlog.Warn("Syncuser is completed, please remember to rebuild container or add `--build` flag for automatic rebuild after syncuser") - } else if write && build { - // if write = true and build = true, then it'll trigger the container build after sync - cbp := &wwapiv1.ContainerBuildParameter{ - ContainerNames: []string{containerName}, - Force: true, - All: false, - } - err := container_build.ContainerBuild(cbp) - if err != nil { - return fmt.Errorf("error during container build: %s", err) - } - } - - return nil -} diff --git a/internal/app/wwctl/flags/flags.go b/internal/app/wwctl/flags/flags.go new file mode 100644 index 00000000..30e2596b --- /dev/null +++ b/internal/app/wwctl/flags/flags.go @@ -0,0 +1,10 @@ +package flags + +import ( + "github.com/spf13/cobra" +) + +func AddContainer(cmd *cobra.Command, dest *string) { + cmd.Flags().StringVarP(dest, "container", "C", "", "Set image name (backwards-compatibility)") + cmd.Flags().Lookup("container").Hidden = true +} diff --git a/internal/app/wwctl/image/build/build_test.go b/internal/app/wwctl/image/build/build_test.go new file mode 100644 index 00000000..1fe91c28 --- /dev/null +++ b/internal/app/wwctl/image/build/build_test.go @@ -0,0 +1,20 @@ +package build + +import ( + "testing" +) + +// TestArgsImageBuild is a regression test for 215. +func TestArgsImageBuild(t *testing.T) { + command := GetCommand() + + err := command.Args(command, []string{}) + if err != nil { + t.Errorf("no arguments to image build should succeed.") + } + + err = command.Args(command, []string{"image1", "image2"}) + if err != nil { + t.Errorf("multiple arguments to image build should succeed.") + } +} diff --git a/internal/app/wwctl/image/build/main.go b/internal/app/wwctl/image/build/main.go new file mode 100644 index 00000000..e0ea2e34 --- /dev/null +++ b/internal/app/wwctl/image/build/main.go @@ -0,0 +1,16 @@ +package build + +import ( + "github.com/spf13/cobra" + "github.com/warewulf/warewulf/internal/pkg/api/image" + "github.com/warewulf/warewulf/internal/pkg/api/routes/wwapiv1" +) + +func CobraRunE(cmd *cobra.Command, args []string) error { + cbp := &wwapiv1.ImageBuildParameter{ + ImageNames: args, + Force: BuildForce, + All: BuildAll, + } + return image.ImageBuild(cbp) +} diff --git a/internal/app/wwctl/container/build/root.go b/internal/app/wwctl/image/build/root.go similarity index 68% rename from internal/app/wwctl/container/build/root.go rename to internal/app/wwctl/image/build/root.go index d0e5fe24..c66aff54 100644 --- a/internal/app/wwctl/container/build/root.go +++ b/internal/app/wwctl/image/build/root.go @@ -2,22 +2,22 @@ package build import ( "github.com/spf13/cobra" - "github.com/warewulf/warewulf/internal/pkg/container" + "github.com/warewulf/warewulf/internal/pkg/image" ) var ( baseCmd = &cobra.Command{ DisableFlagsInUseLine: true, - Use: "build [OPTIONS] CONTAINER [...]", - Short: "(Re)build a bootable VNFS image", - Long: "This command will build a bootable VNFS image from imported CONTAINER image(s).", + Use: "build [OPTIONS] IMAGE [...]", + Short: "(Re)build a bootable image", + Long: "This command will build a bootable image from an imported IMAGE(s).", RunE: CobraRunE, Args: cobra.ArbitraryArgs, ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { if len(args) != 0 { return nil, cobra.ShellCompDirectiveNoFileComp } - list, _ := container.ListSources() + list, _ := image.ListSources() return list, cobra.ShellCompDirectiveNoFileComp }, } @@ -26,7 +26,7 @@ var ( ) func init() { - baseCmd.PersistentFlags().BoolVarP(&BuildAll, "all", "a", false, "(re)Build all VNFS images for all nodes") + baseCmd.PersistentFlags().BoolVarP(&BuildAll, "all", "a", false, "(re)Build all images") baseCmd.PersistentFlags().BoolVarP(&BuildForce, "force", "f", false, "Force rebuild, even if it isn't necessary") } diff --git a/internal/app/wwctl/image/copy/main.go b/internal/app/wwctl/image/copy/main.go new file mode 100644 index 00000000..83bc2ff2 --- /dev/null +++ b/internal/app/wwctl/image/copy/main.go @@ -0,0 +1,50 @@ +package copy + +import ( + "fmt" + + "github.com/spf13/cobra" + "github.com/warewulf/warewulf/internal/pkg/api/routes/wwapiv1" + "github.com/warewulf/warewulf/internal/pkg/image" + "github.com/warewulf/warewulf/internal/pkg/wwlog" +) + +func CobraRunE(cmd *cobra.Command, args []string) (err error) { + + if len(args) > 2 { + wwlog.Warn("copy only requires 2 arguments but you provided %d arguments. Hence, they will be ignored.", len(args)) + } + + cdp := &wwapiv1.ImageCopyParameter{ + ImageSource: args[0], + ImageDestination: args[1], + Build: Build, + } + + if !image.DoesSourceExist(cdp.ImageSource) { + return fmt.Errorf("image's source doesn't exists: %s", cdp.ImageSource) + } + + if !image.ValidName(cdp.ImageDestination) { + return fmt.Errorf("image name contains illegal characters : %s", cdp.ImageDestination) + } + + if image.DoesSourceExist(cdp.ImageDestination) { + return fmt.Errorf("an other image with name: %s already exists in sources", cdp.ImageDestination) + } + + err = image.Duplicate(cdp.ImageSource, cdp.ImageDestination) + if err != nil { + return fmt.Errorf("could not duplicate image: %s", err.Error()) + } + + if cdp.Build { + err = image.Build(cdp.ImageDestination, true) + if err != nil { + return err + } + } + + wwlog.Info("Image %s successfully duplicated as %s", cdp.ImageSource, cdp.ImageDestination) + return +} diff --git a/internal/app/wwctl/container/copy/main_test.go b/internal/app/wwctl/image/copy/main_test.go similarity index 55% rename from internal/app/wwctl/container/copy/main_test.go rename to internal/app/wwctl/image/copy/main_test.go index cb6a3e74..9784a12c 100644 --- a/internal/app/wwctl/container/copy/main_test.go +++ b/internal/app/wwctl/image/copy/main_test.go @@ -11,23 +11,23 @@ import ( func Test_Copy(t *testing.T) { env := testenv.New(t) - env.WriteFile(path.Join(testenv.WWChrootdir, "test-container/rootfs/bin/sh"), `test`) + env.WriteFile(path.Join(testenv.WWChrootdir, "test-image/rootfs/bin/sh"), `test`) defer env.RemoveAll() warewulfd.SetNoDaemon() - t.Run("container copy without build", func(t *testing.T) { + t.Run("image copy without build", func(t *testing.T) { baseCmd := GetCommand() - baseCmd.SetArgs([]string{"test-container", "test-container-copy-without-build"}) + baseCmd.SetArgs([]string{"test-image", "test-image-copy-without-build"}) err := baseCmd.Execute() assert.NoError(t, err) - assert.NoFileExists(t, path.Join(env.BaseDir, testenv.WWProvisiondir, "container", "test-container-copy-without-build.img")) + assert.NoFileExists(t, path.Join(env.BaseDir, testenv.WWProvisiondir, "image", "test-image-copy-without-build.img")) }) - t.Run("container copy with build", func(t *testing.T) { + t.Run("image copy with build", func(t *testing.T) { baseCmd := GetCommand() - baseCmd.SetArgs([]string{"-b", "test-container", "test-container-copy"}) + baseCmd.SetArgs([]string{"-b", "test-image", "test-image-copy"}) err := baseCmd.Execute() assert.NoError(t, err) - assert.FileExists(t, path.Join(env.BaseDir, testenv.WWProvisiondir, "container", "test-container-copy.img")) + assert.FileExists(t, path.Join(env.BaseDir, testenv.WWProvisiondir, "image", "test-image-copy.img")) }) } diff --git a/internal/app/wwctl/container/copy/root.go b/internal/app/wwctl/image/copy/root.go similarity index 75% rename from internal/app/wwctl/container/copy/root.go rename to internal/app/wwctl/image/copy/root.go index d717c262..009c33d6 100644 --- a/internal/app/wwctl/container/copy/root.go +++ b/internal/app/wwctl/image/copy/root.go @@ -2,23 +2,23 @@ package copy import ( "github.com/spf13/cobra" - "github.com/warewulf/warewulf/internal/pkg/container" + "github.com/warewulf/warewulf/internal/pkg/image" ) var ( baseCmd = &cobra.Command{ DisableFlagsInUseLine: true, - Use: "copy CONTAINER NEW_NAME", + Use: "copy IMAGE NEW_NAME", Aliases: []string{"cp"}, - Short: "Copy an existing container", - Long: "This command will duplicate an imported container image.", + Short: "Copy an existing image", + Long: "This command will duplicate an imported image.", RunE: CobraRunE, Args: cobra.MinimumNArgs(2), ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { if len(args) != 0 { return nil, cobra.ShellCompDirectiveNoFileComp } - list, _ := container.ListSources() + list, _ := image.ListSources() return list, cobra.ShellCompDirectiveNoFileComp }, } @@ -26,7 +26,7 @@ var ( ) func init() { - baseCmd.PersistentFlags().BoolVarP(&Build, "build", "b", false, "Build container after copy") + baseCmd.PersistentFlags().BoolVarP(&Build, "build", "b", false, "Build image after copy") } // GetRootCommand returns the root cobra.Command for the application. diff --git a/internal/app/wwctl/container/delete/main.go b/internal/app/wwctl/image/delete/main.go similarity index 64% rename from internal/app/wwctl/container/delete/main.go rename to internal/app/wwctl/image/delete/main.go index ffcbd7e8..e869ac31 100644 --- a/internal/app/wwctl/container/delete/main.go +++ b/internal/app/wwctl/image/delete/main.go @@ -3,7 +3,7 @@ package delete import ( "fmt" - "github.com/warewulf/warewulf/internal/pkg/api/container" + "github.com/warewulf/warewulf/internal/pkg/api/image" "github.com/warewulf/warewulf/internal/pkg/api/routes/wwapiv1" apiutil "github.com/warewulf/warewulf/internal/pkg/api/util" @@ -11,16 +11,16 @@ import ( ) func CobraRunE(cmd *cobra.Command, args []string) (err error) { - cdp := &wwapiv1.ContainerDeleteParameter{ - ContainerNames: args, + cdp := &wwapiv1.ImageDeleteParameter{ + ImageNames: args, } if !SetYes { - yes := apiutil.ConfirmationPrompt(fmt.Sprintf("Are you sure you want to delete container %s", args)) + yes := apiutil.ConfirmationPrompt(fmt.Sprintf("Are you sure you want to delete image %s", args)) if !yes { return } } - return container.ContainerDelete(cdp) + return image.ImageDelete(cdp) } diff --git a/internal/app/wwctl/container/delete/root.go b/internal/app/wwctl/image/delete/root.go similarity index 69% rename from internal/app/wwctl/container/delete/root.go rename to internal/app/wwctl/image/delete/root.go index 4a9d7649..7fd1efb3 100644 --- a/internal/app/wwctl/container/delete/root.go +++ b/internal/app/wwctl/image/delete/root.go @@ -2,22 +2,22 @@ package delete import ( "github.com/spf13/cobra" - "github.com/warewulf/warewulf/internal/pkg/container" + "github.com/warewulf/warewulf/internal/pkg/image" ) var ( baseCmd = &cobra.Command{ DisableFlagsInUseLine: true, - Use: "delete [OPTIONS] CONTAINER [...]", + Use: "delete [OPTIONS] IMAGE [...]", Aliases: []string{"rm", "remove", "del"}, - Short: "Delete an imported container", - Long: "This command will delete CONTAINERs that have been imported into Warewulf.", + Short: "Delete an imported image", + Long: "This command will delete IMAGEs that have been imported into Warewulf.", RunE: CobraRunE, ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { if len(args) != 0 { return nil, cobra.ShellCompDirectiveNoFileComp } - list, _ := container.ListSources() + list, _ := image.ListSources() return list, cobra.ShellCompDirectiveNoFileComp }, } diff --git a/internal/app/wwctl/container/exec/child/main.go b/internal/app/wwctl/image/exec/child/main.go similarity index 68% rename from internal/app/wwctl/container/exec/child/main.go rename to internal/app/wwctl/image/exec/child/main.go index 7847616d..64e105b2 100644 --- a/internal/app/wwctl/container/exec/child/main.go +++ b/internal/app/wwctl/image/exec/child/main.go @@ -13,7 +13,7 @@ import ( "github.com/spf13/cobra" warewulfconf "github.com/warewulf/warewulf/internal/pkg/config" - "github.com/warewulf/warewulf/internal/pkg/container" + "github.com/warewulf/warewulf/internal/pkg/image" "github.com/warewulf/warewulf/internal/pkg/node" "github.com/warewulf/warewulf/internal/pkg/overlay" "github.com/warewulf/warewulf/internal/pkg/util" @@ -27,20 +27,20 @@ func CobraRunE(cmd *cobra.Command, args []string) (err error) { return fmt.Errorf("PID is not 1: %d", os.Getpid()) } - containerName := args[0] + imageName := args[0] - if !container.ValidSource(containerName) { - return fmt.Errorf("unknown Warewulf container: %s", containerName) + if !image.ValidSource(imageName) { + return fmt.Errorf("unknown Warewulf image: %s", imageName) } conf := warewulfconf.Get() - runDir := container.RunDir(containerName) + runDir := image.RunDir(imageName) if _, err := os.Stat(runDir); os.IsNotExist(err) { - return fmt.Errorf("container run directory does not exist: %w", err) + return fmt.Errorf("image run directory does not exist: %w", err) } - mountPts := conf.MountsContainer - mountPts = append(container.InitMountPnts(binds), mountPts...) + mountPts := conf.MountsImage + mountPts = append(image.InitMountPnts(binds), mountPts...) // check for valid mount points - lowerObjects := checkMountPoints(containerName, mountPts) + lowerObjects := checkMountPoints(imageName, mountPts) // need to create a overlay, where the lower layer contains // the missing mount points wwlog.Verbose("for ephermal mount use tempdir %s", runDir) @@ -72,18 +72,18 @@ func CobraRunE(cmd *cobra.Command, args []string) (err error) { defer desc.Close() } } - containerPath := container.RootFsDir(containerName) + imagePath := image.RootFsDir(imageName) // running in a private PID space, so also make / private, so that nothing gets out from here err = syscall.Mount("", "/", "", syscall.MS_PRIVATE|syscall.MS_REC, "") if err != nil { return fmt.Errorf("failed to mount: %w", err) } - ps1Str := fmt.Sprintf("[%s|%s] Warewulf> ", containerName, exitEval) + ps1Str := fmt.Sprintf("[%s|%s] Warewulf> ", imageName, exitEval) if len(lowerObjects) != 0 && nodename == "" { options := fmt.Sprintf("lowerdir=%s,upperdir=%s,workdir=%s", - path.Join(runDir, "lower"), containerPath, path.Join(runDir, "work")) + path.Join(runDir, "lower"), imagePath, path.Join(runDir, "work")) wwlog.Debug("overlay options: %s", options) - err = syscall.Mount("overlay", containerPath, "overlay", 0, options) + err = syscall.Mount("overlay", imagePath, "overlay", 0, options) if err != nil { wwlog.Warn("Couldn't create overlay for ephermal mount points: %s", err) } @@ -108,22 +108,22 @@ func CobraRunE(cmd *cobra.Command, args []string) (err error) { return fmt.Errorf("could not build overlay: %s", err) } options := fmt.Sprintf("lowerdir=%s:%s:%s", - path.Join(runDir, "lower"), containerPath, path.Join(runDir, "nodeoverlay")) + path.Join(runDir, "lower"), imagePath, path.Join(runDir, "nodeoverlay")) wwlog.Debug("overlay options: %s", options) - err = syscall.Mount("overlay", containerPath, "overlay", 0, options) + err = syscall.Mount("overlay", imagePath, "overlay", 0, options) if err != nil { return fmt.Errorf("Couldn't create overlay for node render overlay: %s", err) } - ps1Str = fmt.Sprintf("[%s|ro|%s] Warewulf> ", containerName, nodename) + ps1Str = fmt.Sprintf("[%s|ro|%s] Warewulf> ", imageName, nodename) } - if !container.IsWriteAble(containerName) && nodename == "" { - wwlog.Verbose("mounting %s ro", containerPath) - ps1Str = fmt.Sprintf("[%s|ro] Warewulf> ", containerName) - err = syscall.Mount(containerPath, containerPath, "", syscall.MS_BIND, "") + if !image.IsWriteAble(imageName) && nodename == "" { + wwlog.Verbose("mounting %s ro", imagePath) + ps1Str = fmt.Sprintf("[%s|ro] Warewulf> ", imageName) + err = syscall.Mount(imagePath, imagePath, "", syscall.MS_BIND, "") if err != nil { return fmt.Errorf("failed to prepare bind mount: %w", err) } - err = syscall.Mount(containerPath, containerPath, "", syscall.MS_REMOUNT|syscall.MS_RDONLY|syscall.MS_BIND, "") + err = syscall.Mount(imagePath, imagePath, "", syscall.MS_REMOUNT|syscall.MS_RDONLY|syscall.MS_BIND, "") if err != nil { return fmt.Errorf("failed to remount ro: %w", err) } @@ -133,23 +133,23 @@ func CobraRunE(cmd *cobra.Command, args []string) (err error) { if mntPnt.Copy() { continue } - wwlog.Debug("bind mounting: %s -> %s", mntPnt.Source, path.Join(containerPath, mntPnt.Dest)) - err = syscall.Mount(mntPnt.Source, path.Join(containerPath, mntPnt.Dest), "", syscall.MS_BIND, "") + wwlog.Debug("bind mounting: %s -> %s", mntPnt.Source, path.Join(imagePath, mntPnt.Dest)) + err = syscall.Mount(mntPnt.Source, path.Join(imagePath, mntPnt.Dest), "", syscall.MS_BIND, "") if err != nil { wwlog.Warn("Couldn't mount %s to %s: %s", mntPnt.Source, mntPnt.Dest, err) } else if mntPnt.ReadOnly() { - err = syscall.Mount(mntPnt.Source, path.Join(containerPath, mntPnt.Dest), "", syscall.MS_REMOUNT|syscall.MS_RDONLY|syscall.MS_BIND, "") + err = syscall.Mount(mntPnt.Source, path.Join(imagePath, mntPnt.Dest), "", syscall.MS_REMOUNT|syscall.MS_RDONLY|syscall.MS_BIND, "") if err != nil { wwlog.Warn("failed to following mount readonly: %s", mntPnt.Source) } else { - wwlog.Verbose("mounted readonly from host to container: %s:%s", mntPnt.Source, mntPnt.Dest) + wwlog.Verbose("mounted readonly from host to image: %s:%s", mntPnt.Source, mntPnt.Dest) } } else { - wwlog.Verbose("mounted from host to container: %s:%s", mntPnt.Source, mntPnt.Dest) + wwlog.Verbose("mounted from host to image: %s:%s", mntPnt.Source, mntPnt.Dest) } } - err = syscall.Chroot(containerPath) + err = syscall.Chroot(imagePath) if err != nil { return fmt.Errorf("failed to chroot: %w", err) } @@ -181,10 +181,10 @@ func CobraRunE(cmd *cobra.Command, args []string) (err error) { } /* -Check if the bind mount points exists in the given container. Returns +Check if the bind mount points exists in the given image. Returns the invalid mount points. Directories always have '/' as suffix */ -func checkMountPoints(containerName string, binds []*warewulfconf.MountEntry) (overlayObjects []string) { +func checkMountPoints(imageName string, binds []*warewulfconf.MountEntry) (overlayObjects []string) { overlayObjects = []string{} for _, b := range binds { if b.Copy() { @@ -192,17 +192,17 @@ func checkMountPoints(containerName string, binds []*warewulfconf.MountEntry) (o } _, err := os.Stat(b.Source) if err != nil { - wwlog.Debug("Couldn't stat %s create no mount point in container", b.Source) + wwlog.Debug("Couldn't stat %s create no mount point in image", b.Source) continue } - wwlog.Debug("Checking in container for %s", path.Join(container.RootFsDir(containerName), b.Dest)) - if _, err = os.Stat(path.Join(container.RootFsDir(containerName), b.Dest)); err != nil { + wwlog.Debug("Checking in image for %s", path.Join(image.RootFsDir(imageName), b.Dest)) + if _, err = os.Stat(path.Join(image.RootFsDir(imageName), b.Dest)); err != nil { if os.IsNotExist(err) { if util.IsDir(b.Dest) && !strings.HasSuffix(b.Dest, "/") { b.Dest += "/" } overlayObjects = append(overlayObjects, b.Dest) - wwlog.Debug("Container %s, needs following path: %s", containerName, b.Dest) + wwlog.Debug("Image %s, needs following path: %s", imageName, b.Dest) } } } diff --git a/internal/app/wwctl/container/exec/child/non-Linux.go b/internal/app/wwctl/image/exec/child/non-Linux.go similarity index 100% rename from internal/app/wwctl/container/exec/child/non-Linux.go rename to internal/app/wwctl/image/exec/child/non-Linux.go diff --git a/internal/app/wwctl/container/exec/child/root.go b/internal/app/wwctl/image/exec/child/root.go similarity index 100% rename from internal/app/wwctl/container/exec/child/root.go rename to internal/app/wwctl/image/exec/child/root.go diff --git a/internal/app/wwctl/container/exec/main.go b/internal/app/wwctl/image/exec/main.go similarity index 59% rename from internal/app/wwctl/container/exec/main.go rename to internal/app/wwctl/image/exec/main.go index 51f2993f..495518c6 100644 --- a/internal/app/wwctl/container/exec/main.go +++ b/internal/app/wwctl/image/exec/main.go @@ -14,7 +14,7 @@ import ( warewulfconf "github.com/warewulf/warewulf/internal/pkg/config" "github.com/spf13/cobra" - "github.com/warewulf/warewulf/internal/pkg/container" + "github.com/warewulf/warewulf/internal/pkg/image" "github.com/warewulf/warewulf/internal/pkg/util" "github.com/warewulf/warewulf/internal/pkg/wwlog" ) @@ -33,15 +33,15 @@ func runChildCmd(cmd *cobra.Command, args []string) error { var childCommandFunc = runChildCmd // Fork a child process with a new PID space -func runContainedCmd(cmd *cobra.Command, containerName string, args []string) (err error) { +func runContainedCmd(cmd *cobra.Command, imageName string, args []string) (err error) { wwlog.Debug("runContainedCmd:args: %v", args) conf := warewulfconf.Get() - runDir := container.RunDir(containerName) + runDir := image.RunDir(imageName) if err := os.Mkdir(runDir, 0750); err != nil { if _, existerr := os.Stat(runDir); !os.IsNotExist(existerr) { - return fmt.Errorf("run directory already exists: another container command may already be running (otherwise, remove %s)", runDir) + return fmt.Errorf("run directory already exists: another image command may already be running (otherwise, remove %s)", runDir) } else { return fmt.Errorf("unable to create run directory: %w", err) } @@ -53,8 +53,8 @@ func runContainedCmd(cmd *cobra.Command, containerName string, args []string) (e }() logStr := fmt.Sprint(wwlog.GetLogLevel()) - childArgs := []string{"--warewulfconf", conf.GetWarewulfConf(), "--loglevel", logStr, "container", "exec", "__child"} - childArgs = append(childArgs, containerName) + childArgs := []string{"--warewulfconf", conf.GetWarewulfConf(), "--loglevel", logStr, "image", "exec", "__child"} + childArgs = append(childArgs, imageName) for _, b := range binds { childArgs = append(childArgs, "--bind", b) } @@ -63,27 +63,27 @@ func runContainedCmd(cmd *cobra.Command, containerName string, args []string) (e } childArgs = append(childArgs, "--") childArgs = append(childArgs, args...) - // copy the files into the container at this stage, es in __child the + // copy the files into the image at this stage, es in __child the // command syscall.Exec which replaces the __child process with the - // exec command in the container. All the mounts, have to be done in + // exec command in the image. All the mounts, have to be done in // __child so that the used mounts don't propagate outside on the host // (see the CLONE attributes), but as for the copy option we need - // to see if a file was modified after it was copied into the container + // to see if a file was modified after it was copied into the image // so do this here. // At first read out conf, the parse commandline, as copy files has the // same synatx as mount points - mountPts := append(container.InitMountPnts(binds), conf.MountsContainer...) + mountPts := append(image.InitMountPnts(binds), conf.MountsImage...) filesToCpy := getCopyFiles(mountPts) for _, cpyFile := range filesToCpy { - if err := (cpyFile).copyToContainer(containerName); err != nil { + if err := (cpyFile).copyToImage(imageName); err != nil { wwlog.Warn("couldn't copy file: %s", err) } } wwlog.Verbose("Running contained command: %s", childArgs) retVal := childCommandFunc(cmd, childArgs) for _, cpyFile := range filesToCpy { - if cpyFile.shouldRemoveFromContainer(containerName) { - if err := cpyFile.removeFromContainer(containerName); err != nil { + if cpyFile.shouldRemoveFromImage(imageName) { + if err := cpyFile.removeFromImage(imageName); err != nil { wwlog.Warn("couldn't remove file: %s", err) } } @@ -94,36 +94,40 @@ func runContainedCmd(cmd *cobra.Command, containerName string, args []string) (e func CobraRunE(cmd *cobra.Command, args []string) error { wwlog.Debug("CobraRunE:args: %v", args) - containerName := args[0] - wwlog.Debug("CobraRunE:containerName: %v", containerName) - if !container.ValidSource(containerName) { - return fmt.Errorf("unknown Warewulf container: %s", containerName) + imageName := args[0] + wwlog.Debug("CobraRunE:imageName: %v", imageName) + if !image.ValidSource(imageName) { + return fmt.Errorf("unknown Warewulf image: %s", imageName) } - os.Setenv("WW_CONTAINER_SHELL", containerName) + os.Setenv("WW_CONTAINER_SHELL", imageName) + os.Setenv("WW_IMAGE_SHELL", imageName) - containerPath := container.RootFsDir(containerName) + imagePath := image.RootFsDir(imageName) - beforePasswdTime := getTime(path.Join(containerPath, "/etc/passwd")) + beforePasswdTime := getTime(path.Join(imagePath, "/etc/passwd")) wwlog.Debug("passwdTime: %v", beforePasswdTime) - beforeGroupTime := getTime(path.Join(containerPath, "/etc/group")) + beforeGroupTime := getTime(path.Join(imagePath, "/etc/group")) wwlog.Debug("groupTime: %v", beforeGroupTime) - err := runContainedCmd(cmd, containerName, args[1:]) + err := runContainedCmd(cmd, imageName, args[1:]) if err != nil { - return fmt.Errorf("failed executing container command: %s", err) + return fmt.Errorf("command returned an error: %v: %s", args[1:], err) } - if util.IsFile(path.Join(containerPath, "/etc/warewulf/container_exit.sh")) { - wwlog.Verbose("Found clean script: /etc/warewulf/container_exit.sh") - err = runContainedCmd(cmd, containerName, []string{"/bin/sh", "/etc/warewulf/container_exit.sh"}) - if err != nil { - return fmt.Errorf("failed executing exit script: %s", err) + for _, exitScript := range []string{"/etc/warewulf/image_exit.sh", "/etc/warewulf/container_exit.sh"} { + if util.IsFile(path.Join(imagePath, exitScript)) { + wwlog.Verbose("Found exit script: %s", exitScript) + err = runContainedCmd(cmd, imageName, []string{"/bin/sh", exitScript}) + if err != nil { + return fmt.Errorf("exit script returned an error: %v: %s", exitScript, err) + } + break } } userdbChanged := false if !beforePasswdTime.IsZero() { - afterPasswdTime := getTime(path.Join(containerPath, "/etc/passwd")) + afterPasswdTime := getTime(path.Join(imagePath, "/etc/passwd")) wwlog.Debug("passwdTime: %v", afterPasswdTime) if beforePasswdTime.Before(afterPasswdTime) { if !SyncUser { @@ -133,7 +137,7 @@ func CobraRunE(cmd *cobra.Command, args []string) error { } } if !beforeGroupTime.IsZero() { - afterGroupTime := getTime(path.Join(containerPath, "/etc/group")) + afterGroupTime := getTime(path.Join(imagePath, "/etc/group")) wwlog.Debug("groupTime: %v", afterGroupTime) if beforeGroupTime.Before(afterGroupTime) { if !SyncUser { @@ -143,17 +147,17 @@ func CobraRunE(cmd *cobra.Command, args []string) error { } } if userdbChanged && SyncUser { - err = container.SyncUids(containerName, false) + err = image.SyncUids(imageName, false) if err != nil { wwlog.Error("Error in user sync, fix error and run 'syncuser' manually: %s", err) } } if Build { - wwlog.Info("Building container image: %s", containerName) - err = container.Build(containerName, false) + wwlog.Info("Building image: %s", imageName) + err = image.Build(imageName, false) if err != nil { - return fmt.Errorf("could not build container image: %s: %s", containerName, err) + return fmt.Errorf("could not build image: %s: %s", imageName, err) } } return nil @@ -183,21 +187,21 @@ type copyFile struct { modTime time.Time } -func (this *copyFile) containerDest(containerName string) string { - return path.Join(container.RootFsDir(containerName), this.fileName) +func (this *copyFile) imageDest(imageName string) string { + return path.Join(image.RootFsDir(imageName), this.fileName) } -func (this *copyFile) copyToContainer(containerName string) error { - containerDest := this.containerDest(containerName) - if _, err := os.Stat(path.Dir(containerDest)); err != nil { +func (this *copyFile) copyToImage(imageName string) error { + imageDest := this.imageDest(imageName) + if _, err := os.Stat(path.Dir(imageDest)); err != nil { return err - } else if _, err := os.Stat(containerDest); err == nil { + } else if _, err := os.Stat(imageDest); err == nil { return err } else if _, err := os.Stat(this.src); err != nil { return err - } else if err := util.CopyFile(this.src, containerDest); err != nil { + } else if err := util.CopyFile(this.src, imageDest); err != nil { return err - } else if stat, err := os.Stat(containerDest); err != nil { + } else if stat, err := os.Stat(imageDest); err != nil { return err } else { this.modTime = stat.ModTime() @@ -205,12 +209,12 @@ func (this *copyFile) copyToContainer(containerName string) error { } } -func (this *copyFile) shouldRemoveFromContainer(containerName string) bool { - containerDest := this.containerDest(containerName) +func (this *copyFile) shouldRemoveFromImage(imageName string) bool { + imageDest := this.imageDest(imageName) if this.modTime.IsZero() { wwlog.Debug("file was not previously copied: %s", this.fileName) return false - } else if destStat, err := os.Stat(containerDest); err != nil { + } else if destStat, err := os.Stat(imageDest); err != nil { wwlog.Verbose("file is no longer present: %s (%s)", this.fileName, err) return false } else if destStat.ModTime() == this.modTime { @@ -221,9 +225,9 @@ func (this *copyFile) shouldRemoveFromContainer(containerName string) bool { } } -func (this *copyFile) removeFromContainer(containerName string) error { - containerDest := this.containerDest(containerName) - return os.Remove(containerDest) +func (this *copyFile) removeFromImage(imageName string) error { + imageDest := this.imageDest(imageName) + return os.Remove(imageDest) } /* diff --git a/internal/app/wwctl/container/exec/main_test.go b/internal/app/wwctl/image/exec/main_test.go similarity index 68% rename from internal/app/wwctl/container/exec/main_test.go rename to internal/app/wwctl/image/exec/main_test.go index 8c6b7954..4f7eb3af 100644 --- a/internal/app/wwctl/container/exec/main_test.go +++ b/internal/app/wwctl/image/exec/main_test.go @@ -40,37 +40,37 @@ func Test_Exec(t *testing.T) { { name: "plain test", args: []string{"test", "/bin/true"}, - stdout: `--loglevel 20 container exec __child test -- /bin/true`, + stdout: `--loglevel 20 image exec __child test -- /bin/true`, build: true, }, { name: "test with --bind", args: []string{"test", "--bind", "/tmp", "/bin/true"}, - stdout: `--loglevel 20 container exec __child test --bind /tmp -- /bin/true`, + stdout: `--loglevel 20 image exec __child test --bind /tmp -- /bin/true`, build: true, }, { name: "test with --node", args: []string{"test", "--node", "node1", "/bin/true"}, - stdout: `--loglevel 20 container exec __child test --node node1 -- /bin/true`, + stdout: `--loglevel 20 image exec __child test --node node1 -- /bin/true`, build: true, }, { name: "test with --build=false", args: []string{"test", "--build=false", "/bin/true"}, - stdout: `--loglevel 20 container exec __child test -- /bin/true`, + stdout: `--loglevel 20 image exec __child test -- /bin/true`, build: false, }, { name: "test with --node and --bind", args: []string{"test", "--bind", "/tmp", "--node", "node1", "/bin/true"}, - stdout: `--loglevel 20 container exec __child test --bind /tmp --node node1 -- /bin/true`, + stdout: `--loglevel 20 image exec __child test --bind /tmp --node node1 -- /bin/true`, build: true, }, { name: "test with complex command", args: []string{"test", "/bin/bash", "echo 'hello'"}, - stdout: `--loglevel 20 container exec __child test -- /bin/bash echo 'hello'`, + stdout: `--loglevel 20 image exec __child test -- /bin/bash echo 'hello'`, build: true, }, } @@ -82,8 +82,8 @@ func Test_Exec(t *testing.T) { nodeName = "" Build = true SyncUser = false - os.Remove(env.GetPath("/srv/warewulf/container/test.img")) - os.Remove(env.GetPath("/srv/warewulf/container/test.img.gz")) + os.Remove(env.GetPath("/srv/warewulf/image/test.img")) + os.Remove(env.GetPath("/srv/warewulf/image/test.img.gz")) }() cmd := GetCommand() cmd.SetArgs(tt.args) @@ -95,11 +95,11 @@ func Test_Exec(t *testing.T) { assert.NotEmpty(t, out.String()) assert.Contains(t, out.String(), tt.stdout) if tt.build { - assert.FileExists(t, env.GetPath("/srv/warewulf/container/test.img")) - assert.FileExists(t, env.GetPath("/srv/warewulf/container/test.img.gz")) + assert.FileExists(t, env.GetPath("/srv/warewulf/image/test.img")) + assert.FileExists(t, env.GetPath("/srv/warewulf/image/test.img.gz")) } else { - assert.NoFileExists(t, env.GetPath("/srv/warewulf/container/test.img")) - assert.NoFileExists(t, env.GetPath("/srv/warewulf/container/test.img.gz")) + assert.NoFileExists(t, env.GetPath("/srv/warewulf/image/test.img")) + assert.NoFileExists(t, env.GetPath("/srv/warewulf/image/test.img.gz")) } }) } diff --git a/internal/app/wwctl/container/exec/non-linux.go b/internal/app/wwctl/image/exec/non-linux.go similarity index 100% rename from internal/app/wwctl/container/exec/non-linux.go rename to internal/app/wwctl/image/exec/non-linux.go diff --git a/internal/app/wwctl/container/exec/root.go b/internal/app/wwctl/image/exec/root.go similarity index 63% rename from internal/app/wwctl/container/exec/root.go rename to internal/app/wwctl/image/exec/root.go index f5909878..8433586b 100644 --- a/internal/app/wwctl/container/exec/root.go +++ b/internal/app/wwctl/image/exec/root.go @@ -2,25 +2,25 @@ package exec import ( "github.com/spf13/cobra" - "github.com/warewulf/warewulf/internal/app/wwctl/container/exec/child" - "github.com/warewulf/warewulf/internal/pkg/container" + "github.com/warewulf/warewulf/internal/app/wwctl/image/exec/child" + "github.com/warewulf/warewulf/internal/pkg/image" ) var ( baseCmd = &cobra.Command{ DisableFlagsInUseLine: true, - Use: "exec [OPTIONS] CONTAINER COMMAND", - Short: "Run a command inside of a Warewulf container", - Long: "Run a COMMAND inside of a warewulf CONTAINER.\n" + + Use: "exec [OPTIONS] IMAGE COMMAND", + Short: "Run a command inside of a Warewulf image", + Long: "Run a COMMAND inside of a warewulf IMAGE.\n" + "This is commonly used with an interactive shell such as /bin/bash\n" + - "to run a virtual environment within the container.", + "to run a virtual environment within the image.", RunE: CobraRunE, Args: cobra.MinimumNArgs(2), ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { if len(args) != 0 { return nil, cobra.ShellCompDirectiveNoFileComp } - list, _ := container.ListSources() + list, _ := image.ListSources() return list, cobra.ShellCompDirectiveNoFileComp }, FParseErrWhitelist: cobra.FParseErrWhitelist{UnknownFlags: true}, @@ -34,12 +34,12 @@ var ( func init() { baseCmd.AddCommand(child.GetCommand()) baseCmd.PersistentFlags().StringArrayVarP(&binds, "bind", "b", []string{}, `source[:destination[:{ro|copy}]] -Bind a local path which must exist into the container. If destination is not +Bind a local path which must exist into the image. If destination is not set, uses the same path as source. "ro" binds read-only. "copy" temporarily -copies the file into the container.`) - baseCmd.PersistentFlags().BoolVar(&SyncUser, "syncuser", false, "Synchronize UIDs/GIDs from host to container") - baseCmd.PersistentFlags().BoolVar(&Build, "build", true, "(Re)build the container image automatically") - baseCmd.PersistentFlags().StringVarP(&nodeName, "node", "n", "", "Create a read only view of the container for the given node") +copies the file into the image.`) + baseCmd.PersistentFlags().BoolVar(&SyncUser, "syncuser", false, "Synchronize UIDs/GIDs from host to image") + baseCmd.PersistentFlags().BoolVar(&Build, "build", true, "(Re)build the image automatically") + baseCmd.PersistentFlags().StringVarP(&nodeName, "node", "n", "", "Create a read only view of the image for the given node") } // GetRootCommand returns the root cobra.Command for the application. diff --git a/internal/app/wwctl/container/imprt/main.go b/internal/app/wwctl/image/imprt/main.go similarity index 77% rename from internal/app/wwctl/container/imprt/main.go rename to internal/app/wwctl/image/imprt/main.go index af706a11..13b1bf1c 100644 --- a/internal/app/wwctl/container/imprt/main.go +++ b/internal/app/wwctl/image/imprt/main.go @@ -2,7 +2,7 @@ package imprt import ( "github.com/spf13/cobra" - apicontainer "github.com/warewulf/warewulf/internal/pkg/api/container" + apiimage "github.com/warewulf/warewulf/internal/pkg/api/image" "github.com/warewulf/warewulf/internal/pkg/api/routes/wwapiv1" ) @@ -14,7 +14,7 @@ func CobraRunE(cmd *cobra.Command, args []string) (err error) { name = args[1] } - cip := &wwapiv1.ContainerImportParameter{ + cip := &wwapiv1.ImageImportParameter{ Source: args[0], Name: name, Force: SetForce, @@ -27,6 +27,6 @@ func CobraRunE(cmd *cobra.Command, args []string) (err error) { Platform: Platform, } - _, err = apicontainer.ContainerImport(cip) + _, err = apiimage.ImageImport(cip) return } diff --git a/internal/app/wwctl/container/imprt/root.go b/internal/app/wwctl/image/imprt/root.go similarity index 82% rename from internal/app/wwctl/container/imprt/root.go rename to internal/app/wwctl/image/imprt/root.go index 2a22097f..3f7d0355 100644 --- a/internal/app/wwctl/container/imprt/root.go +++ b/internal/app/wwctl/image/imprt/root.go @@ -9,9 +9,9 @@ var ( baseCmd = &cobra.Command{ DisableFlagsInUseLine: true, Use: "import [OPTIONS] SOURCE [NAME]", - Short: "Import a container into Warewulf", + Short: "Import an image into Warewulf", Aliases: []string{"pull"}, - Long: `This command will pull and import a container into Warewulf from SOURCE, + Long: `This command will pull and import an image into Warewulf from SOURCE, optionally renaming it to NAME. The SOURCE must be in a supported URI format. Formats are: * docker://registry.example.org/example:latest @@ -19,8 +19,8 @@ are: * file://path/to/archive/tar/ball * /path/to/archive/tar/ball * /path/to/chroot/ -Imported containers are used to create bootable VNFS images.`, - Example: "wwctl container import docker://ghcr.io/warewulf/warewulf-rockylinux:8 rockylinux-8", +Imported images are used to create bootable images.`, + Example: "wwctl image import docker://ghcr.io/warewulf/warewulf-rockylinux:8 rockylinux-8", RunE: CobraRunE, Args: cobra.MinimumNArgs(1), PreRun: func(cmd *cobra.Command, args []string) { @@ -40,10 +40,10 @@ Imported containers are used to create bootable VNFS images.`, ) func init() { - baseCmd.PersistentFlags().BoolVarP(&SetForce, "force", "f", false, "Force overwrite of an existing container") - baseCmd.PersistentFlags().BoolVarP(&SetUpdate, "update", "u", false, "Update and overwrite an existing container") - baseCmd.PersistentFlags().BoolVarP(&SetBuild, "build", "b", false, "Build container after pulling") - baseCmd.PersistentFlags().BoolVar(&SyncUser, "syncuser", false, "Synchronize UIDs/GIDs from host to container") + baseCmd.PersistentFlags().BoolVarP(&SetForce, "force", "f", false, "Force overwrite of an existing image") + baseCmd.PersistentFlags().BoolVarP(&SetUpdate, "update", "u", false, "Update and overwrite an existing image") + baseCmd.PersistentFlags().BoolVarP(&SetBuild, "build", "b", false, "Build image after pulling") + baseCmd.PersistentFlags().BoolVar(&SyncUser, "syncuser", false, "Synchronize UIDs/GIDs from host to image") baseCmd.PersistentFlags().BoolVar(&OciNoHttps, "nohttps", false, "Ignore wrong TLS certificates, superseedes env WAREWULF_OCI_NOHTTPS") baseCmd.PersistentFlags().StringVar(&OciUsername, "username", "", "Set username for the access to the registry, superseedes env WAREWULF_OCI_USERNAME") baseCmd.PersistentFlags().StringVar(&OciPassword, "password", "", "Set password for the access to the registry, superseedes env WAREWULF_OCI_PASSWORD") diff --git a/internal/app/wwctl/container/kernels/main.go b/internal/app/wwctl/image/kernels/main.go similarity index 72% rename from internal/app/wwctl/container/kernels/main.go rename to internal/app/wwctl/image/kernels/main.go index 283682db..409d7395 100644 --- a/internal/app/wwctl/container/kernels/main.go +++ b/internal/app/wwctl/image/kernels/main.go @@ -6,7 +6,7 @@ import ( "github.com/spf13/cobra" "github.com/warewulf/warewulf/internal/app/wwctl/table" - "github.com/warewulf/warewulf/internal/pkg/container" + "github.com/warewulf/warewulf/internal/pkg/image" "github.com/warewulf/warewulf/internal/pkg/kernel" "github.com/warewulf/warewulf/internal/pkg/node" ) @@ -30,7 +30,7 @@ func CobraRunE(cmd *cobra.Command, args []string) error { var sources []string if len(args) == 0 { - if sources_, err := container.ListSources(); err == nil { + if sources_, err := image.ListSources(); err == nil { sources = sources_ } else { return err @@ -40,16 +40,16 @@ func CobraRunE(cmd *cobra.Command, args []string) error { } t := table.New(cmd.OutOrStdout()) - t.AddHeader("Container", "Kernel", "Version", "Default", "Nodes") + t.AddHeader("Image", "Kernel", "Version", "Default", "Nodes") for _, source := range sources { - containerKernels := kernel.FindKernels(source) - defaultKernel := containerKernels.Default() - for _, kernel_ := range containerKernels { + imageKernels := kernel.FindKernels(source) + defaultKernel := imageKernels.Default() + for _, kernel_ := range imageKernels { isDefault := defaultKernel != nil && defaultKernel == kernel_ defaultStr := strconv.FormatBool(isDefault) nodeCount := kernelNodes[*kernel_] if isDefault { - nodeCount = nodeCount + kernelNodes[kernel.Kernel{ContainerName: source, Path: ""}] + nodeCount = nodeCount + kernelNodes[kernel.Kernel{ImageName: source, Path: ""}] } t.AddLine(table.Prep([]string{source, kernel_.Path, kernel_.Version(), defaultStr, strconv.Itoa(nodeCount)})...) } diff --git a/internal/app/wwctl/container/kernels/main_test.go b/internal/app/wwctl/image/kernels/main_test.go similarity index 50% rename from internal/app/wwctl/container/kernels/main_test.go rename to internal/app/wwctl/image/kernels/main_test.go index ecbd520c..7d25c7c5 100644 --- a/internal/app/wwctl/container/kernels/main_test.go +++ b/internal/app/wwctl/image/kernels/main_test.go @@ -21,18 +21,18 @@ func Test_List(t *testing.T) { files: map[string][]string{}, args: []string{}, stdout: ` -Container Kernel Version Default Nodes ---------- ------ ------- ------- ----- +Image Kernel Version Default Nodes +----- ------ ------- ------- ----- `, }, "list": { files: map[string][]string{ - "container1": []string{ + "image1": []string{ "/boot/vmlinuz-5.14.0-427.18.1.el9_4.x86_64", "/boot/vmlinuz-5.14.0-427.24.1.el9_4.x86_64", "/boot/vmlinuz-4.14.0-427.18.1.el8_4.x86_64", }, - "container2": []string{ + "image2": []string{ "/boot/vmlinuz-0-rescue-eb46964329b146e39518c625feab3ea0", "/boot/vmlinuz-5.14.0-362.24.1.el9_3.aarch64", "/boot/vmlinuz-5.14.0-427.31.1.el9_4.aarch64+debug", @@ -42,26 +42,26 @@ Container Kernel Version Default Nodes }, args: []string{}, stdout: ` -Container Kernel Version Default Nodes ---------- ------ ------- ------- ----- -container1 /boot/vmlinuz-4.14.0-427.18.1.el8_4.x86_64 4.14.0-427.18.1 false 0 -container1 /boot/vmlinuz-5.14.0-427.18.1.el9_4.x86_64 5.14.0-427.18.1 false 0 -container1 /boot/vmlinuz-5.14.0-427.24.1.el9_4.x86_64 5.14.0-427.24.1 true 0 -container2 /boot/vmlinuz-0-rescue-eb46964329b146e39518c625feab3ea0 -- false 0 -container2 /boot/vmlinuz-5.14.0-284.30.1.el9_2.aarch64 5.14.0-284.30.1 false 0 -container2 /boot/vmlinuz-5.14.0-362.24.1.el9_3.aarch64 5.14.0-362.24.1 false 0 -container2 /boot/vmlinuz-5.14.0-427.31.1.el9_4.aarch64 5.14.0-427.31.1 true 0 -container2 /boot/vmlinuz-5.14.0-427.31.1.el9_4.aarch64+debug 5.14.0-427.31.1 false 0 +Image Kernel Version Default Nodes +----- ------ ------- ------- ----- +image1 /boot/vmlinuz-4.14.0-427.18.1.el8_4.x86_64 4.14.0-427.18.1 false 0 +image1 /boot/vmlinuz-5.14.0-427.18.1.el9_4.x86_64 5.14.0-427.18.1 false 0 +image1 /boot/vmlinuz-5.14.0-427.24.1.el9_4.x86_64 5.14.0-427.24.1 true 0 +image2 /boot/vmlinuz-0-rescue-eb46964329b146e39518c625feab3ea0 -- false 0 +image2 /boot/vmlinuz-5.14.0-284.30.1.el9_2.aarch64 5.14.0-284.30.1 false 0 +image2 /boot/vmlinuz-5.14.0-362.24.1.el9_3.aarch64 5.14.0-362.24.1 false 0 +image2 /boot/vmlinuz-5.14.0-427.31.1.el9_4.aarch64 5.14.0-427.31.1 true 0 +image2 /boot/vmlinuz-5.14.0-427.31.1.el9_4.aarch64+debug 5.14.0-427.31.1 false 0 `, }, - "single container": { + "single image": { files: map[string][]string{ - "container1": []string{ + "image1": []string{ "/boot/vmlinuz-5.14.0-427.18.1.el9_4.x86_64", "/boot/vmlinuz-5.14.0-427.24.1.el9_4.x86_64", "/boot/vmlinuz-4.14.0-427.18.1.el8_4.x86_64", }, - "container2": []string{ + "image2": []string{ "/boot/vmlinuz-0-rescue-eb46964329b146e39518c625feab3ea0", "/boot/vmlinuz-5.14.0-362.24.1.el9_3.aarch64", "/boot/vmlinuz-5.14.0-427.31.1.el9_4.aarch64+debug", @@ -69,15 +69,15 @@ container2 /boot/vmlinuz-5.14.0-427.31.1.el9_4.aarch64+debug 5.14.0-427. "/boot/vmlinuz-5.14.0-427.31.1.el9_4.aarch64", }, }, - args: []string{"container2"}, + args: []string{"image2"}, stdout: ` -Container Kernel Version Default Nodes ---------- ------ ------- ------- ----- -container2 /boot/vmlinuz-0-rescue-eb46964329b146e39518c625feab3ea0 -- false 0 -container2 /boot/vmlinuz-5.14.0-284.30.1.el9_2.aarch64 5.14.0-284.30.1 false 0 -container2 /boot/vmlinuz-5.14.0-362.24.1.el9_3.aarch64 5.14.0-362.24.1 false 0 -container2 /boot/vmlinuz-5.14.0-427.31.1.el9_4.aarch64 5.14.0-427.31.1 true 0 -container2 /boot/vmlinuz-5.14.0-427.31.1.el9_4.aarch64+debug 5.14.0-427.31.1 false 0 +Image Kernel Version Default Nodes +----- ------ ------- ------- ----- +image2 /boot/vmlinuz-0-rescue-eb46964329b146e39518c625feab3ea0 -- false 0 +image2 /boot/vmlinuz-5.14.0-284.30.1.el9_2.aarch64 5.14.0-284.30.1 false 0 +image2 /boot/vmlinuz-5.14.0-362.24.1.el9_3.aarch64 5.14.0-362.24.1 false 0 +image2 /boot/vmlinuz-5.14.0-427.31.1.el9_4.aarch64 5.14.0-427.31.1 true 0 +image2 /boot/vmlinuz-5.14.0-427.31.1.el9_4.aarch64+debug 5.14.0-427.31.1 false 0 `, }, } @@ -86,8 +86,8 @@ container2 /boot/vmlinuz-5.14.0-427.31.1.el9_4.aarch64+debug 5.14.0-427. t.Run(name, func(t *testing.T) { env := testenv.New(t) defer env.RemoveAll() - for container, files := range tt.files { - rootfs := filepath.Join(filepath.Join("/var/lib/warewulf/chroots", container), "rootfs") + for image, files := range tt.files { + rootfs := filepath.Join(filepath.Join("/var/lib/warewulf/chroots", image), "rootfs") for _, file := range files { env.CreateFile(filepath.Join(rootfs, file)) } diff --git a/internal/app/wwctl/container/kernels/root.go b/internal/app/wwctl/image/kernels/root.go similarity index 76% rename from internal/app/wwctl/container/kernels/root.go rename to internal/app/wwctl/image/kernels/root.go index 2b9aeca7..834c66a3 100644 --- a/internal/app/wwctl/container/kernels/root.go +++ b/internal/app/wwctl/image/kernels/root.go @@ -10,11 +10,11 @@ var ( baseCmd = &cobra.Command{ DisableFlagsInUseLine: true, Use: "kernels [OPTIONS]", - Short: "List available container kernels", - Long: "This command lists the kernels that are available in the imported containers.", + Short: "List available image kernels", + Long: "This command lists the kernels that are available in the imported images.", RunE: CobraRunE, Aliases: []string{"kernel"}, - ValidArgsFunction: completions.Containers, + ValidArgsFunction: completions.Images, } ) diff --git a/internal/app/wwctl/image/list/main.go b/internal/app/wwctl/image/list/main.go new file mode 100644 index 00000000..ea8f1dde --- /dev/null +++ b/internal/app/wwctl/image/list/main.go @@ -0,0 +1,84 @@ +package list + +import ( + "strconv" + "time" + + "github.com/spf13/cobra" + + "github.com/warewulf/warewulf/internal/app/wwctl/table" + apiimage "github.com/warewulf/warewulf/internal/pkg/api/image" + "github.com/warewulf/warewulf/internal/pkg/image" + "github.com/warewulf/warewulf/internal/pkg/util" +) + +var imageList = apiimage.ImageList + +func CobraRunE(vars *variables) func(cmd *cobra.Command, args []string) (err error) { + return func(cmd *cobra.Command, args []string) (err error) { + t := table.New(cmd.OutOrStdout()) + showSize := vars.size || vars.chroot || vars.compressed + if showSize || vars.full || vars.kernel { + imageInfo, err := imageList() + if err != nil { + return err + } + if vars.full { + t.AddHeader("IMAGE NAME", "NODES", "KERNEL VERSION", "CREATION TIME", "MODIFICATION TIME", "SIZE") + for i := 0; i < len(imageInfo); i++ { + createTime := time.Unix(int64(imageInfo[i].CreateDate), 0) + modTime := time.Unix(int64(imageInfo[i].ModDate), 0) + sz := util.ByteToString(int64(imageInfo[i].ImgSize)) + if vars.compressed { + sz = util.ByteToString(int64(imageInfo[i].ImgSizeComp)) + } + if vars.chroot { + sz = util.ByteToString(int64(imageInfo[i].Size)) + } + t.AddLine( + imageInfo[i].Name, + strconv.FormatUint(uint64(imageInfo[i].NodeCount), 10), + imageInfo[i].KernelVersion, + createTime.Format(time.RFC822), + modTime.Format(time.RFC822), + sz, + ) + } + } else if vars.kernel { + t.AddHeader("IMAGE NAME", "NODES", "KERNEL VERSION") + for i := 0; i < len(imageInfo); i++ { + t.AddLine( + imageInfo[i].Name, + strconv.FormatUint(uint64(imageInfo[i].NodeCount), 10), + imageInfo[i].KernelVersion, + ) + } + } else if showSize { + t.AddHeader("IMAGE NAME", "NODES", "SIZE") + for i := 0; i < len(imageInfo); i++ { + sz := util.ByteToString(int64(imageInfo[i].ImgSize)) + if vars.compressed { + sz = util.ByteToString(int64(imageInfo[i].ImgSizeComp)) + } + if vars.chroot { + sz = util.ByteToString(int64(imageInfo[i].Size)) + } + + t.AddLine( + imageInfo[i].Name, + strconv.FormatUint(uint64(imageInfo[i].NodeCount), 10), + sz, + ) + } + } + } else { + t.AddHeader("IMAGE NAME") + list, _ := image.ListSources() + for _, cont := range list { + t.AddLine(cont) + } + } + t.Print() + return + } +} diff --git a/internal/app/wwctl/container/list/main_test.go b/internal/app/wwctl/image/list/main_test.go similarity index 76% rename from internal/app/wwctl/container/list/main_test.go rename to internal/app/wwctl/image/list/main_test.go index 6f271642..e5052083 100644 --- a/internal/app/wwctl/container/list/main_test.go +++ b/internal/app/wwctl/image/list/main_test.go @@ -22,12 +22,12 @@ func Test_List(t *testing.T) { mockFunc func() }{ { - name: "container list test", + name: "image list test", args: []string{"-l"}, stdout: ` -CONTAINER NAME NODES KERNEL VERSION CREATION TIME MODIFICATION TIME SIZE --------------- ----- -------------- ------------- ----------------- ---- -test 1 kernel 01 Jan 70 00:00 UTC 01 Jan 70 00:00 UTC 0 B +IMAGE NAME NODES KERNEL VERSION CREATION TIME MODIFICATION TIME SIZE +---------- ----- -------------- ------------- ----------------- ---- +test 1 kernel 01 Jan 70 00:00 UTC 01 Jan 70 00:00 UTC 0 B `, inDb: ` nodeprofiles: @@ -38,8 +38,8 @@ nodes: - default `, mockFunc: func() { - containerList = func() (containerInfo []*wwapiv1.ContainerInfo, err error) { - containerInfo = append(containerInfo, &wwapiv1.ContainerInfo{ + imageList = func() (imageInfo []*wwapiv1.ImageInfo, err error) { + imageInfo = append(imageInfo, &wwapiv1.ImageInfo{ Name: "test", NodeCount: 1, KernelVersion: "kernel", diff --git a/internal/app/wwctl/container/list/root.go b/internal/app/wwctl/image/list/root.go similarity index 85% rename from internal/app/wwctl/container/list/root.go rename to internal/app/wwctl/image/list/root.go index 04c8db95..fac941c6 100644 --- a/internal/app/wwctl/container/list/root.go +++ b/internal/app/wwctl/image/list/root.go @@ -18,8 +18,8 @@ func GetCommand() *cobra.Command { baseCmd := &cobra.Command{ DisableFlagsInUseLine: true, Use: "list [OPTIONS]", - Short: "List imported Warewulf containers", - Long: "This command will show you the containers that are imported into Warewulf.", + Short: "List imported Warewulf images", + Long: "This command will show you the images that are imported into Warewulf.", RunE: CobraRunE(&vars), Aliases: []string{"ls"}, } diff --git a/internal/app/wwctl/image/rename/main.go b/internal/app/wwctl/image/rename/main.go new file mode 100644 index 00000000..100fa749 --- /dev/null +++ b/internal/app/wwctl/image/rename/main.go @@ -0,0 +1,44 @@ +package rename + +import ( + "fmt" + + "github.com/spf13/cobra" + api "github.com/warewulf/warewulf/internal/pkg/api/image" + "github.com/warewulf/warewulf/internal/pkg/api/routes/wwapiv1" + "github.com/warewulf/warewulf/internal/pkg/image" + "github.com/warewulf/warewulf/internal/pkg/wwlog" +) + +func CobraRunE(cmd *cobra.Command, args []string) (err error) { + if len(args) != 2 { + return fmt.Errorf("rename requires 2 arguments: %d provided", len(args)) + } + + crp := &wwapiv1.ImageRenameParameter{ + ImageName: args[0], + TargetName: args[1], + Build: SetBuild, + } + + if !image.DoesSourceExist(crp.ImageName) { + return fmt.Errorf("%s source dir does not exist", crp.ImageName) + } + + if image.DoesSourceExist(crp.TargetName) { + return fmt.Errorf("an other image with the name %s already exists", crp.TargetName) + } + + if !image.ValidName(crp.TargetName) { + return fmt.Errorf("image name contains illegal characters : %s", crp.TargetName) + } + + err = api.ImageRename(crp) + if err != nil { + err = fmt.Errorf("could not rename image: %s", err.Error()) + return + } + + wwlog.Info("Image %s successfully renamed as %s", crp.ImageName, crp.TargetName) + return +} diff --git a/internal/app/wwctl/container/rename/main_test.go b/internal/app/wwctl/image/rename/main_test.go similarity index 56% rename from internal/app/wwctl/container/rename/main_test.go rename to internal/app/wwctl/image/rename/main_test.go index 551efc65..fe6ce724 100644 --- a/internal/app/wwctl/container/rename/main_test.go +++ b/internal/app/wwctl/image/rename/main_test.go @@ -7,7 +7,7 @@ import ( "testing" "github.com/stretchr/testify/assert" - containerList "github.com/warewulf/warewulf/internal/app/wwctl/container/list" + imageList "github.com/warewulf/warewulf/internal/app/wwctl/image/list" "github.com/warewulf/warewulf/internal/pkg/testenv" "github.com/warewulf/warewulf/internal/pkg/warewulfd" "github.com/warewulf/warewulf/internal/pkg/wwlog" @@ -15,33 +15,33 @@ import ( func Test_Rename(t *testing.T) { env := testenv.New(t) - env.WriteFile(path.Join(testenv.WWChrootdir, "test-container/rootfs/file"), `test`) + env.WriteFile(path.Join(testenv.WWChrootdir, "test-image/rootfs/file"), `test`) defer env.RemoveAll() warewulfd.SetNoDaemon() - // first we will verify that there is an existing container - t.Run("container list", func(t *testing.T) { - verifyContainerListOutput(t, "test-container") + // first we will verify that there is an existing image + t.Run("image list", func(t *testing.T) { + verifyImageListOutput(t, "test-image") }) // then rename it - t.Run("container rename", func(t *testing.T) { + t.Run("image rename", func(t *testing.T) { baseCmd := GetCommand() baseCmd.SetOut(os.Stdout) baseCmd.SetErr(os.Stdout) - baseCmd.SetArgs([]string{"test-container", "test-container-rename"}) + baseCmd.SetArgs([]string{"test-image", "test-image-rename"}) err := baseCmd.Execute() assert.NoError(t, err) }) // retrieve again - t.Run("Container list", func(t *testing.T) { - verifyContainerListOutput(t, "test-container-rename") + t.Run("Image list", func(t *testing.T) { + verifyImageListOutput(t, "test-image-rename") }) } -func verifyContainerListOutput(t *testing.T, content string) { - baseCmd := containerList.GetCommand() +func verifyImageListOutput(t *testing.T, content string) { + baseCmd := imageList.GetCommand() buf := new(bytes.Buffer) baseCmd.SetOut(buf) baseCmd.SetErr(buf) diff --git a/internal/app/wwctl/container/rename/root.go b/internal/app/wwctl/image/rename/root.go similarity index 69% rename from internal/app/wwctl/container/rename/root.go rename to internal/app/wwctl/image/rename/root.go index c4dc1adc..055cc22a 100644 --- a/internal/app/wwctl/container/rename/root.go +++ b/internal/app/wwctl/image/rename/root.go @@ -2,22 +2,22 @@ package rename import ( "github.com/spf13/cobra" - "github.com/warewulf/warewulf/internal/pkg/container" + "github.com/warewulf/warewulf/internal/pkg/image" ) var baseCmd = &cobra.Command{ DisableFlagsInUseLine: true, - Use: "rename CONTAINER NEW_NAME", + Use: "rename IMAGE NEW_NAME", Aliases: []string{"mv"}, - Short: "Rename an existing container", - Long: "This command will rename an existing container.", + Short: "Rename an existing image", + Long: "This command will rename an existing image.", RunE: CobraRunE, Args: cobra.MinimumNArgs(2), ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { if len(args) != 0 { return nil, cobra.ShellCompDirectiveNoFileComp } - list, _ := container.ListSources() + list, _ := image.ListSources() return list, cobra.ShellCompDirectiveNoFileComp }, } @@ -25,7 +25,7 @@ var baseCmd = &cobra.Command{ var SetBuild bool func init() { - baseCmd.PersistentFlags().BoolVarP(&SetBuild, "build", "b", false, "Build container after rename") + baseCmd.PersistentFlags().BoolVarP(&SetBuild, "build", "b", false, "Build image after rename") } // GetRootCommand returns the root cobra.Command for the application. diff --git a/internal/app/wwctl/image/root.go b/internal/app/wwctl/image/root.go new file mode 100644 index 00000000..f8eefe33 --- /dev/null +++ b/internal/app/wwctl/image/root.go @@ -0,0 +1,45 @@ +package image + +import ( + "github.com/spf13/cobra" + "github.com/warewulf/warewulf/internal/app/wwctl/image/build" + "github.com/warewulf/warewulf/internal/app/wwctl/image/copy" + "github.com/warewulf/warewulf/internal/app/wwctl/image/delete" + "github.com/warewulf/warewulf/internal/app/wwctl/image/exec" + "github.com/warewulf/warewulf/internal/app/wwctl/image/imprt" + "github.com/warewulf/warewulf/internal/app/wwctl/image/kernels" + "github.com/warewulf/warewulf/internal/app/wwctl/image/list" + "github.com/warewulf/warewulf/internal/app/wwctl/image/rename" + "github.com/warewulf/warewulf/internal/app/wwctl/image/shell" + "github.com/warewulf/warewulf/internal/app/wwctl/image/show" + "github.com/warewulf/warewulf/internal/app/wwctl/image/syncuser" +) + +var baseCmd = &cobra.Command{ + DisableFlagsInUseLine: true, + Use: "image COMMAND [OPTIONS]", + Short: "Operating system image management", + Long: "Starting with version 4, Warewulf uses images to build the bootable\n" + + "node images. These commands will help you import, manage, and transform\n" + + "images into bootable Warewulf images.", + Aliases: []string{"vnfs", "container"}, +} + +func init() { + baseCmd.AddCommand(build.GetCommand()) + baseCmd.AddCommand(list.GetCommand()) + baseCmd.AddCommand(imprt.GetCommand()) + baseCmd.AddCommand(exec.GetCommand()) + baseCmd.AddCommand(shell.GetCommand()) + baseCmd.AddCommand(delete.GetCommand()) + baseCmd.AddCommand(show.GetCommand()) + baseCmd.AddCommand(syncuser.GetCommand()) + baseCmd.AddCommand(copy.GetCommand()) + baseCmd.AddCommand(rename.GetCommand()) + baseCmd.AddCommand(kernels.GetCommand()) +} + +// GetRootCommand returns the root cobra.Command for the application. +func GetCommand() *cobra.Command { + return baseCmd +} diff --git a/internal/app/wwctl/container/shell/main.go b/internal/app/wwctl/image/shell/main.go similarity index 57% rename from internal/app/wwctl/container/shell/main.go rename to internal/app/wwctl/image/shell/main.go index 54911323..2f50c76b 100644 --- a/internal/app/wwctl/container/shell/main.go +++ b/internal/app/wwctl/image/shell/main.go @@ -9,22 +9,22 @@ import ( "path" "github.com/spf13/cobra" - cntexec "github.com/warewulf/warewulf/internal/app/wwctl/container/exec" - "github.com/warewulf/warewulf/internal/pkg/container" + cntexec "github.com/warewulf/warewulf/internal/app/wwctl/image/exec" + "github.com/warewulf/warewulf/internal/pkg/image" "github.com/warewulf/warewulf/internal/pkg/wwlog" ) func CobraRunE(cmd *cobra.Command, args []string) error { - containerName := args[0] + imageName := args[0] var allargs []string - if !container.ValidSource(containerName) { - return fmt.Errorf("unknown Warewulf container: %s", containerName) + if !image.ValidSource(imageName) { + return fmt.Errorf("unknown Warewulf image: %s", imageName) } shellName := os.Getenv("SHELL") - if !container.ValidSource(containerName) { - return fmt.Errorf("unknown Warewulf container: %s", containerName) + if !image.ValidSource(imageName) { + return fmt.Errorf("unknown Warewulf image: %s", imageName) } var shells []string if shellName == "" { @@ -33,7 +33,7 @@ func CobraRunE(cmd *cobra.Command, args []string) error { shells = append(shells, shellName, "/bin/bash") } for _, s := range shells { - if _, err := os.Stat(path.Join(container.RootFsDir(containerName), s)); err == nil { + if _, err := os.Stat(path.Join(image.RootFsDir(imageName), s)); err == nil { shellName = s break } @@ -46,7 +46,7 @@ func CobraRunE(cmd *cobra.Command, args []string) error { cntexec.SyncUser = syncUser cntexec.Build = build if cntexec.Build { - wwlog.Info("Container image build will be skipped if the shell ends with a non-zero exit code.") + wwlog.Info("Image build will be skipped if the shell ends with a non-zero exit code.") } return cntexec.CobraRunE(cmd, allargs) } diff --git a/internal/app/wwctl/container/shell/root.go b/internal/app/wwctl/image/shell/root.go similarity index 70% rename from internal/app/wwctl/container/shell/root.go rename to internal/app/wwctl/image/shell/root.go index b01d48c8..1f76537e 100644 --- a/internal/app/wwctl/container/shell/root.go +++ b/internal/app/wwctl/image/shell/root.go @@ -2,15 +2,15 @@ package shell import ( "github.com/spf13/cobra" - "github.com/warewulf/warewulf/internal/pkg/container" + "github.com/warewulf/warewulf/internal/pkg/image" ) var ( baseCmd = &cobra.Command{ DisableFlagsInUseLine: true, - Use: "shell [OPTIONS] CONTAINER", - Short: "Run a shell inside of a Warewulf container", - Long: "Run a interactive shell inside of a warewulf CONTAINER.\n", + Use: "shell [OPTIONS] IMAGE", + Short: "Run a shell inside of a Warewulf image", + Long: "Run a interactive shell inside of a warewulf IMAGE.\n", Aliases: []string{"chroot"}, RunE: CobraRunE, Args: cobra.MinimumNArgs(1), @@ -18,7 +18,7 @@ var ( if len(args) != 0 { return nil, cobra.ShellCompDirectiveNoFileComp } - list, _ := container.ListSources() + list, _ := image.ListSources() return list, cobra.ShellCompDirectiveNoFileComp }, FParseErrWhitelist: cobra.FParseErrWhitelist{UnknownFlags: true}, @@ -31,12 +31,12 @@ var ( func init() { baseCmd.PersistentFlags().StringArrayVarP(&binds, "bind", "b", []string{}, `source[:destination[:{ro|copy}]] -Bind a local path which must exist into the container. If destination is not +Bind a local path which must exist into the image. If destination is not set, uses the same path as source. "ro" binds read-only. "copy" temporarily -copies the file into the container.`) - baseCmd.PersistentFlags().StringVarP(&nodeName, "node", "n", "", "Create a read only view of the container for the given node") - baseCmd.PersistentFlags().BoolVar(&syncUser, "syncuser", false, "Synchronize UIDs/GIDs from host to container") - baseCmd.PersistentFlags().BoolVar(&build, "build", true, "(Re)build the container image automatically") +copies the file into the image.`) + baseCmd.PersistentFlags().StringVarP(&nodeName, "node", "n", "", "Create a read only view of the image for the given node") + baseCmd.PersistentFlags().BoolVar(&syncUser, "syncuser", false, "Synchronize UIDs/GIDs from host to image") + baseCmd.PersistentFlags().BoolVar(&build, "build", true, "(Re)build the image automatically") } // GetRootCommand returns the root cobra.Command for the application. diff --git a/internal/app/wwctl/container/show/main.go b/internal/app/wwctl/image/show/main.go similarity index 74% rename from internal/app/wwctl/container/show/main.go rename to internal/app/wwctl/image/show/main.go index 5611975b..3678403d 100644 --- a/internal/app/wwctl/container/show/main.go +++ b/internal/app/wwctl/image/show/main.go @@ -3,7 +3,7 @@ package show import ( "fmt" - "github.com/warewulf/warewulf/internal/pkg/api/container" + "github.com/warewulf/warewulf/internal/pkg/api/image" "github.com/warewulf/warewulf/internal/pkg/api/routes/wwapiv1" "github.com/spf13/cobra" @@ -11,12 +11,12 @@ import ( func CobraRunE(cmd *cobra.Command, args []string) (err error) { - csp := &wwapiv1.ContainerShowParameter{ - ContainerName: args[0], + csp := &wwapiv1.ImageShowParameter{ + ImageName: args[0], } - var r *wwapiv1.ContainerShowResponse - r, err = container.ContainerShow(csp) + var r *wwapiv1.ImageShowResponse + r, err = image.ImageShow(csp) if err != nil { return } diff --git a/internal/app/wwctl/container/show/root.go b/internal/app/wwctl/image/show/root.go similarity index 62% rename from internal/app/wwctl/container/show/root.go rename to internal/app/wwctl/image/show/root.go index 30d3e1a8..de10fc30 100644 --- a/internal/app/wwctl/container/show/root.go +++ b/internal/app/wwctl/image/show/root.go @@ -2,22 +2,22 @@ package show import ( "github.com/spf13/cobra" - "github.com/warewulf/warewulf/internal/pkg/container" + "github.com/warewulf/warewulf/internal/pkg/image" ) var ( baseCmd = &cobra.Command{ DisableFlagsInUseLine: true, - Use: "show [OPTIONS] CONTAINER", - Short: "Show root fs dir for container", - Long: `Shows the base directory for the chroot of the given container. -More information about the container can be shown with the '-a' option.`, + Use: "show [OPTIONS] IMAGE", + Short: "Show root fs dir for image", + Long: `Shows the base directory for the chroot of the given image. +More information about the image can be shown with the '-a' option.`, RunE: CobraRunE, ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { if len(args) != 0 { return nil, cobra.ShellCompDirectiveNoFileComp } - list, _ := container.ListSources() + list, _ := image.ListSources() return list, cobra.ShellCompDirectiveNoFileComp }, @@ -27,7 +27,7 @@ More information about the container can be shown with the '-a' option.`, ) func init() { - baseCmd.PersistentFlags().BoolVarP(&ShowAll, "all", "a", false, "Show all information about a container") + baseCmd.PersistentFlags().BoolVarP(&ShowAll, "all", "a", false, "Show all information about an image") } diff --git a/internal/app/wwctl/image/syncuser/main.go b/internal/app/wwctl/image/syncuser/main.go new file mode 100644 index 00000000..c96ffd4f --- /dev/null +++ b/internal/app/wwctl/image/syncuser/main.go @@ -0,0 +1,40 @@ +package syncuser + +import ( + "fmt" + + "github.com/spf13/cobra" + image_build "github.com/warewulf/warewulf/internal/pkg/api/image" + "github.com/warewulf/warewulf/internal/pkg/api/routes/wwapiv1" + "github.com/warewulf/warewulf/internal/pkg/image" + "github.com/warewulf/warewulf/internal/pkg/wwlog" +) + +func CobraRunE(cmd *cobra.Command, args []string) error { + imageName := args[0] + if !image.ValidName(imageName) { + return fmt.Errorf("%s is not a valid image", imageName) + } + err := image.SyncUids(imageName, write) + if err != nil { + return fmt.Errorf("error in synchronize: %s", err) + } + + if write && !build { + // when write = true and build = false, we will print a warnning, this is the default case + wwlog.Warn("Syncuser is completed, please remember to rebuild image or add `--build` flag for automatic rebuild after syncuser") + } else if write && build { + // if write = true and build = true, then it'll trigger the image build after sync + cbp := &wwapiv1.ImageBuildParameter{ + ImageNames: []string{imageName}, + Force: true, + All: false, + } + err := image_build.ImageBuild(cbp) + if err != nil { + return fmt.Errorf("error during image build: %s", err) + } + } + + return nil +} diff --git a/internal/app/wwctl/container/syncuser/root.go b/internal/app/wwctl/image/syncuser/root.go similarity index 63% rename from internal/app/wwctl/container/syncuser/root.go rename to internal/app/wwctl/image/syncuser/root.go index 296ed34e..ebd103d4 100644 --- a/internal/app/wwctl/container/syncuser/root.go +++ b/internal/app/wwctl/image/syncuser/root.go @@ -2,23 +2,23 @@ package syncuser import ( "github.com/spf13/cobra" - "github.com/warewulf/warewulf/internal/pkg/container" + "github.com/warewulf/warewulf/internal/pkg/image" ) var ( baseCmd = &cobra.Command{ DisableFlagsInUseLine: true, - Use: "syncuser [OPTIONS] CONTAINER", - Short: "Synchronizes user in container", - Long: `Synchronize the uids and gids from the host to the container. -Users/groups which are only present in the container will be preserved if no + Use: "syncuser [OPTIONS] IMAGE", + Short: "Synchronizes user in image", + Long: `Synchronize the uids and gids from the host to the image. +Users/groups which are only present in the image will be preserved if no uid/gid collision is detected. File ownerships are also changed.`, RunE: CobraRunE, ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { if len(args) != 0 { return nil, cobra.ShellCompDirectiveNoFileComp } - list, _ := container.ListSources() + list, _ := image.ListSources() return list, cobra.ShellCompDirectiveNoFileComp }, @@ -29,8 +29,8 @@ uid/gid collision is detected. File ownerships are also changed.`, ) func init() { - baseCmd.PersistentFlags().BoolVar(&write, "write", false, "Synchronize uis/gids and write files in container") - baseCmd.PersistentFlags().BoolVar(&build, "build", false, "Build container after syncuser is completed") + baseCmd.PersistentFlags().BoolVar(&write, "write", false, "Synchronize uis/gids and write files in image") + baseCmd.PersistentFlags().BoolVar(&build, "build", false, "Build image after syncuser is completed") } // GetRootCommand returns the root cobra.Command for the application. diff --git a/internal/app/wwctl/node/add/root.go b/internal/app/wwctl/node/add/root.go index 543dfc80..51ddd618 100644 --- a/internal/app/wwctl/node/add/root.go +++ b/internal/app/wwctl/node/add/root.go @@ -5,7 +5,8 @@ import ( "github.com/spf13/cobra" "github.com/warewulf/warewulf/internal/app/wwctl/completions" - "github.com/warewulf/warewulf/internal/pkg/container" + "github.com/warewulf/warewulf/internal/app/wwctl/flags" + "github.com/warewulf/warewulf/internal/pkg/image" "github.com/warewulf/warewulf/internal/pkg/node" "github.com/warewulf/warewulf/internal/pkg/overlay" ) @@ -31,9 +32,10 @@ func GetCommand() *cobra.Command { } vars.nodeConf.CreateFlags(baseCmd) vars.nodeAdd.CreateAddFlags(baseCmd) + flags.AddContainer(baseCmd, &(vars.nodeConf.Profile.ImageName)) // register the command line completions - if err := baseCmd.RegisterFlagCompletionFunc("container", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - list, _ := container.ListSources() + if err := baseCmd.RegisterFlagCompletionFunc("image", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + list, _ := image.ListSources() return list, cobra.ShellCompDirectiveNoFileComp }); err != nil { log.Println(err) diff --git a/internal/app/wwctl/node/list/main_test.go b/internal/app/wwctl/node/list/main_test.go index 8c54e46b..01cff18e 100644 --- a/internal/app/wwctl/node/list/main_test.go +++ b/internal/app/wwctl/node/list/main_test.go @@ -271,9 +271,9 @@ nodes: args: []string{"-l"}, wantErr: false, stdout: ` -NODE NAME KERNEL VERSION CONTAINER OVERLAYS (S/R) ---------- -------------- --------- -------------- -n01 -- -- /rop1,rop2 +NODE NAME KERNEL VERSION IMAGE OVERLAYS (S/R) +--------- -------------- ----- -------------- +n01 -- -- /rop1,rop2 `, inDb: `nodeprofiles: p1: @@ -291,9 +291,9 @@ nodes: args: []string{"-l"}, wantErr: false, stdout: ` -NODE NAME KERNEL VERSION CONTAINER OVERLAYS (S/R) ---------- -------------- --------- -------------- -n01 -- -- sop1/rop1,rop2,nop1,~rop1 +NODE NAME KERNEL VERSION IMAGE OVERLAYS (S/R) +--------- -------------- ----- -------------- +n01 -- -- sop1/rop1,rop2,nop1,~rop1 `, inDb: `nodeprofiles: p1: @@ -453,7 +453,7 @@ nodes: ], "Comment": "", "ClusterName": "", - "ContainerName": "", + "ImageName": "", "Ipxe": "", "RuntimeOverlay": null, "SystemOverlay": null, @@ -492,7 +492,7 @@ nodes: ], "Comment": "", "ClusterName": "", - "ContainerName": "", + "ImageName": "", "Ipxe": "", "RuntimeOverlay": null, "SystemOverlay": null, @@ -515,7 +515,7 @@ nodes: ], "Comment": "", "ClusterName": "", - "ContainerName": "", + "ImageName": "", "Ipxe": "", "RuntimeOverlay": null, "SystemOverlay": null, diff --git a/internal/app/wwctl/node/set/root.go b/internal/app/wwctl/node/set/root.go index 89e1a42c..a84aaa30 100644 --- a/internal/app/wwctl/node/set/root.go +++ b/internal/app/wwctl/node/set/root.go @@ -5,7 +5,8 @@ import ( "github.com/spf13/cobra" "github.com/warewulf/warewulf/internal/app/wwctl/completions" - "github.com/warewulf/warewulf/internal/pkg/container" + "github.com/warewulf/warewulf/internal/app/wwctl/flags" + "github.com/warewulf/warewulf/internal/pkg/image" "github.com/warewulf/warewulf/internal/pkg/node" "github.com/warewulf/warewulf/internal/pkg/overlay" ) @@ -44,12 +45,13 @@ func GetCommand() *cobra.Command { vars.nodeConf.CreateFlags(baseCmd) vars.nodeAdd.CreateAddFlags(baseCmd) vars.nodeDel.CreateDelFlags(baseCmd) + flags.AddContainer(baseCmd, &(vars.nodeConf.Profile.ImageName)) baseCmd.PersistentFlags().BoolVarP(&vars.setNodeAll, "all", "a", false, "Set all nodes") baseCmd.PersistentFlags().BoolVarP(&vars.setYes, "yes", "y", false, "Set 'yes' to all questions asked") baseCmd.PersistentFlags().BoolVarP(&vars.setForce, "force", "f", false, "Force configuration (even on error)") // register the command line completions - if err := baseCmd.RegisterFlagCompletionFunc("container", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - list, _ := container.ListSources() + if err := baseCmd.RegisterFlagCompletionFunc("image", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + list, _ := image.ListSources() return list, cobra.ShellCompDirectiveNoFileComp }); err != nil { log.Println(err) diff --git a/internal/app/wwctl/overlay/build/main_test.go b/internal/app/wwctl/overlay/build/main_test.go index 6820e5c0..f86bb942 100644 --- a/internal/app/wwctl/overlay/build/main_test.go +++ b/internal/app/wwctl/overlay/build/main_test.go @@ -17,7 +17,7 @@ func Benchmark_Overlay_Build(b *testing.B) { `nodeprofiles: default: comment: This profile is automatically included for each node - container name: rockylinux-9 + image name: rockylinux-9 ipxe template: default runtime overlay: - hosts diff --git a/internal/app/wwctl/profile/add/root.go b/internal/app/wwctl/profile/add/root.go index 1e9b577b..e4a73e13 100644 --- a/internal/app/wwctl/profile/add/root.go +++ b/internal/app/wwctl/profile/add/root.go @@ -5,7 +5,8 @@ import ( "github.com/spf13/cobra" "github.com/warewulf/warewulf/internal/app/wwctl/completions" - "github.com/warewulf/warewulf/internal/pkg/container" + "github.com/warewulf/warewulf/internal/app/wwctl/flags" + "github.com/warewulf/warewulf/internal/pkg/image" "github.com/warewulf/warewulf/internal/pkg/node" "github.com/warewulf/warewulf/internal/pkg/overlay" ) @@ -30,9 +31,10 @@ func GetCommand() *cobra.Command { } vars.profileConf.CreateFlags(baseCmd) vars.profileAdd.CreateAddFlags(baseCmd) + flags.AddContainer(baseCmd, &(vars.profileConf.ImageName)) // register the command line completions - if err := baseCmd.RegisterFlagCompletionFunc("container", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - list, _ := container.ListSources() + if err := baseCmd.RegisterFlagCompletionFunc("image", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + list, _ := image.ListSources() return list, cobra.ShellCompDirectiveNoFileComp }); err != nil { log.Println(err) diff --git a/internal/app/wwctl/profile/list/main_test.go b/internal/app/wwctl/profile/list/main_test.go index 808ccef4..e7b57358 100644 --- a/internal/app/wwctl/profile/list/main_test.go +++ b/internal/app/wwctl/profile/list/main_test.go @@ -157,7 +157,7 @@ nodes: "Profiles": null, "Comment": "", "ClusterName": "", - "ContainerName": "", + "ImageName": "", "Ipxe": "", "RuntimeOverlay": null, "SystemOverlay": null, @@ -209,7 +209,7 @@ nodes: "Profiles": null, "Comment": "", "ClusterName": "", - "ContainerName": "", + "ImageName": "", "Ipxe": "", "RuntimeOverlay": null, "SystemOverlay": null, @@ -228,7 +228,7 @@ nodes: "Profiles": null, "Comment": "", "ClusterName": "", - "ContainerName": "", + "ImageName": "", "Ipxe": "", "RuntimeOverlay": null, "SystemOverlay": null, diff --git a/internal/app/wwctl/profile/set/root.go b/internal/app/wwctl/profile/set/root.go index 5224d8ee..bb049075 100644 --- a/internal/app/wwctl/profile/set/root.go +++ b/internal/app/wwctl/profile/set/root.go @@ -5,7 +5,8 @@ import ( "github.com/spf13/cobra" "github.com/warewulf/warewulf/internal/app/wwctl/completions" - "github.com/warewulf/warewulf/internal/pkg/container" + "github.com/warewulf/warewulf/internal/app/wwctl/flags" + "github.com/warewulf/warewulf/internal/pkg/image" "github.com/warewulf/warewulf/internal/pkg/node" "github.com/warewulf/warewulf/internal/pkg/overlay" ) @@ -51,10 +52,11 @@ func GetCommand() *cobra.Command { vars.profileConf.CreateFlags(baseCmd) vars.profileDel.CreateDelFlags(baseCmd) vars.profileAdd.CreateAddFlags(baseCmd) + flags.AddContainer(baseCmd, &(vars.profileConf.ImageName)) baseCmd.PersistentFlags().BoolVarP(&vars.setYes, "yes", "y", false, "Set 'yes' to all questions asked") // register the command line completions - if err := baseCmd.RegisterFlagCompletionFunc("container", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - list, _ := container.ListSources() + if err := baseCmd.RegisterFlagCompletionFunc("image", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + list, _ := image.ListSources() return list, cobra.ShellCompDirectiveNoFileComp }); err != nil { log.Println(err) diff --git a/internal/app/wwctl/root.go b/internal/app/wwctl/root.go index 70dcf95c..a1fbeb50 100644 --- a/internal/app/wwctl/root.go +++ b/internal/app/wwctl/root.go @@ -6,8 +6,8 @@ import ( "github.com/spf13/cobra" "github.com/warewulf/warewulf/internal/app/wwctl/clean" "github.com/warewulf/warewulf/internal/app/wwctl/configure" - "github.com/warewulf/warewulf/internal/app/wwctl/container" "github.com/warewulf/warewulf/internal/app/wwctl/genconf" + "github.com/warewulf/warewulf/internal/app/wwctl/image" "github.com/warewulf/warewulf/internal/app/wwctl/node" "github.com/warewulf/warewulf/internal/app/wwctl/overlay" "github.com/warewulf/warewulf/internal/app/wwctl/power" @@ -49,7 +49,7 @@ func init() { rootCmd.SetUsageTemplate(help.UsageTemplate) rootCmd.SetHelpTemplate(help.HelpTemplate) rootCmd.AddCommand(overlay.GetCommand()) - rootCmd.AddCommand(container.GetCommand()) + rootCmd.AddCommand(image.GetCommand()) rootCmd.AddCommand(node.GetCommand()) rootCmd.AddCommand(power.GetCommand()) rootCmd.AddCommand(profile.GetCommand()) diff --git a/internal/pkg/api/container/container.go b/internal/pkg/api/image/image.go similarity index 56% rename from internal/pkg/api/container/container.go rename to internal/pkg/api/image/image.go index fde6d25d..c868ef42 100644 --- a/internal/pkg/api/container/container.go +++ b/internal/pkg/api/image/image.go @@ -1,4 +1,4 @@ -package container +package image import ( "fmt" @@ -10,7 +10,7 @@ import ( "github.com/containers/image/v5/types" "github.com/warewulf/warewulf/internal/pkg/api/routes/wwapiv1" - "github.com/warewulf/warewulf/internal/pkg/container" + "github.com/warewulf/warewulf/internal/pkg/image" "github.com/warewulf/warewulf/internal/pkg/kernel" "github.com/warewulf/warewulf/internal/pkg/node" "github.com/warewulf/warewulf/internal/pkg/util" @@ -18,71 +18,71 @@ import ( "github.com/warewulf/warewulf/internal/pkg/wwlog" ) -func ContainerCopy(cbp *wwapiv1.ContainerCopyParameter) (err error) { +func ImageCopy(cbp *wwapiv1.ImageCopyParameter) (err error) { if cbp == nil { - return fmt.Errorf("containerCopyParameter is nil") + return fmt.Errorf("imageCopyParameter is nil") } - if !container.DoesSourceExist(cbp.ContainerSource) { - return fmt.Errorf("container %s does not exists.", cbp.ContainerSource) + if !image.DoesSourceExist(cbp.ImageSource) { + return fmt.Errorf("image %s does not exists.", cbp.ImageSource) } - if !container.ValidName(cbp.ContainerDestination) { - return fmt.Errorf("container name contains illegal characters : %s", cbp.ContainerDestination) + if !image.ValidName(cbp.ImageDestination) { + return fmt.Errorf("image name contains illegal characters : %s", cbp.ImageDestination) } - if container.DoesSourceExist(cbp.ContainerDestination) { - return fmt.Errorf("An other container with the name %s already exists", cbp.ContainerDestination) + if image.DoesSourceExist(cbp.ImageDestination) { + return fmt.Errorf("An other image with the name %s already exists", cbp.ImageDestination) } - err = container.Duplicate(cbp.ContainerSource, cbp.ContainerDestination) + err = image.Duplicate(cbp.ImageSource, cbp.ImageDestination) if err != nil { return fmt.Errorf("could not duplicate image: %s", err.Error()) } if cbp.Build { - err = container.Build(cbp.ContainerDestination, true) + err = image.Build(cbp.ImageDestination, true) if err != nil { return err } } - return fmt.Errorf("Container %s has been succesfully duplicated as %s", cbp.ContainerSource, cbp.ContainerDestination) + return fmt.Errorf("Image %s has been succesfully duplicated as %s", cbp.ImageSource, cbp.ImageDestination) } -func ContainerBuild(cbp *wwapiv1.ContainerBuildParameter) (err error) { +func ImageBuild(cbp *wwapiv1.ImageBuildParameter) (err error) { if cbp == nil { - return fmt.Errorf("ContainerBuildParameter is nil") + return fmt.Errorf("ImageBuildParameter is nil") } - var containers []string + var images []string if cbp.All { - containers, err = container.ListSources() + images, err = image.ListSources() } else { - containers = cbp.ContainerNames + images = cbp.ImageNames } - if len(containers) == 0 { + if len(images) == 0 { return } - for _, c := range containers { - if !container.ValidSource(c) { - return fmt.Errorf("VNFS name does not exist: %s", c) + for _, c := range images { + if !image.ValidSource(c) { + return fmt.Errorf("Image name does not exist: %s", c) } - err = container.Build(c, cbp.Force) + err = image.Build(c, cbp.Force) if err != nil { - return fmt.Errorf("could not build container %s: %s", c, err) + return fmt.Errorf("could not build image %s: %s", c, err) } } return } -func ContainerDelete(cdp *wwapiv1.ContainerDeleteParameter) (err error) { +func ImageDelete(cdp *wwapiv1.ImageDeleteParameter) (err error) { if cdp == nil { - return fmt.Errorf("ContainerDeleteParameter is nil") + return fmt.Errorf("ImageDeleteParameter is nil") } nodeDB, err := node.New() @@ -96,36 +96,36 @@ func ContainerDelete(cdp *wwapiv1.ContainerDeleteParameter) (err error) { } ARG_LOOP: - for i := 0; i < len(cdp.ContainerNames); i++ { + for i := 0; i < len(cdp.ImageNames); i++ { //_, arg := range args { - containerName := cdp.ContainerNames[i] + imageName := cdp.ImageNames[i] for _, n := range nodes { - if n.ContainerName == containerName { - wwlog.Error("Container is configured for nodes, skipping: %s", containerName) + if n.ImageName == imageName { + wwlog.Error("Image is configured for nodes, skipping: %s", imageName) continue ARG_LOOP } } - if !container.ValidSource(containerName) { - wwlog.Error("Container name is not a valid source: %s", containerName) + if !image.ValidSource(imageName) { + wwlog.Error("Image name is not a valid source: %s", imageName) continue } - err := container.DeleteSource(containerName) + err := image.DeleteSource(imageName) if err != nil { - wwlog.Error("Could not remove source: %s", containerName) + wwlog.Error("Could not remove source: %s", imageName) } - err = container.DeleteImage(containerName) + err = image.DeleteImage(imageName) if err != nil { - wwlog.Error("Could not remove image files %s", containerName) + wwlog.Error("Could not remove image files %s", imageName) } - fmt.Printf("Container has been deleted: %s\n", containerName) + fmt.Printf("Image has been deleted: %s\n", imageName) } return } -func ContainerImport(cip *wwapiv1.ContainerImportParameter) (containerName string, err error) { +func ImageImport(cip *wwapiv1.ImageImportParameter) (imageName string, err error) { if cip == nil { err = fmt.Errorf("NodeAddParameter is nil") return @@ -133,20 +133,20 @@ func ContainerImport(cip *wwapiv1.ContainerImportParameter) (containerName strin if cip.Name == "" { name := path.Base(cip.Source) - wwlog.Info("Setting VNFS name: %s", name) + wwlog.Info("Setting image name: %s", name) cip.Name = name } - if !container.ValidName(cip.Name) { - err = fmt.Errorf("VNFS name contains illegal characters: %s", cip.Name) + if !image.ValidName(cip.Name) { + err = fmt.Errorf("Image name contains illegal characters: %s", cip.Name) return } - containerName = cip.Name - fullPath := container.SourceDir(cip.Name) + imageName = cip.Name + fullPath := image.SourceDir(cip.Name) - // container already exists and should be removed first + // image already exists and should be removed first if util.IsDir(fullPath) && cip.Force { - wwlog.Info("Overwriting existing VNFS") + wwlog.Info("Overwriting existing image") err = os.RemoveAll(fullPath) if err != nil { return @@ -155,10 +155,10 @@ func ContainerImport(cip *wwapiv1.ContainerImportParameter) (containerName strin if util.IsDir(fullPath) { if !cip.Update { - err = fmt.Errorf("VNFS Name exists, specify --force, --update, or choose a different name: %s", cip.Name) + err = fmt.Errorf("Image name exists, specify --force, --update, or choose a different name: %s", cip.Name) return } - wwlog.Info("Updating existing VNFS") + wwlog.Info("Updating existing image") } else if strings.HasPrefix(cip.Source, "docker://") || strings.HasPrefix(cip.Source, "docker-daemon://") || strings.HasPrefix(cip.Source, "file://") || util.IsFile(cip.Source) { var sCtx *types.SystemContext @@ -174,17 +174,17 @@ func ContainerImport(cip *wwapiv1.ContainerImportParameter) (containerName strin return } } - err = container.ImportDocker(cip.Source, cip.Name, sCtx) + err = image.ImportDocker(cip.Source, cip.Name, sCtx) if err != nil { err = fmt.Errorf("could not import image: %s", err.Error()) - _ = container.DeleteSource(cip.Name) + _ = image.DeleteSource(cip.Name) return } } else if util.IsDir(cip.Source) { - err = container.ImportDirectory(cip.Source, cip.Name) + err = image.ImportDirectory(cip.Source, cip.Name) if err != nil { err = fmt.Errorf("could not import image: %s", err.Error()) - _ = container.DeleteSource(cip.Name) + _ = image.DeleteSource(cip.Name) return } } else { @@ -193,7 +193,7 @@ func ContainerImport(cip *wwapiv1.ContainerImportParameter) (containerName strin } if cip.SyncUser { - err = container.SyncUids(cip.Name, true) + err = image.SyncUids(cip.Name, true) if err != nil { err = fmt.Errorf("error in user sync, fix error and run 'syncuser' manually: %s", err) return @@ -201,20 +201,20 @@ func ContainerImport(cip *wwapiv1.ContainerImportParameter) (containerName strin } if cip.Build { - wwlog.Info("Building container: %s", cip.Name) - err = container.Build(cip.Name, true) + wwlog.Info("Building image: %s", cip.Name) + err = image.Build(cip.Name, true) if err != nil { - err = fmt.Errorf("could not build container %s: %s", cip.Name, err.Error()) + err = fmt.Errorf("could not build image %s: %s", cip.Name, err.Error()) return } } return } -func ContainerList() (containerInfo []*wwapiv1.ContainerInfo, err error) { +func ImageList() (imageInfo []*wwapiv1.ImageInfo, err error) { var sources []string - sources, err = container.ListSources() + sources, err = image.ListSources() if err != nil { wwlog.Error("%s", err) return @@ -234,7 +234,7 @@ func ContainerList() (containerInfo []*wwapiv1.ContainerInfo, err error) { nodemap := make(map[string]int) for _, n := range nodes { - nodemap[n.ContainerName]++ + nodemap[n.ImageName]++ } for _, source := range sources { @@ -249,31 +249,31 @@ func ContainerList() (containerInfo []*wwapiv1.ContainerInfo, err error) { kernelVersion = kernel.Version() } var creationTime uint64 - sourceStat, err := os.Stat(container.SourceDir(source)) - wwlog.Debug("Checking creation time for: %s,%v", container.SourceDir(source), sourceStat.ModTime()) + sourceStat, err := os.Stat(image.SourceDir(source)) + wwlog.Debug("Checking creation time for: %s,%v", image.SourceDir(source), sourceStat.ModTime()) if err != nil { wwlog.Error("%s\n", err) } else { creationTime = uint64(sourceStat.ModTime().Unix()) } var modTime uint64 - imageStat, err := os.Stat(container.ImageFile(source)) + imageStat, err := os.Stat(image.ImageFile(source)) if err == nil { modTime = uint64(imageStat.ModTime().Unix()) } - size, err := util.DirSize(container.SourceDir(source)) + size, err := util.DirSize(image.SourceDir(source)) if err != nil { wwlog.Error("%s\n", err) } imgSize := 0 - if imgF, err := os.Stat(container.ImageFile(source)); err == nil { + if imgF, err := os.Stat(image.ImageFile(source)); err == nil { imgSize = int(imgF.Size()) } imgCSize := 0 - if imgFC, err := os.Stat(container.ImageFile(source) + ".gz"); err == nil { + if imgFC, err := os.Stat(image.ImageFile(source) + ".gz"); err == nil { imgCSize = int(imgFC.Size()) } - containerInfo = append(containerInfo, &wwapiv1.ContainerInfo{ + imageInfo = append(imageInfo, &wwapiv1.ImageInfo{ Name: source, NodeCount: uint32(nodemap[source]), KernelVersion: kernelVersion, @@ -288,20 +288,20 @@ func ContainerList() (containerInfo []*wwapiv1.ContainerInfo, err error) { return } -func ContainerShow(csp *wwapiv1.ContainerShowParameter) (response *wwapiv1.ContainerShowResponse, err error) { - containerName := csp.ContainerName +func ImageShow(csp *wwapiv1.ImageShowParameter) (response *wwapiv1.ImageShowResponse, err error) { + imageName := csp.ImageName - if !container.ValidName(containerName) { - err = fmt.Errorf("%s is not a valid container name", containerName) + if !image.ValidName(imageName) { + err = fmt.Errorf("%s is not a valid image name", imageName) return } - rootFsDir := container.RootFsDir(containerName) + rootFsDir := image.RootFsDir(imageName) if !util.IsDir(rootFsDir) { - err = fmt.Errorf("%s is not a valid container", containerName) + err = fmt.Errorf("%s is not a valid image", imageName) return } - kernel := kernel.FindKernels(containerName).Default() + kernel := kernel.FindKernels(imageName).Default() kernelVersion := "" if kernel != nil { kernelVersion = kernel.Version() @@ -319,13 +319,13 @@ func ContainerShow(csp *wwapiv1.ContainerShowParameter) (response *wwapiv1.Conta var nodeList []string for _, n := range nodes { - if n.ContainerName == containerName { + if n.ImageName == imageName { nodeList = append(nodeList, n.Id()) } } - response = &wwapiv1.ContainerShowResponse{ - Name: containerName, + response = &wwapiv1.ImageShowResponse{ + Name: imageName, Rootfs: rootFsDir, Nodes: nodeList, KernelVersion: kernelVersion, @@ -333,28 +333,28 @@ func ContainerShow(csp *wwapiv1.ContainerShowParameter) (response *wwapiv1.Conta return } -func ContainerRename(crp *wwapiv1.ContainerRenameParameter) (err error) { - // rename the container source folder - sourceDir := container.SourceDir(crp.ContainerName) - destDir := container.SourceDir(crp.TargetName) +func ImageRename(crp *wwapiv1.ImageRenameParameter) (err error) { + // rename the image source folder + sourceDir := image.SourceDir(crp.ImageName) + destDir := image.SourceDir(crp.TargetName) err = os.Rename(sourceDir, destDir) if err != nil { return err } - err = container.DeleteImage(crp.ContainerName) + err = image.DeleteImage(crp.ImageName) if err != nil { - wwlog.Warn("Could not remove image files for %s: %s", crp.ContainerName, err) + wwlog.Warn("Could not remove image files for %s: %s", crp.ImageName, err) } if crp.Build { - err = container.Build(crp.TargetName, true) + err = image.Build(crp.TargetName, true) if err != nil { return err } } - // update the nodes profiles container name + // update the nodes profiles image name nodeDB, err := node.New() if err != nil { return err @@ -365,8 +365,8 @@ func ContainerRename(crp *wwapiv1.ContainerRenameParameter) (err error) { return err } for _, node := range nodes { - if node.ContainerName == crp.ContainerName { - node.ContainerName = crp.TargetName + if node.ImageName == crp.ImageName { + node.ImageName = crp.TargetName } } @@ -375,8 +375,8 @@ func ContainerRename(crp *wwapiv1.ContainerRenameParameter) (err error) { return err } for _, profile := range profiles { - if profile.ContainerName == crp.ContainerName { - profile.ContainerName = crp.TargetName + if profile.ImageName == crp.ImageName { + profile.ImageName = crp.TargetName } } diff --git a/internal/pkg/api/node/list.go b/internal/pkg/api/node/list.go index ceeb4ccb..004e2ce5 100644 --- a/internal/pkg/api/node/list.go +++ b/internal/pkg/api/node/list.go @@ -74,7 +74,7 @@ func NodeList(nodeGet *wwapiv1.GetNodeList) (nodeList wwapiv1.NodeList, err erro } } else if nodeGet.Type == wwapiv1.GetNodeList_Long { nodeList.Output = append(nodeList.Output, - fmt.Sprintf("%s:=:%s:=:%s:=:%s", "NODE NAME", "KERNEL VERSION", "CONTAINER", "OVERLAYS (S/R)")) + fmt.Sprintf("%s:=:%s:=:%s:=:%s", "NODE NAME", "KERNEL VERSION", "IMAGE", "OVERLAYS (S/R)")) for _, n := range node.FilterNodeListByName(nodes, nodeGet.Nodes) { kernelVersion := "" if n.Kernel != nil { @@ -83,7 +83,7 @@ func NodeList(nodeGet *wwapiv1.GetNodeList) (nodeList wwapiv1.NodeList, err erro nodeList.Output = append(nodeList.Output, fmt.Sprintf("%s:=:%s:=:%s:=:%s", n.Id(), kernelVersion, - n.ContainerName, + n.ImageName, strings.Join(n.SystemOverlay, ",")+"/"+strings.Join(n.RuntimeOverlay, ","))) } } else if nodeGet.Type == wwapiv1.GetNodeList_All { diff --git a/internal/pkg/api/routes/v1/routes.proto b/internal/pkg/api/routes/v1/routes.proto index 88942dac..86758d79 100644 --- a/internal/pkg/api/routes/v1/routes.proto +++ b/internal/pkg/api/routes/v1/routes.proto @@ -16,33 +16,33 @@ message NodeDBHash { string hash = 1; } -// Container +// Image -// ContainerBuildParameter contains input for building zero or more containers. -message ContainerBuildParameter { - repeated string containerNames = 1; +// ImageBuildParameter contains input for building zero or more images. +message ImageBuildParameter { + repeated string imageNames = 1; bool force = 2; bool all = 3; // bool default = 4; } -// ContainerDeleteParameter contains input for removing containers from Warewulf +// ImageDeleteParameter contains input for removing images from Warewulf // management. -message ContainerDeleteParameter { - repeated string containerNames = 1; +message ImageDeleteParameter { + repeated string imageNames = 1; } -// ContainerCopyParameter contains 2 inputs : first one for the source container name and second one for the duplicated container name. -message ContainerCopyParameter { - string containerSource = 1; - string containerDestination = 2; +// ImageCopyParameter contains 2 inputs : first one for the image source name and second one for the duplicated image name. +message ImageCopyParameter { + string imageSource = 1; + string imageDestination = 2; bool build = 3; } -// ContainerImportParameter has all input for importing a container. -message ContainerImportParameter{ - string source = 1; // container source uri - string name = 2; // container name +// ImageImportParameter has all input for importing an image. +message ImageImportParameter{ + string source = 1; // image source uri + string name = 2; // image name bool force = 3; bool update = 4; bool build = 5; @@ -54,9 +54,9 @@ message ContainerImportParameter{ string platform = 11; } -// ContainerInfo has data on each container. This is emitted in the -// ContainerListResponse. -message ContainerInfo { +// ImageInfo has data on each image. This is emitted in the +// ImageListResponse. +message ImageInfo { string name = 1; uint32 nodeCount = 2; string kernelVersion = 3; @@ -67,32 +67,32 @@ message ContainerInfo { uint64 imgSizeComp = 8; } -// ContainerListResponse has all information that ContainerList provides. -message ContainerListResponse { - repeated ContainerInfo containers = 1; +// ImageListResponse has all information that ImageList provides. +message ImageListResponse { + repeated ImageInfo images = 1; } -// ContainerShowParameter is the input for ContainerShow. -message ContainerShowParameter { - string containerName = 1; +// ImageShowParameter is the input for ImageShow. +message ImageShowParameter { + string imageName = 1; } -// ContainerShowResponse has all information emitted on ContainerShow. -message ContainerShowResponse { +// ImageShowResponse has all information emitted on ImageShow. +message ImageShowResponse { string Name = 1; string Rootfs = 2; repeated string Nodes = 3; string KernelVersion = 4; } -// ContainerSyncUserParameter is the input for ContainerSyncUser. -message ContainerSyncUserParameter { - string containerName = 1; +// ImageSyncUserParameter is the input for ImageSyncUser. +message ImageSyncUserParameter { + string imageName = 1; } -// ContainerRenameParameter is the input for ContainerRename -message ContainerRenameParameter { - string containerName = 1; +// ImageRenameParameter is the input for ImageRename +message ImageRenameParameter { + string imageName = 1; string targetName = 2; bool build = 3; } @@ -241,56 +241,56 @@ message CanWriteConfig { // WWApi defines the wwapid service web interface. service WWApi { - // Containers + // Images - // ContainerBuild builds zero or more containers. - rpc ContainerBuild(ContainerBuildParameter) returns (ContainerListResponse) { + // ImageBuild builds zero or more images. + rpc ImageBuild(ImageBuildParameter) returns (ImageListResponse) { option (google.api.http) = { - post: "/v1/containerbuild" + post: "/v1/imagebuild" body: "*" }; } - // ContainerDelete removes one or more container from Warewulf management. - rpc ContainerDelete(ContainerDeleteParameter) returns (google.protobuf.Empty) { + // ImageDelete removes one or more image from Warewulf management. + rpc ImageDelete(ImageDeleteParameter) returns (google.protobuf.Empty) { option (google.api.http) = { - delete: "/v1/container" + delete: "/v1/image" }; } - rpc ContainerCopy(ContainerCopyParameter) returns (google.protobuf.Empty) { + rpc ImageCopy(ImageCopyParameter) returns (google.protobuf.Empty) { option (google.api.http) = { - post: "/v1/containercopy" + post: "/v1/imagecopy" body: "*" }; } - // ContainerImport imports a container to Warewulf. - rpc ContainerImport(ContainerImportParameter) returns (ContainerListResponse) { + // ImageImport imports an image to Warewulf. + rpc ImageImport(ImageImportParameter) returns (ImageListResponse) { option(google.api.http) = { - post: "/v1/container" + post: "/v1/image" body: "*" }; } - // ContainerList lists ContainerInfo for each container. - rpc ContainerList(google.protobuf.Empty) returns (ContainerListResponse) { + // ImageList lists ImageInfo for each image. + rpc ImageList(google.protobuf.Empty) returns (ImageListResponse) { option (google.api.http) = { - get: "/v1/container" + get: "/v1/image" }; } - // ContainerShow lists ContainerShow for each container. - rpc ContainerShow(ContainerShowParameter) returns (ContainerShowResponse) { + // ImageShow lists ImageShow for each image. + rpc ImageShow(ImageShowParameter) returns (ImageShowResponse) { option (google.api.http) = { - get: "/v1/containershow" + get: "/v1/imageshow" }; } - // ContainerRename renames the container - rpc ContainerRename(ContainerRenameParameter) returns (google.protobuf.Empty) { + // ImageRename renames the image + rpc ImageRename(ImageRenameParameter) returns (google.protobuf.Empty) { option (google.api.http) = { - post: "/v1/containerrename" + post: "/v1/imagerename" body: "*" }; } diff --git a/internal/pkg/api/routes/wwapiv1/routes.pb.go b/internal/pkg/api/routes/wwapiv1/routes.pb.go index d4a6c95d..1937b039 100644 --- a/internal/pkg/api/routes/wwapiv1/routes.pb.go +++ b/internal/pkg/api/routes/wwapiv1/routes.pb.go @@ -133,19 +133,19 @@ func (x *NodeDBHash) GetHash() string { return "" } -// ContainerBuildParameter contains input for building zero or more containers. -type ContainerBuildParameter struct { +// ImageBuildParameter contains input for building zero or more images. +type ImageBuildParameter struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - ContainerNames []string `protobuf:"bytes,1,rep,name=containerNames,proto3" json:"containerNames,omitempty"` - Force bool `protobuf:"varint,2,opt,name=force,proto3" json:"force,omitempty"` - All bool `protobuf:"varint,3,opt,name=all,proto3" json:"all,omitempty"` // bool default = 4; + ImageNames []string `protobuf:"bytes,1,rep,name=imageNames,proto3" json:"imageNames,omitempty"` + Force bool `protobuf:"varint,2,opt,name=force,proto3" json:"force,omitempty"` + All bool `protobuf:"varint,3,opt,name=all,proto3" json:"all,omitempty"` // bool default = 4; } -func (x *ContainerBuildParameter) Reset() { - *x = ContainerBuildParameter{} +func (x *ImageBuildParameter) Reset() { + *x = ImageBuildParameter{} if protoimpl.UnsafeEnabled { mi := &file_routes_proto_msgTypes[1] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -153,13 +153,13 @@ func (x *ContainerBuildParameter) Reset() { } } -func (x *ContainerBuildParameter) String() string { +func (x *ImageBuildParameter) String() string { return protoimpl.X.MessageStringOf(x) } -func (*ContainerBuildParameter) ProtoMessage() {} +func (*ImageBuildParameter) ProtoMessage() {} -func (x *ContainerBuildParameter) ProtoReflect() protoreflect.Message { +func (x *ImageBuildParameter) ProtoReflect() protoreflect.Message { mi := &file_routes_proto_msgTypes[1] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -171,44 +171,44 @@ func (x *ContainerBuildParameter) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use ContainerBuildParameter.ProtoReflect.Descriptor instead. -func (*ContainerBuildParameter) Descriptor() ([]byte, []int) { +// Deprecated: Use ImageBuildParameter.ProtoReflect.Descriptor instead. +func (*ImageBuildParameter) Descriptor() ([]byte, []int) { return file_routes_proto_rawDescGZIP(), []int{1} } -func (x *ContainerBuildParameter) GetContainerNames() []string { +func (x *ImageBuildParameter) GetImageNames() []string { if x != nil { - return x.ContainerNames + return x.ImageNames } return nil } -func (x *ContainerBuildParameter) GetForce() bool { +func (x *ImageBuildParameter) GetForce() bool { if x != nil { return x.Force } return false } -func (x *ContainerBuildParameter) GetAll() bool { +func (x *ImageBuildParameter) GetAll() bool { if x != nil { return x.All } return false } -// ContainerDeleteParameter contains input for removing containers from Warewulf +// ImageDeleteParameter contains input for removing images from Warewulf // management. -type ContainerDeleteParameter struct { +type ImageDeleteParameter struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - ContainerNames []string `protobuf:"bytes,1,rep,name=containerNames,proto3" json:"containerNames,omitempty"` + ImageNames []string `protobuf:"bytes,1,rep,name=imageNames,proto3" json:"imageNames,omitempty"` } -func (x *ContainerDeleteParameter) Reset() { - *x = ContainerDeleteParameter{} +func (x *ImageDeleteParameter) Reset() { + *x = ImageDeleteParameter{} if protoimpl.UnsafeEnabled { mi := &file_routes_proto_msgTypes[2] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -216,13 +216,13 @@ func (x *ContainerDeleteParameter) Reset() { } } -func (x *ContainerDeleteParameter) String() string { +func (x *ImageDeleteParameter) String() string { return protoimpl.X.MessageStringOf(x) } -func (*ContainerDeleteParameter) ProtoMessage() {} +func (*ImageDeleteParameter) ProtoMessage() {} -func (x *ContainerDeleteParameter) ProtoReflect() protoreflect.Message { +func (x *ImageDeleteParameter) ProtoReflect() protoreflect.Message { mi := &file_routes_proto_msgTypes[2] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -234,31 +234,31 @@ func (x *ContainerDeleteParameter) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use ContainerDeleteParameter.ProtoReflect.Descriptor instead. -func (*ContainerDeleteParameter) Descriptor() ([]byte, []int) { +// Deprecated: Use ImageDeleteParameter.ProtoReflect.Descriptor instead. +func (*ImageDeleteParameter) Descriptor() ([]byte, []int) { return file_routes_proto_rawDescGZIP(), []int{2} } -func (x *ContainerDeleteParameter) GetContainerNames() []string { +func (x *ImageDeleteParameter) GetImageNames() []string { if x != nil { - return x.ContainerNames + return x.ImageNames } return nil } -// ContainerCopyParameter contains 2 inputs : first one for the source container name and second one for the duplicated container name. -type ContainerCopyParameter struct { +// ImageCopyParameter contains 2 inputs : first one for the image source name and second one for the duplicated image name. +type ImageCopyParameter struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - ContainerSource string `protobuf:"bytes,1,opt,name=containerSource,proto3" json:"containerSource,omitempty"` - ContainerDestination string `protobuf:"bytes,2,opt,name=containerDestination,proto3" json:"containerDestination,omitempty"` - Build bool `protobuf:"varint,3,opt,name=build,proto3" json:"build,omitempty"` + ImageSource string `protobuf:"bytes,1,opt,name=imageSource,proto3" json:"imageSource,omitempty"` + ImageDestination string `protobuf:"bytes,2,opt,name=imageDestination,proto3" json:"imageDestination,omitempty"` + Build bool `protobuf:"varint,3,opt,name=build,proto3" json:"build,omitempty"` } -func (x *ContainerCopyParameter) Reset() { - *x = ContainerCopyParameter{} +func (x *ImageCopyParameter) Reset() { + *x = ImageCopyParameter{} if protoimpl.UnsafeEnabled { mi := &file_routes_proto_msgTypes[3] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -266,13 +266,13 @@ func (x *ContainerCopyParameter) Reset() { } } -func (x *ContainerCopyParameter) String() string { +func (x *ImageCopyParameter) String() string { return protoimpl.X.MessageStringOf(x) } -func (*ContainerCopyParameter) ProtoMessage() {} +func (*ImageCopyParameter) ProtoMessage() {} -func (x *ContainerCopyParameter) ProtoReflect() protoreflect.Message { +func (x *ImageCopyParameter) ProtoReflect() protoreflect.Message { mi := &file_routes_proto_msgTypes[3] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -284,40 +284,40 @@ func (x *ContainerCopyParameter) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use ContainerCopyParameter.ProtoReflect.Descriptor instead. -func (*ContainerCopyParameter) Descriptor() ([]byte, []int) { +// Deprecated: Use ImageCopyParameter.ProtoReflect.Descriptor instead. +func (*ImageCopyParameter) Descriptor() ([]byte, []int) { return file_routes_proto_rawDescGZIP(), []int{3} } -func (x *ContainerCopyParameter) GetContainerSource() string { +func (x *ImageCopyParameter) GetImageSource() string { if x != nil { - return x.ContainerSource + return x.ImageSource } return "" } -func (x *ContainerCopyParameter) GetContainerDestination() string { +func (x *ImageCopyParameter) GetImageDestination() string { if x != nil { - return x.ContainerDestination + return x.ImageDestination } return "" } -func (x *ContainerCopyParameter) GetBuild() bool { +func (x *ImageCopyParameter) GetBuild() bool { if x != nil { return x.Build } return false } -// ContainerImportParameter has all input for importing a container. -type ContainerImportParameter struct { +// ImageImportParameter has all input for importing an image. +type ImageImportParameter struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Source string `protobuf:"bytes,1,opt,name=source,proto3" json:"source,omitempty"` // container source uri - Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` // container name + Source string `protobuf:"bytes,1,opt,name=source,proto3" json:"source,omitempty"` // image source uri + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` // image name Force bool `protobuf:"varint,3,opt,name=force,proto3" json:"force,omitempty"` Update bool `protobuf:"varint,4,opt,name=update,proto3" json:"update,omitempty"` Build bool `protobuf:"varint,5,opt,name=build,proto3" json:"build,omitempty"` @@ -329,8 +329,8 @@ type ContainerImportParameter struct { Platform string `protobuf:"bytes,11,opt,name=platform,proto3" json:"platform,omitempty"` } -func (x *ContainerImportParameter) Reset() { - *x = ContainerImportParameter{} +func (x *ImageImportParameter) Reset() { + *x = ImageImportParameter{} if protoimpl.UnsafeEnabled { mi := &file_routes_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -338,13 +338,13 @@ func (x *ContainerImportParameter) Reset() { } } -func (x *ContainerImportParameter) String() string { +func (x *ImageImportParameter) String() string { return protoimpl.X.MessageStringOf(x) } -func (*ContainerImportParameter) ProtoMessage() {} +func (*ImageImportParameter) ProtoMessage() {} -func (x *ContainerImportParameter) ProtoReflect() protoreflect.Message { +func (x *ImageImportParameter) ProtoReflect() protoreflect.Message { mi := &file_routes_proto_msgTypes[4] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -356,84 +356,84 @@ func (x *ContainerImportParameter) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use ContainerImportParameter.ProtoReflect.Descriptor instead. -func (*ContainerImportParameter) Descriptor() ([]byte, []int) { +// Deprecated: Use ImageImportParameter.ProtoReflect.Descriptor instead. +func (*ImageImportParameter) Descriptor() ([]byte, []int) { return file_routes_proto_rawDescGZIP(), []int{4} } -func (x *ContainerImportParameter) GetSource() string { +func (x *ImageImportParameter) GetSource() string { if x != nil { return x.Source } return "" } -func (x *ContainerImportParameter) GetName() string { +func (x *ImageImportParameter) GetName() string { if x != nil { return x.Name } return "" } -func (x *ContainerImportParameter) GetForce() bool { +func (x *ImageImportParameter) GetForce() bool { if x != nil { return x.Force } return false } -func (x *ContainerImportParameter) GetUpdate() bool { +func (x *ImageImportParameter) GetUpdate() bool { if x != nil { return x.Update } return false } -func (x *ContainerImportParameter) GetBuild() bool { +func (x *ImageImportParameter) GetBuild() bool { if x != nil { return x.Build } return false } -func (x *ContainerImportParameter) GetSyncUser() bool { +func (x *ImageImportParameter) GetSyncUser() bool { if x != nil { return x.SyncUser } return false } -func (x *ContainerImportParameter) GetOciNoHttps() bool { +func (x *ImageImportParameter) GetOciNoHttps() bool { if x != nil { return x.OciNoHttps } return false } -func (x *ContainerImportParameter) GetOciUsername() string { +func (x *ImageImportParameter) GetOciUsername() string { if x != nil { return x.OciUsername } return "" } -func (x *ContainerImportParameter) GetOciPassword() string { +func (x *ImageImportParameter) GetOciPassword() string { if x != nil { return x.OciPassword } return "" } -func (x *ContainerImportParameter) GetPlatform() string { +func (x *ImageImportParameter) GetPlatform() string { if x != nil { return x.Platform } return "" } -// ContainerInfo has data on each container. This is emitted in the -// ContainerListResponse. -type ContainerInfo struct { +// ImageInfo has data on each image. This is emitted in the +// ImageListResponse. +type ImageInfo struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields @@ -448,8 +448,8 @@ type ContainerInfo struct { ImgSizeComp uint64 `protobuf:"varint,8,opt,name=imgSizeComp,proto3" json:"imgSizeComp,omitempty"` } -func (x *ContainerInfo) Reset() { - *x = ContainerInfo{} +func (x *ImageInfo) Reset() { + *x = ImageInfo{} if protoimpl.UnsafeEnabled { mi := &file_routes_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -457,13 +457,13 @@ func (x *ContainerInfo) Reset() { } } -func (x *ContainerInfo) String() string { +func (x *ImageInfo) String() string { return protoimpl.X.MessageStringOf(x) } -func (*ContainerInfo) ProtoMessage() {} +func (*ImageInfo) ProtoMessage() {} -func (x *ContainerInfo) ProtoReflect() protoreflect.Message { +func (x *ImageInfo) ProtoReflect() protoreflect.Message { mi := &file_routes_proto_msgTypes[5] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -475,78 +475,78 @@ func (x *ContainerInfo) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use ContainerInfo.ProtoReflect.Descriptor instead. -func (*ContainerInfo) Descriptor() ([]byte, []int) { +// Deprecated: Use ImageInfo.ProtoReflect.Descriptor instead. +func (*ImageInfo) Descriptor() ([]byte, []int) { return file_routes_proto_rawDescGZIP(), []int{5} } -func (x *ContainerInfo) GetName() string { +func (x *ImageInfo) GetName() string { if x != nil { return x.Name } return "" } -func (x *ContainerInfo) GetNodeCount() uint32 { +func (x *ImageInfo) GetNodeCount() uint32 { if x != nil { return x.NodeCount } return 0 } -func (x *ContainerInfo) GetKernelVersion() string { +func (x *ImageInfo) GetKernelVersion() string { if x != nil { return x.KernelVersion } return "" } -func (x *ContainerInfo) GetCreateDate() uint64 { +func (x *ImageInfo) GetCreateDate() uint64 { if x != nil { return x.CreateDate } return 0 } -func (x *ContainerInfo) GetModDate() uint64 { +func (x *ImageInfo) GetModDate() uint64 { if x != nil { return x.ModDate } return 0 } -func (x *ContainerInfo) GetSize() uint64 { +func (x *ImageInfo) GetSize() uint64 { if x != nil { return x.Size } return 0 } -func (x *ContainerInfo) GetImgSize() uint64 { +func (x *ImageInfo) GetImgSize() uint64 { if x != nil { return x.ImgSize } return 0 } -func (x *ContainerInfo) GetImgSizeComp() uint64 { +func (x *ImageInfo) GetImgSizeComp() uint64 { if x != nil { return x.ImgSizeComp } return 0 } -// ContainerListResponse has all information that ContainerList provides. -type ContainerListResponse struct { +// ImageListResponse has all information that ImageList provides. +type ImageListResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Containers []*ContainerInfo `protobuf:"bytes,1,rep,name=containers,proto3" json:"containers,omitempty"` + Images []*ImageInfo `protobuf:"bytes,1,rep,name=images,proto3" json:"images,omitempty"` } -func (x *ContainerListResponse) Reset() { - *x = ContainerListResponse{} +func (x *ImageListResponse) Reset() { + *x = ImageListResponse{} if protoimpl.UnsafeEnabled { mi := &file_routes_proto_msgTypes[6] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -554,13 +554,13 @@ func (x *ContainerListResponse) Reset() { } } -func (x *ContainerListResponse) String() string { +func (x *ImageListResponse) String() string { return protoimpl.X.MessageStringOf(x) } -func (*ContainerListResponse) ProtoMessage() {} +func (*ImageListResponse) ProtoMessage() {} -func (x *ContainerListResponse) ProtoReflect() protoreflect.Message { +func (x *ImageListResponse) ProtoReflect() protoreflect.Message { mi := &file_routes_proto_msgTypes[6] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -572,29 +572,29 @@ func (x *ContainerListResponse) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use ContainerListResponse.ProtoReflect.Descriptor instead. -func (*ContainerListResponse) Descriptor() ([]byte, []int) { +// Deprecated: Use ImageListResponse.ProtoReflect.Descriptor instead. +func (*ImageListResponse) Descriptor() ([]byte, []int) { return file_routes_proto_rawDescGZIP(), []int{6} } -func (x *ContainerListResponse) GetContainers() []*ContainerInfo { +func (x *ImageListResponse) GetImages() []*ImageInfo { if x != nil { - return x.Containers + return x.Images } return nil } -// ContainerShowParameter is the input for ContainerShow. -type ContainerShowParameter struct { +// ImageShowParameter is the input for ImageShow. +type ImageShowParameter struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - ContainerName string `protobuf:"bytes,1,opt,name=containerName,proto3" json:"containerName,omitempty"` + ImageName string `protobuf:"bytes,1,opt,name=imageName,proto3" json:"imageName,omitempty"` } -func (x *ContainerShowParameter) Reset() { - *x = ContainerShowParameter{} +func (x *ImageShowParameter) Reset() { + *x = ImageShowParameter{} if protoimpl.UnsafeEnabled { mi := &file_routes_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -602,13 +602,13 @@ func (x *ContainerShowParameter) Reset() { } } -func (x *ContainerShowParameter) String() string { +func (x *ImageShowParameter) String() string { return protoimpl.X.MessageStringOf(x) } -func (*ContainerShowParameter) ProtoMessage() {} +func (*ImageShowParameter) ProtoMessage() {} -func (x *ContainerShowParameter) ProtoReflect() protoreflect.Message { +func (x *ImageShowParameter) ProtoReflect() protoreflect.Message { mi := &file_routes_proto_msgTypes[7] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -620,20 +620,20 @@ func (x *ContainerShowParameter) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use ContainerShowParameter.ProtoReflect.Descriptor instead. -func (*ContainerShowParameter) Descriptor() ([]byte, []int) { +// Deprecated: Use ImageShowParameter.ProtoReflect.Descriptor instead. +func (*ImageShowParameter) Descriptor() ([]byte, []int) { return file_routes_proto_rawDescGZIP(), []int{7} } -func (x *ContainerShowParameter) GetContainerName() string { +func (x *ImageShowParameter) GetImageName() string { if x != nil { - return x.ContainerName + return x.ImageName } return "" } -// ContainerShowResponse has all information emitted on ContainerShow. -type ContainerShowResponse struct { +// ImageShowResponse has all information emitted on ImageShow. +type ImageShowResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields @@ -644,8 +644,8 @@ type ContainerShowResponse struct { KernelVersion string `protobuf:"bytes,4,opt,name=KernelVersion,proto3" json:"KernelVersion,omitempty"` } -func (x *ContainerShowResponse) Reset() { - *x = ContainerShowResponse{} +func (x *ImageShowResponse) Reset() { + *x = ImageShowResponse{} if protoimpl.UnsafeEnabled { mi := &file_routes_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -653,13 +653,13 @@ func (x *ContainerShowResponse) Reset() { } } -func (x *ContainerShowResponse) String() string { +func (x *ImageShowResponse) String() string { return protoimpl.X.MessageStringOf(x) } -func (*ContainerShowResponse) ProtoMessage() {} +func (*ImageShowResponse) ProtoMessage() {} -func (x *ContainerShowResponse) ProtoReflect() protoreflect.Message { +func (x *ImageShowResponse) ProtoReflect() protoreflect.Message { mi := &file_routes_proto_msgTypes[8] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -671,50 +671,50 @@ func (x *ContainerShowResponse) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use ContainerShowResponse.ProtoReflect.Descriptor instead. -func (*ContainerShowResponse) Descriptor() ([]byte, []int) { +// Deprecated: Use ImageShowResponse.ProtoReflect.Descriptor instead. +func (*ImageShowResponse) Descriptor() ([]byte, []int) { return file_routes_proto_rawDescGZIP(), []int{8} } -func (x *ContainerShowResponse) GetName() string { +func (x *ImageShowResponse) GetName() string { if x != nil { return x.Name } return "" } -func (x *ContainerShowResponse) GetRootfs() string { +func (x *ImageShowResponse) GetRootfs() string { if x != nil { return x.Rootfs } return "" } -func (x *ContainerShowResponse) GetNodes() []string { +func (x *ImageShowResponse) GetNodes() []string { if x != nil { return x.Nodes } return nil } -func (x *ContainerShowResponse) GetKernelVersion() string { +func (x *ImageShowResponse) GetKernelVersion() string { if x != nil { return x.KernelVersion } return "" } -// ContainerSyncUserParameter is the input for ContainerSyncUser. -type ContainerSyncUserParameter struct { +// ImageSyncUserParameter is the input for ImageSyncUser. +type ImageSyncUserParameter struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - ContainerName string `protobuf:"bytes,1,opt,name=containerName,proto3" json:"containerName,omitempty"` + ImageName string `protobuf:"bytes,1,opt,name=imageName,proto3" json:"imageName,omitempty"` } -func (x *ContainerSyncUserParameter) Reset() { - *x = ContainerSyncUserParameter{} +func (x *ImageSyncUserParameter) Reset() { + *x = ImageSyncUserParameter{} if protoimpl.UnsafeEnabled { mi := &file_routes_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -722,13 +722,13 @@ func (x *ContainerSyncUserParameter) Reset() { } } -func (x *ContainerSyncUserParameter) String() string { +func (x *ImageSyncUserParameter) String() string { return protoimpl.X.MessageStringOf(x) } -func (*ContainerSyncUserParameter) ProtoMessage() {} +func (*ImageSyncUserParameter) ProtoMessage() {} -func (x *ContainerSyncUserParameter) ProtoReflect() protoreflect.Message { +func (x *ImageSyncUserParameter) ProtoReflect() protoreflect.Message { mi := &file_routes_proto_msgTypes[9] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -740,31 +740,31 @@ func (x *ContainerSyncUserParameter) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use ContainerSyncUserParameter.ProtoReflect.Descriptor instead. -func (*ContainerSyncUserParameter) Descriptor() ([]byte, []int) { +// Deprecated: Use ImageSyncUserParameter.ProtoReflect.Descriptor instead. +func (*ImageSyncUserParameter) Descriptor() ([]byte, []int) { return file_routes_proto_rawDescGZIP(), []int{9} } -func (x *ContainerSyncUserParameter) GetContainerName() string { +func (x *ImageSyncUserParameter) GetImageName() string { if x != nil { - return x.ContainerName + return x.ImageName } return "" } -// ContainerRenameParameter is the input for ContainerRename -type ContainerRenameParameter struct { +// ImageRenameParameter is the input for ImageRename +type ImageRenameParameter struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - ContainerName string `protobuf:"bytes,1,opt,name=containerName,proto3" json:"containerName,omitempty"` - TargetName string `protobuf:"bytes,2,opt,name=targetName,proto3" json:"targetName,omitempty"` - Build bool `protobuf:"varint,3,opt,name=build,proto3" json:"build,omitempty"` + ImageName string `protobuf:"bytes,1,opt,name=imageName,proto3" json:"imageName,omitempty"` + TargetName string `protobuf:"bytes,2,opt,name=targetName,proto3" json:"targetName,omitempty"` + Build bool `protobuf:"varint,3,opt,name=build,proto3" json:"build,omitempty"` } -func (x *ContainerRenameParameter) Reset() { - *x = ContainerRenameParameter{} +func (x *ImageRenameParameter) Reset() { + *x = ImageRenameParameter{} if protoimpl.UnsafeEnabled { mi := &file_routes_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -772,13 +772,13 @@ func (x *ContainerRenameParameter) Reset() { } } -func (x *ContainerRenameParameter) String() string { +func (x *ImageRenameParameter) String() string { return protoimpl.X.MessageStringOf(x) } -func (*ContainerRenameParameter) ProtoMessage() {} +func (*ImageRenameParameter) ProtoMessage() {} -func (x *ContainerRenameParameter) ProtoReflect() protoreflect.Message { +func (x *ImageRenameParameter) ProtoReflect() protoreflect.Message { mi := &file_routes_proto_msgTypes[10] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -790,26 +790,26 @@ func (x *ContainerRenameParameter) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use ContainerRenameParameter.ProtoReflect.Descriptor instead. -func (*ContainerRenameParameter) Descriptor() ([]byte, []int) { +// Deprecated: Use ImageRenameParameter.ProtoReflect.Descriptor instead. +func (*ImageRenameParameter) Descriptor() ([]byte, []int) { return file_routes_proto_rawDescGZIP(), []int{10} } -func (x *ContainerRenameParameter) GetContainerName() string { +func (x *ImageRenameParameter) GetImageName() string { if x != nil { - return x.ContainerName + return x.ImageName } return "" } -func (x *ContainerRenameParameter) GetTargetName() string { +func (x *ImageRenameParameter) GetTargetName() string { if x != nil { return x.TargetName } return "" } -func (x *ContainerRenameParameter) GetBuild() bool { +func (x *ImageRenameParameter) GetBuild() bool { if x != nil { return x.Build } @@ -1937,351 +1937,339 @@ var file_routes_proto_rawDesc = []byte{ 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x20, 0x0a, 0x0a, 0x4e, 0x6f, 0x64, 0x65, 0x44, 0x42, 0x48, 0x61, 0x73, 0x68, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x04, 0x68, 0x61, 0x73, 0x68, 0x22, 0x69, 0x0a, 0x17, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, - 0x65, 0x72, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, - 0x12, 0x26, 0x0a, 0x0e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x4e, 0x61, 0x6d, - 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, - 0x6e, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x6f, 0x72, 0x63, - 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x12, 0x10, - 0x0a, 0x03, 0x61, 0x6c, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x03, 0x61, 0x6c, 0x6c, - 0x22, 0x42, 0x0a, 0x18, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x44, 0x65, 0x6c, - 0x65, 0x74, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x12, 0x26, 0x0a, 0x0e, - 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x01, - 0x20, 0x03, 0x28, 0x09, 0x52, 0x0e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x4e, - 0x61, 0x6d, 0x65, 0x73, 0x22, 0x8c, 0x01, 0x0a, 0x16, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, - 0x65, 0x72, 0x43, 0x6f, 0x70, 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x12, - 0x28, 0x0a, 0x0f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, - 0x6e, 0x65, 0x72, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x32, 0x0a, 0x14, 0x63, 0x6f, 0x6e, - 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x14, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, - 0x65, 0x72, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x14, 0x0a, - 0x05, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x62, 0x75, - 0x69, 0x6c, 0x64, 0x22, 0xa6, 0x02, 0x0a, 0x18, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, - 0x72, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, - 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, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, - 0x66, 0x6f, 0x72, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x66, 0x6f, 0x72, - 0x63, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x06, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x62, 0x75, - 0x69, 0x6c, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x62, 0x75, 0x69, 0x6c, 0x64, - 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, 0x12, 0x1e, 0x0a, 0x0a, - 0x6f, 0x63, 0x69, 0x4e, 0x6f, 0x48, 0x74, 0x74, 0x70, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x0a, 0x6f, 0x63, 0x69, 0x4e, 0x6f, 0x48, 0x74, 0x74, 0x70, 0x73, 0x12, 0x20, 0x0a, 0x0b, - 0x6f, 0x63, 0x69, 0x55, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0b, 0x6f, 0x63, 0x69, 0x55, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, - 0x0a, 0x0b, 0x6f, 0x63, 0x69, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x0a, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x0b, 0x6f, 0x63, 0x69, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, - 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x18, 0x0b, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x22, 0xf1, 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, 0x12, 0x18, 0x0a, 0x07, 0x69, 0x6d, 0x67, 0x53, 0x69, 0x7a, 0x65, 0x18, - 0x07, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x69, 0x6d, 0x67, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x20, - 0x0a, 0x0b, 0x69, 0x6d, 0x67, 0x53, 0x69, 0x7a, 0x65, 0x43, 0x6f, 0x6d, 0x70, 0x18, 0x08, 0x20, - 0x01, 0x28, 0x04, 0x52, 0x0b, 0x69, 0x6d, 0x67, 0x53, 0x69, 0x7a, 0x65, 0x43, 0x6f, 0x6d, 0x70, - 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, 0x76, 0x0a, 0x18, 0x43, 0x6f, 0x6e, 0x74, 0x61, - 0x69, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x6e, 0x61, 0x6d, 0x65, 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, 0x12, 0x1e, 0x0a, 0x0a, 0x74, 0x61, 0x72, - 0x67, 0x65, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x74, - 0x61, 0x72, 0x67, 0x65, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x62, 0x75, 0x69, - 0x6c, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x62, 0x75, 0x69, 0x6c, 0x64, 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, 0xad, 0x01, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x4c, 0x69, - 0x73, 0x74, 0x12, 0x32, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x08, 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, - 0x09, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x22, 0x54, 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, 0x12, 0x08, - 0x0a, 0x04, 0x59, 0x41, 0x4d, 0x4c, 0x10, 0x06, 0x12, 0x08, 0x0a, 0x04, 0x4a, 0x53, 0x4f, 0x4e, - 0x10, 0x07, 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, 0x7e, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, - 0x66, 0x69, 0x6c, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x53, 0x68, 0x6f, 0x77, - 0x41, 0x6c, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x53, 0x68, 0x6f, 0x77, 0x41, - 0x6c, 0x6c, 0x12, 0x1a, 0x0a, 0x08, 0x53, 0x68, 0x6f, 0x77, 0x59, 0x61, 0x6d, 0x6c, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x53, 0x68, 0x6f, 0x77, 0x59, 0x61, 0x6d, 0x6c, 0x12, 0x1a, - 0x0a, 0x08, 0x53, 0x68, 0x6f, 0x77, 0x4a, 0x73, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x08, 0x53, 0x68, 0x6f, 0x77, 0x4a, 0x73, 0x6f, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x50, 0x72, - 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x50, 0x72, - 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x22, 0x25, 0x0a, 0x0b, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, - 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, 0x7e, 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, 0x14, 0x0a, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x68, - 0x61, 0x73, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x68, 0x61, 0x73, 0x68, 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, 0x48, 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, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x61, 0x73, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x04, 0x68, 0x61, 0x73, 0x68, 0x22, 0x5d, 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, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x61, 0x73, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x04, 0x68, 0x61, 0x73, 0x68, 0x22, 0x99, 0x06, 0x0a, 0x10, 0x43, 0x6f, 0x6e, 0x66, 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, - 0x22, 0x0a, 0x0c, 0x6e, 0x65, 0x74, 0x64, 0x65, 0x76, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x6e, 0x65, 0x74, 0x64, 0x65, 0x76, 0x44, 0x65, 0x6c, - 0x65, 0x74, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x64, 0x69, 0x73, 0x6b, 0x44, 0x65, 0x6c, 0x65, 0x74, - 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x64, 0x69, 0x73, 0x6b, 0x44, 0x65, 0x6c, - 0x65, 0x74, 0x65, 0x12, 0x28, 0x0a, 0x0f, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, - 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x70, 0x61, - 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x2a, 0x0a, - 0x10, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x44, 0x65, 0x6c, 0x65, 0x74, - 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, - 0x74, 0x65, 0x6d, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x61, 0x6c, 0x6c, - 0x43, 0x6f, 0x6e, 0x66, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x61, 0x6c, 0x6c, - 0x43, 0x6f, 0x6e, 0x66, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x18, 0x07, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x63, - 0x6f, 0x6e, 0x66, 0x4c, 0x69, 0x73, 0x74, 0x18, 0x08, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x63, - 0x6f, 0x6e, 0x66, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x3e, 0x0a, 0x06, 0x74, 0x61, 0x67, 0x41, 0x64, - 0x64, 0x18, 0x09, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x77, 0x77, 0x61, 0x70, 0x69, 0x2e, - 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x53, 0x65, 0x74, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, - 0x74, 0x65, 0x72, 0x2e, 0x54, 0x61, 0x67, 0x41, 0x64, 0x64, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, - 0x06, 0x74, 0x61, 0x67, 0x41, 0x64, 0x64, 0x12, 0x47, 0x0a, 0x09, 0x6e, 0x65, 0x74, 0x54, 0x61, - 0x67, 0x41, 0x64, 0x64, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x77, 0x77, 0x61, + 0x04, 0x68, 0x61, 0x73, 0x68, 0x22, 0x5d, 0x0a, 0x13, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x42, 0x75, + 0x69, 0x6c, 0x64, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x12, 0x1e, 0x0a, 0x0a, + 0x69, 0x6d, 0x61, 0x67, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, + 0x52, 0x0a, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x14, 0x0a, 0x05, + 0x66, 0x6f, 0x72, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x66, 0x6f, 0x72, + 0x63, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x6c, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x03, 0x61, 0x6c, 0x6c, 0x22, 0x36, 0x0a, 0x14, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x44, 0x65, 0x6c, + 0x65, 0x74, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x12, 0x1e, 0x0a, 0x0a, + 0x69, 0x6d, 0x61, 0x67, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, + 0x52, 0x0a, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x22, 0x78, 0x0a, 0x12, + 0x49, 0x6d, 0x61, 0x67, 0x65, 0x43, 0x6f, 0x70, 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, + 0x65, 0x72, 0x12, 0x20, 0x0a, 0x0b, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x53, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x53, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x12, 0x2a, 0x0a, 0x10, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x44, 0x65, 0x73, + 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, + 0x69, 0x6d, 0x61, 0x67, 0x65, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x12, 0x14, 0x0a, 0x05, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x05, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x22, 0xa2, 0x02, 0x0a, 0x14, 0x49, 0x6d, 0x61, 0x67, 0x65, + 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 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, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x66, + 0x6f, 0x72, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x66, 0x6f, 0x72, 0x63, + 0x65, 0x12, 0x16, 0x0a, 0x06, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x06, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x62, 0x75, 0x69, + 0x6c, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x62, 0x75, 0x69, 0x6c, 0x64, 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, 0x12, 0x1e, 0x0a, 0x0a, 0x6f, + 0x63, 0x69, 0x4e, 0x6f, 0x48, 0x74, 0x74, 0x70, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x0a, 0x6f, 0x63, 0x69, 0x4e, 0x6f, 0x48, 0x74, 0x74, 0x70, 0x73, 0x12, 0x20, 0x0a, 0x0b, 0x6f, + 0x63, 0x69, 0x55, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0b, 0x6f, 0x63, 0x69, 0x55, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, + 0x0b, 0x6f, 0x63, 0x69, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x0a, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0b, 0x6f, 0x63, 0x69, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, + 0x1a, 0x0a, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x18, 0x0b, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x22, 0xed, 0x01, 0x0a, 0x09, + 0x49, 0x6d, 0x61, 0x67, 0x65, 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, 0x12, + 0x18, 0x0a, 0x07, 0x69, 0x6d, 0x67, 0x53, 0x69, 0x7a, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x04, + 0x52, 0x07, 0x69, 0x6d, 0x67, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x69, 0x6d, 0x67, + 0x53, 0x69, 0x7a, 0x65, 0x43, 0x6f, 0x6d, 0x70, 0x18, 0x08, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, + 0x69, 0x6d, 0x67, 0x53, 0x69, 0x7a, 0x65, 0x43, 0x6f, 0x6d, 0x70, 0x22, 0x40, 0x0a, 0x11, 0x49, + 0x6d, 0x61, 0x67, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x2b, 0x0a, 0x06, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x13, 0x2e, 0x77, 0x77, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6d, 0x61, 0x67, + 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x06, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x73, 0x22, 0x32, 0x0a, + 0x12, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x53, 0x68, 0x6f, 0x77, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, + 0x74, 0x65, 0x72, 0x12, 0x1c, 0x0a, 0x09, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x4e, 0x61, 0x6d, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x4e, 0x61, 0x6d, + 0x65, 0x22, 0x7b, 0x0a, 0x11, 0x49, 0x6d, 0x61, 0x67, 0x65, 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, 0x36, + 0x0a, 0x16, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x53, 0x79, 0x6e, 0x63, 0x55, 0x73, 0x65, 0x72, 0x50, + 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x12, 0x1c, 0x0a, 0x09, 0x69, 0x6d, 0x61, 0x67, + 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x69, 0x6d, 0x61, + 0x67, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x6a, 0x0a, 0x14, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x52, + 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x12, 0x1c, + 0x0a, 0x09, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x09, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1e, 0x0a, 0x0a, + 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0a, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, + 0x62, 0x75, 0x69, 0x6c, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x62, 0x75, 0x69, + 0x6c, 0x64, 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, 0xad, 0x01, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x4e, 0x6f, 0x64, + 0x65, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x32, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x08, 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, 0x09, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x22, + 0x54, 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, 0x12, 0x08, 0x0a, 0x04, 0x59, 0x41, 0x4d, 0x4c, 0x10, 0x06, 0x12, 0x08, 0x0a, 0x04, 0x4a, + 0x53, 0x4f, 0x4e, 0x10, 0x07, 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, 0x7e, 0x0a, 0x0e, 0x47, 0x65, 0x74, + 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x53, + 0x68, 0x6f, 0x77, 0x41, 0x6c, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x53, 0x68, + 0x6f, 0x77, 0x41, 0x6c, 0x6c, 0x12, 0x1a, 0x0a, 0x08, 0x53, 0x68, 0x6f, 0x77, 0x59, 0x61, 0x6d, + 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x53, 0x68, 0x6f, 0x77, 0x59, 0x61, 0x6d, + 0x6c, 0x12, 0x1a, 0x0a, 0x08, 0x53, 0x68, 0x6f, 0x77, 0x4a, 0x73, 0x6f, 0x6e, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x08, 0x53, 0x68, 0x6f, 0x77, 0x4a, 0x73, 0x6f, 0x6e, 0x12, 0x1a, 0x0a, + 0x08, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, + 0x08, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x22, 0x25, 0x0a, 0x0b, 0x50, 0x72, 0x6f, + 0x66, 0x69, 0x6c, 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, 0x7e, 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, 0x14, 0x0a, 0x05, 0x66, 0x6f, 0x72, 0x63, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x12, 0x12, + 0x0a, 0x04, 0x68, 0x61, 0x73, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x68, 0x61, + 0x73, 0x68, 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, 0x48, 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, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x61, 0x73, 0x68, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x68, 0x61, 0x73, 0x68, 0x22, 0x5d, 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, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x61, 0x73, 0x68, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x68, 0x61, 0x73, 0x68, 0x22, 0x99, 0x06, 0x0a, 0x10, 0x43, 0x6f, + 0x6e, 0x66, 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, 0x22, 0x0a, 0x0c, 0x6e, 0x65, 0x74, 0x64, 0x65, 0x76, 0x44, 0x65, 0x6c, 0x65, + 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x6e, 0x65, 0x74, 0x64, 0x65, 0x76, + 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x64, 0x69, 0x73, 0x6b, 0x44, 0x65, + 0x6c, 0x65, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x64, 0x69, 0x73, 0x6b, + 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x28, 0x0a, 0x0f, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, + 0x69, 0x6f, 0x6e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0f, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, + 0x12, 0x2a, 0x0a, 0x10, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x44, 0x65, + 0x6c, 0x65, 0x74, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x66, 0x69, 0x6c, 0x65, + 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x1a, 0x0a, 0x08, + 0x61, 0x6c, 0x6c, 0x43, 0x6f, 0x6e, 0x66, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, + 0x61, 0x6c, 0x6c, 0x43, 0x6f, 0x6e, 0x66, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x6f, 0x72, 0x63, + 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x12, 0x1a, + 0x0a, 0x08, 0x63, 0x6f, 0x6e, 0x66, 0x4c, 0x69, 0x73, 0x74, 0x18, 0x08, 0x20, 0x03, 0x28, 0x09, + 0x52, 0x08, 0x63, 0x6f, 0x6e, 0x66, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x3e, 0x0a, 0x06, 0x74, 0x61, + 0x67, 0x41, 0x64, 0x64, 0x18, 0x09, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x77, 0x77, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x53, 0x65, 0x74, 0x50, 0x61, 0x72, - 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x2e, 0x4e, 0x65, 0x74, 0x54, 0x61, 0x67, 0x41, 0x64, 0x64, - 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x09, 0x6e, 0x65, 0x74, 0x54, 0x61, 0x67, 0x41, 0x64, 0x64, - 0x12, 0x4a, 0x0a, 0x0a, 0x69, 0x70, 0x6d, 0x69, 0x54, 0x61, 0x67, 0x41, 0x64, 0x64, 0x18, 0x0b, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x77, 0x77, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, - 0x43, 0x6f, 0x6e, 0x66, 0x53, 0x65, 0x74, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, - 0x2e, 0x49, 0x70, 0x6d, 0x69, 0x54, 0x61, 0x67, 0x41, 0x64, 0x64, 0x45, 0x6e, 0x74, 0x72, 0x79, - 0x52, 0x0a, 0x69, 0x70, 0x6d, 0x69, 0x54, 0x61, 0x67, 0x41, 0x64, 0x64, 0x12, 0x16, 0x0a, 0x06, - 0x74, 0x61, 0x67, 0x44, 0x65, 0x6c, 0x18, 0x0c, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x74, 0x61, - 0x67, 0x44, 0x65, 0x6c, 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x65, 0x74, 0x54, 0x61, 0x67, 0x44, 0x65, - 0x6c, 0x18, 0x0d, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x65, 0x74, 0x54, 0x61, 0x67, 0x44, - 0x65, 0x6c, 0x12, 0x1e, 0x0a, 0x0a, 0x69, 0x70, 0x6d, 0x69, 0x54, 0x61, 0x67, 0x44, 0x65, 0x6c, - 0x18, 0x0e, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x69, 0x70, 0x6d, 0x69, 0x54, 0x61, 0x67, 0x44, - 0x65, 0x6c, 0x12, 0x16, 0x0a, 0x06, 0x6e, 0x65, 0x74, 0x64, 0x65, 0x76, 0x18, 0x0f, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x06, 0x6e, 0x65, 0x74, 0x64, 0x65, 0x76, 0x1a, 0x39, 0x0a, 0x0b, 0x54, 0x61, + 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x2e, 0x54, 0x61, 0x67, 0x41, 0x64, 0x64, 0x45, 0x6e, 0x74, + 0x72, 0x79, 0x52, 0x06, 0x74, 0x61, 0x67, 0x41, 0x64, 0x64, 0x12, 0x47, 0x0a, 0x09, 0x6e, 0x65, + 0x74, 0x54, 0x61, 0x67, 0x41, 0x64, 0x64, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, + 0x77, 0x77, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x53, 0x65, 0x74, + 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x2e, 0x4e, 0x65, 0x74, 0x54, 0x61, 0x67, + 0x41, 0x64, 0x64, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x09, 0x6e, 0x65, 0x74, 0x54, 0x61, 0x67, + 0x41, 0x64, 0x64, 0x12, 0x4a, 0x0a, 0x0a, 0x69, 0x70, 0x6d, 0x69, 0x54, 0x61, 0x67, 0x41, 0x64, + 0x64, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x77, 0x77, 0x61, 0x70, 0x69, 0x2e, + 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x53, 0x65, 0x74, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, + 0x74, 0x65, 0x72, 0x2e, 0x49, 0x70, 0x6d, 0x69, 0x54, 0x61, 0x67, 0x41, 0x64, 0x64, 0x45, 0x6e, + 0x74, 0x72, 0x79, 0x52, 0x0a, 0x69, 0x70, 0x6d, 0x69, 0x54, 0x61, 0x67, 0x41, 0x64, 0x64, 0x12, + 0x16, 0x0a, 0x06, 0x74, 0x61, 0x67, 0x44, 0x65, 0x6c, 0x18, 0x0c, 0x20, 0x03, 0x28, 0x09, 0x52, + 0x06, 0x74, 0x61, 0x67, 0x44, 0x65, 0x6c, 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x65, 0x74, 0x54, 0x61, + 0x67, 0x44, 0x65, 0x6c, 0x18, 0x0d, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x65, 0x74, 0x54, + 0x61, 0x67, 0x44, 0x65, 0x6c, 0x12, 0x1e, 0x0a, 0x0a, 0x69, 0x70, 0x6d, 0x69, 0x54, 0x61, 0x67, + 0x44, 0x65, 0x6c, 0x18, 0x0e, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x69, 0x70, 0x6d, 0x69, 0x54, + 0x61, 0x67, 0x44, 0x65, 0x6c, 0x12, 0x16, 0x0a, 0x06, 0x6e, 0x65, 0x74, 0x64, 0x65, 0x76, 0x18, + 0x0f, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6e, 0x65, 0x74, 0x64, 0x65, 0x76, 0x1a, 0x39, 0x0a, + 0x0b, 0x54, 0x61, 0x67, 0x41, 0x64, 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, 0x14, + 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x3c, 0x0a, 0x0e, 0x4e, 0x65, 0x74, 0x54, + 0x61, 0x67, 0x41, 0x64, 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, 0x14, 0x0a, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x3d, 0x0a, 0x0f, 0x49, 0x70, 0x6d, 0x69, 0x54, 0x61, 0x67, 0x41, 0x64, 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, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x3c, 0x0a, 0x0e, 0x4e, 0x65, 0x74, 0x54, 0x61, 0x67, 0x41, - 0x64, 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, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, - 0x02, 0x38, 0x01, 0x1a, 0x3d, 0x0a, 0x0f, 0x49, 0x70, 0x6d, 0x69, 0x54, 0x61, 0x67, 0x41, 0x64, - 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, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, - 0x38, 0x01, 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, 0xfe, 0x09, 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, 0x67, 0x0a, 0x0d, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x43, 0x6f, - 0x70, 0x79, 0x12, 0x20, 0x2e, 0x77, 0x77, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, - 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x43, 0x6f, 0x70, 0x79, 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, 0x1c, 0x82, 0xd3, - 0xe4, 0x93, 0x02, 0x16, 0x22, 0x11, 0x2f, 0x76, 0x31, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, - 0x6e, 0x65, 0x72, 0x63, 0x6f, 0x70, 0x79, 0x3a, 0x01, 0x2a, 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, + 0x65, 0x3a, 0x02, 0x38, 0x01, 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, + 0x9e, 0x09, 0x0a, 0x05, 0x57, 0x57, 0x41, 0x70, 0x69, 0x12, 0x63, 0x0a, 0x0a, 0x49, 0x6d, 0x61, + 0x67, 0x65, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x12, 0x1d, 0x2e, 0x77, 0x77, 0x61, 0x70, 0x69, 0x2e, + 0x76, 0x31, 0x2e, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x50, 0x61, 0x72, + 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x1a, 0x1b, 0x2e, 0x77, 0x77, 0x61, 0x70, 0x69, 0x2e, 0x76, + 0x31, 0x2e, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x19, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x13, 0x22, 0x0e, 0x2f, 0x76, 0x31, + 0x2f, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x3a, 0x01, 0x2a, 0x12, 0x58, + 0x0a, 0x0b, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x1e, 0x2e, + 0x77, 0x77, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6d, 0x61, 0x67, 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, 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, 0x6d, 0x0a, 0x0f, - 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x12, - 0x22, 0x2e, 0x77, 0x77, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, - 0x69, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, + 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x11, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0b, 0x2a, 0x09, 0x2f, + 0x76, 0x31, 0x2f, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x12, 0x5b, 0x0a, 0x09, 0x49, 0x6d, 0x61, 0x67, + 0x65, 0x43, 0x6f, 0x70, 0x79, 0x12, 0x1c, 0x2e, 0x77, 0x77, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, + 0x2e, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x43, 0x6f, 0x70, 0x79, 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, 0x1e, 0x82, 0xd3, 0xe4, - 0x93, 0x02, 0x18, 0x22, 0x13, 0x2f, 0x76, 0x31, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, - 0x65, 0x72, 0x72, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x3a, 0x01, 0x2a, 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, - 0x43, 0x6f, 0x6e, 0x66, 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, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x18, 0x82, 0xd3, 0xe4, + 0x93, 0x02, 0x12, 0x22, 0x0d, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x63, 0x6f, + 0x70, 0x79, 0x3a, 0x01, 0x2a, 0x12, 0x60, 0x0a, 0x0b, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x49, 0x6d, + 0x70, 0x6f, 0x72, 0x74, 0x12, 0x1e, 0x2e, 0x77, 0x77, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, + 0x49, 0x6d, 0x61, 0x67, 0x65, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x50, 0x61, 0x72, 0x61, 0x6d, + 0x65, 0x74, 0x65, 0x72, 0x1a, 0x1b, 0x2e, 0x77, 0x77, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, + 0x49, 0x6d, 0x61, 0x67, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x14, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0e, 0x22, 0x09, 0x2f, 0x76, 0x31, 0x2f, 0x69, + 0x6d, 0x61, 0x67, 0x65, 0x3a, 0x01, 0x2a, 0x12, 0x53, 0x0a, 0x09, 0x49, 0x6d, 0x61, 0x67, 0x65, + 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, 0x1b, 0x2e, 0x77, + 0x77, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x4c, 0x69, 0x73, + 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x11, 0x82, 0xd3, 0xe4, 0x93, 0x02, + 0x0b, 0x12, 0x09, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x12, 0x5d, 0x0a, 0x09, + 0x49, 0x6d, 0x61, 0x67, 0x65, 0x53, 0x68, 0x6f, 0x77, 0x12, 0x1c, 0x2e, 0x77, 0x77, 0x61, 0x70, + 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x53, 0x68, 0x6f, 0x77, 0x50, 0x61, + 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x1a, 0x1b, 0x2e, 0x77, 0x77, 0x61, 0x70, 0x69, 0x2e, + 0x76, 0x31, 0x2e, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x53, 0x68, 0x6f, 0x77, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x15, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0f, 0x12, 0x0d, 0x2f, 0x76, + 0x31, 0x2f, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x73, 0x68, 0x6f, 0x77, 0x12, 0x61, 0x0a, 0x0b, 0x49, + 0x6d, 0x61, 0x67, 0x65, 0x52, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1e, 0x2e, 0x77, 0x77, 0x61, + 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x52, 0x65, 0x6e, 0x61, 0x6d, + 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, 0x1a, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x14, 0x22, 0x0f, 0x2f, 0x76, 0x31, 0x2f, + 0x69, 0x6d, 0x61, 0x67, 0x65, 0x72, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x3a, 0x01, 0x2a, 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, 0x43, 0x6f, 0x6e, 0x66, 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 ( @@ -2299,48 +2287,48 @@ func file_routes_proto_rawDescGZIP() []byte { var file_routes_proto_enumTypes = make([]protoimpl.EnumInfo, 1) var file_routes_proto_msgTypes = make([]protoimpl.MessageInfo, 37) var file_routes_proto_goTypes = []interface{}{ - (GetNodeList_ListType)(0), // 0: wwapi.v1.GetNodeList.ListType - (*NodeDBHash)(nil), // 1: wwapi.v1.NodeDBHash - (*ContainerBuildParameter)(nil), // 2: wwapi.v1.ContainerBuildParameter - (*ContainerDeleteParameter)(nil), // 3: wwapi.v1.ContainerDeleteParameter - (*ContainerCopyParameter)(nil), // 4: wwapi.v1.ContainerCopyParameter - (*ContainerImportParameter)(nil), // 5: wwapi.v1.ContainerImportParameter - (*ContainerInfo)(nil), // 6: wwapi.v1.ContainerInfo - (*ContainerListResponse)(nil), // 7: wwapi.v1.ContainerListResponse - (*ContainerShowParameter)(nil), // 8: wwapi.v1.ContainerShowParameter - (*ContainerShowResponse)(nil), // 9: wwapi.v1.ContainerShowResponse - (*ContainerSyncUserParameter)(nil), // 10: wwapi.v1.ContainerSyncUserParameter - (*ContainerRenameParameter)(nil), // 11: wwapi.v1.ContainerRenameParameter - (*NodeNames)(nil), // 12: wwapi.v1.NodeNames - (*NodeField)(nil), // 13: wwapi.v1.NodeField - (*NetDev)(nil), // 14: wwapi.v1.NetDev - (*NodeInfo)(nil), // 15: wwapi.v1.NodeInfo - (*NodeListResponse)(nil), // 16: wwapi.v1.NodeListResponse - (*GetNodeList)(nil), // 17: wwapi.v1.GetNodeList - (*NodeList)(nil), // 18: wwapi.v1.NodeList - (*GetProfileList)(nil), // 19: wwapi.v1.GetProfileList - (*ProfileList)(nil), // 20: wwapi.v1.ProfileList - (*NodeAddParameter)(nil), // 21: wwapi.v1.NodeAddParameter - (*NodeYaml)(nil), // 22: wwapi.v1.NodeYaml - (*NodeDeleteParameter)(nil), // 23: wwapi.v1.NodeDeleteParameter - (*ConfSetParameter)(nil), // 24: wwapi.v1.ConfSetParameter - (*NodeStatus)(nil), // 25: wwapi.v1.NodeStatus - (*NodeStatusResponse)(nil), // 26: wwapi.v1.NodeStatusResponse - (*VersionResponse)(nil), // 27: wwapi.v1.VersionResponse - (*CanWriteConfig)(nil), // 28: wwapi.v1.CanWriteConfig - nil, // 29: wwapi.v1.NetDev.FieldEntry - nil, // 30: wwapi.v1.NetDev.TagsEntry - nil, // 31: wwapi.v1.NodeInfo.FieldsEntry - nil, // 32: wwapi.v1.NodeInfo.NetDevsEntry - nil, // 33: wwapi.v1.NodeInfo.TagsEntry - nil, // 34: wwapi.v1.NodeInfo.KeysEntry - nil, // 35: wwapi.v1.ConfSetParameter.TagAddEntry - nil, // 36: wwapi.v1.ConfSetParameter.NetTagAddEntry - nil, // 37: wwapi.v1.ConfSetParameter.IpmiTagAddEntry - (*emptypb.Empty)(nil), // 38: google.protobuf.Empty + (GetNodeList_ListType)(0), // 0: wwapi.v1.GetNodeList.ListType + (*NodeDBHash)(nil), // 1: wwapi.v1.NodeDBHash + (*ImageBuildParameter)(nil), // 2: wwapi.v1.ImageBuildParameter + (*ImageDeleteParameter)(nil), // 3: wwapi.v1.ImageDeleteParameter + (*ImageCopyParameter)(nil), // 4: wwapi.v1.ImageCopyParameter + (*ImageImportParameter)(nil), // 5: wwapi.v1.ImageImportParameter + (*ImageInfo)(nil), // 6: wwapi.v1.ImageInfo + (*ImageListResponse)(nil), // 7: wwapi.v1.ImageListResponse + (*ImageShowParameter)(nil), // 8: wwapi.v1.ImageShowParameter + (*ImageShowResponse)(nil), // 9: wwapi.v1.ImageShowResponse + (*ImageSyncUserParameter)(nil), // 10: wwapi.v1.ImageSyncUserParameter + (*ImageRenameParameter)(nil), // 11: wwapi.v1.ImageRenameParameter + (*NodeNames)(nil), // 12: wwapi.v1.NodeNames + (*NodeField)(nil), // 13: wwapi.v1.NodeField + (*NetDev)(nil), // 14: wwapi.v1.NetDev + (*NodeInfo)(nil), // 15: wwapi.v1.NodeInfo + (*NodeListResponse)(nil), // 16: wwapi.v1.NodeListResponse + (*GetNodeList)(nil), // 17: wwapi.v1.GetNodeList + (*NodeList)(nil), // 18: wwapi.v1.NodeList + (*GetProfileList)(nil), // 19: wwapi.v1.GetProfileList + (*ProfileList)(nil), // 20: wwapi.v1.ProfileList + (*NodeAddParameter)(nil), // 21: wwapi.v1.NodeAddParameter + (*NodeYaml)(nil), // 22: wwapi.v1.NodeYaml + (*NodeDeleteParameter)(nil), // 23: wwapi.v1.NodeDeleteParameter + (*ConfSetParameter)(nil), // 24: wwapi.v1.ConfSetParameter + (*NodeStatus)(nil), // 25: wwapi.v1.NodeStatus + (*NodeStatusResponse)(nil), // 26: wwapi.v1.NodeStatusResponse + (*VersionResponse)(nil), // 27: wwapi.v1.VersionResponse + (*CanWriteConfig)(nil), // 28: wwapi.v1.CanWriteConfig + nil, // 29: wwapi.v1.NetDev.FieldEntry + nil, // 30: wwapi.v1.NetDev.TagsEntry + nil, // 31: wwapi.v1.NodeInfo.FieldsEntry + nil, // 32: wwapi.v1.NodeInfo.NetDevsEntry + nil, // 33: wwapi.v1.NodeInfo.TagsEntry + nil, // 34: wwapi.v1.NodeInfo.KeysEntry + nil, // 35: wwapi.v1.ConfSetParameter.TagAddEntry + nil, // 36: wwapi.v1.ConfSetParameter.NetTagAddEntry + nil, // 37: wwapi.v1.ConfSetParameter.IpmiTagAddEntry + (*emptypb.Empty)(nil), // 38: google.protobuf.Empty } var file_routes_proto_depIdxs = []int32{ - 6, // 0: wwapi.v1.ContainerListResponse.containers:type_name -> wwapi.v1.ContainerInfo + 6, // 0: wwapi.v1.ImageListResponse.images:type_name -> wwapi.v1.ImageInfo 29, // 1: wwapi.v1.NetDev.Field:type_name -> wwapi.v1.NetDev.FieldEntry 30, // 2: wwapi.v1.NetDev.Tags:type_name -> wwapi.v1.NetDev.TagsEntry 31, // 3: wwapi.v1.NodeInfo.Fields:type_name -> wwapi.v1.NodeInfo.FieldsEntry @@ -2359,26 +2347,26 @@ var file_routes_proto_depIdxs = []int32{ 14, // 16: wwapi.v1.NodeInfo.NetDevsEntry.value:type_name -> wwapi.v1.NetDev 13, // 17: wwapi.v1.NodeInfo.TagsEntry.value:type_name -> wwapi.v1.NodeField 13, // 18: wwapi.v1.NodeInfo.KeysEntry.value:type_name -> wwapi.v1.NodeField - 2, // 19: wwapi.v1.WWApi.ContainerBuild:input_type -> wwapi.v1.ContainerBuildParameter - 3, // 20: wwapi.v1.WWApi.ContainerDelete:input_type -> wwapi.v1.ContainerDeleteParameter - 4, // 21: wwapi.v1.WWApi.ContainerCopy:input_type -> wwapi.v1.ContainerCopyParameter - 5, // 22: wwapi.v1.WWApi.ContainerImport:input_type -> wwapi.v1.ContainerImportParameter - 38, // 23: wwapi.v1.WWApi.ContainerList:input_type -> google.protobuf.Empty - 8, // 24: wwapi.v1.WWApi.ContainerShow:input_type -> wwapi.v1.ContainerShowParameter - 11, // 25: wwapi.v1.WWApi.ContainerRename:input_type -> wwapi.v1.ContainerRenameParameter + 2, // 19: wwapi.v1.WWApi.ImageBuild:input_type -> wwapi.v1.ImageBuildParameter + 3, // 20: wwapi.v1.WWApi.ImageDelete:input_type -> wwapi.v1.ImageDeleteParameter + 4, // 21: wwapi.v1.WWApi.ImageCopy:input_type -> wwapi.v1.ImageCopyParameter + 5, // 22: wwapi.v1.WWApi.ImageImport:input_type -> wwapi.v1.ImageImportParameter + 38, // 23: wwapi.v1.WWApi.ImageList:input_type -> google.protobuf.Empty + 8, // 24: wwapi.v1.WWApi.ImageShow:input_type -> wwapi.v1.ImageShowParameter + 11, // 25: wwapi.v1.WWApi.ImageRename:input_type -> wwapi.v1.ImageRenameParameter 21, // 26: wwapi.v1.WWApi.NodeAdd:input_type -> wwapi.v1.NodeAddParameter 23, // 27: wwapi.v1.WWApi.NodeDelete:input_type -> wwapi.v1.NodeDeleteParameter 12, // 28: wwapi.v1.WWApi.NodeList:input_type -> wwapi.v1.NodeNames 24, // 29: wwapi.v1.WWApi.NodeSet:input_type -> wwapi.v1.ConfSetParameter 12, // 30: wwapi.v1.WWApi.NodeStatus:input_type -> wwapi.v1.NodeNames 38, // 31: wwapi.v1.WWApi.Version:input_type -> google.protobuf.Empty - 7, // 32: wwapi.v1.WWApi.ContainerBuild:output_type -> wwapi.v1.ContainerListResponse - 38, // 33: wwapi.v1.WWApi.ContainerDelete:output_type -> google.protobuf.Empty - 38, // 34: wwapi.v1.WWApi.ContainerCopy:output_type -> google.protobuf.Empty - 7, // 35: wwapi.v1.WWApi.ContainerImport:output_type -> wwapi.v1.ContainerListResponse - 7, // 36: wwapi.v1.WWApi.ContainerList:output_type -> wwapi.v1.ContainerListResponse - 9, // 37: wwapi.v1.WWApi.ContainerShow:output_type -> wwapi.v1.ContainerShowResponse - 38, // 38: wwapi.v1.WWApi.ContainerRename:output_type -> google.protobuf.Empty + 7, // 32: wwapi.v1.WWApi.ImageBuild:output_type -> wwapi.v1.ImageListResponse + 38, // 33: wwapi.v1.WWApi.ImageDelete:output_type -> google.protobuf.Empty + 38, // 34: wwapi.v1.WWApi.ImageCopy:output_type -> google.protobuf.Empty + 7, // 35: wwapi.v1.WWApi.ImageImport:output_type -> wwapi.v1.ImageListResponse + 7, // 36: wwapi.v1.WWApi.ImageList:output_type -> wwapi.v1.ImageListResponse + 9, // 37: wwapi.v1.WWApi.ImageShow:output_type -> wwapi.v1.ImageShowResponse + 38, // 38: wwapi.v1.WWApi.ImageRename:output_type -> google.protobuf.Empty 16, // 39: wwapi.v1.WWApi.NodeAdd:output_type -> wwapi.v1.NodeListResponse 38, // 40: wwapi.v1.WWApi.NodeDelete:output_type -> google.protobuf.Empty 16, // 41: wwapi.v1.WWApi.NodeList:output_type -> wwapi.v1.NodeListResponse @@ -2411,7 +2399,7 @@ func file_routes_proto_init() { } } file_routes_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ContainerBuildParameter); i { + switch v := v.(*ImageBuildParameter); i { case 0: return &v.state case 1: @@ -2423,7 +2411,7 @@ func file_routes_proto_init() { } } file_routes_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ContainerDeleteParameter); i { + switch v := v.(*ImageDeleteParameter); i { case 0: return &v.state case 1: @@ -2435,7 +2423,7 @@ func file_routes_proto_init() { } } file_routes_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ContainerCopyParameter); i { + switch v := v.(*ImageCopyParameter); i { case 0: return &v.state case 1: @@ -2447,7 +2435,7 @@ func file_routes_proto_init() { } } file_routes_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ContainerImportParameter); i { + switch v := v.(*ImageImportParameter); i { case 0: return &v.state case 1: @@ -2459,7 +2447,7 @@ func file_routes_proto_init() { } } file_routes_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ContainerInfo); i { + switch v := v.(*ImageInfo); i { case 0: return &v.state case 1: @@ -2471,7 +2459,7 @@ func file_routes_proto_init() { } } file_routes_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ContainerListResponse); i { + switch v := v.(*ImageListResponse); i { case 0: return &v.state case 1: @@ -2483,7 +2471,7 @@ func file_routes_proto_init() { } } file_routes_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ContainerShowParameter); i { + switch v := v.(*ImageShowParameter); i { case 0: return &v.state case 1: @@ -2495,7 +2483,7 @@ func file_routes_proto_init() { } } file_routes_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ContainerShowResponse); i { + switch v := v.(*ImageShowResponse); i { case 0: return &v.state case 1: @@ -2507,7 +2495,7 @@ func file_routes_proto_init() { } } file_routes_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ContainerSyncUserParameter); i { + switch v := v.(*ImageSyncUserParameter); i { case 0: return &v.state case 1: @@ -2519,7 +2507,7 @@ func file_routes_proto_init() { } } file_routes_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ContainerRenameParameter); i { + switch v := v.(*ImageRenameParameter); i { case 0: return &v.state case 1: diff --git a/internal/pkg/api/routes/wwapiv1/routes.pb.gw.go b/internal/pkg/api/routes/wwapiv1/routes.pb.gw.go index 60e6b30a..5de07714 100644 --- a/internal/pkg/api/routes/wwapiv1/routes.pb.gw.go +++ b/internal/pkg/api/routes/wwapiv1/routes.pb.gw.go @@ -32,8 +32,8 @@ var _ = runtime.String var _ = utilities.NewDoubleArray var _ = metadata.Join -func request_WWApi_ContainerBuild_0(ctx context.Context, marshaler runtime.Marshaler, client WWApiClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq ContainerBuildParameter +func request_WWApi_ImageBuild_0(ctx context.Context, marshaler runtime.Marshaler, client WWApiClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq ImageBuildParameter var metadata runtime.ServerMetadata newReader, berr := utilities.IOReaderFactory(req.Body) @@ -44,13 +44,13 @@ func request_WWApi_ContainerBuild_0(ctx context.Context, marshaler runtime.Marsh return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } - msg, err := client.ContainerBuild(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + msg, err := client.ImageBuild(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) return msg, metadata, err } -func local_request_WWApi_ContainerBuild_0(ctx context.Context, marshaler runtime.Marshaler, server WWApiServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq ContainerBuildParameter +func local_request_WWApi_ImageBuild_0(ctx context.Context, marshaler runtime.Marshaler, server WWApiServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq ImageBuildParameter var metadata runtime.ServerMetadata newReader, berr := utilities.IOReaderFactory(req.Body) @@ -61,49 +61,49 @@ func local_request_WWApi_ContainerBuild_0(ctx context.Context, marshaler runtime return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } - msg, err := server.ContainerBuild(ctx, &protoReq) + msg, err := server.ImageBuild(ctx, &protoReq) return msg, metadata, err } var ( - filter_WWApi_ContainerDelete_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)} + filter_WWApi_ImageDelete_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)} ) -func request_WWApi_ContainerDelete_0(ctx context.Context, marshaler runtime.Marshaler, client WWApiClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq ContainerDeleteParameter +func request_WWApi_ImageDelete_0(ctx context.Context, marshaler runtime.Marshaler, client WWApiClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq ImageDeleteParameter var metadata runtime.ServerMetadata if err := req.ParseForm(); err != nil { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } - if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_WWApi_ContainerDelete_0); err != nil { + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_WWApi_ImageDelete_0); err != nil { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } - msg, err := client.ContainerDelete(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + msg, err := client.ImageDelete(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) return msg, metadata, err } -func local_request_WWApi_ContainerDelete_0(ctx context.Context, marshaler runtime.Marshaler, server WWApiServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq ContainerDeleteParameter +func local_request_WWApi_ImageDelete_0(ctx context.Context, marshaler runtime.Marshaler, server WWApiServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq ImageDeleteParameter var metadata runtime.ServerMetadata if err := req.ParseForm(); err != nil { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } - if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_WWApi_ContainerDelete_0); err != nil { + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_WWApi_ImageDelete_0); err != nil { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } - msg, err := server.ContainerDelete(ctx, &protoReq) + msg, err := server.ImageDelete(ctx, &protoReq) return msg, metadata, err } -func request_WWApi_ContainerCopy_0(ctx context.Context, marshaler runtime.Marshaler, client WWApiClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq ContainerCopyParameter +func request_WWApi_ImageCopy_0(ctx context.Context, marshaler runtime.Marshaler, client WWApiClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq ImageCopyParameter var metadata runtime.ServerMetadata newReader, berr := utilities.IOReaderFactory(req.Body) @@ -114,13 +114,13 @@ func request_WWApi_ContainerCopy_0(ctx context.Context, marshaler runtime.Marsha return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } - msg, err := client.ContainerCopy(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + msg, err := client.ImageCopy(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) return msg, metadata, err } -func local_request_WWApi_ContainerCopy_0(ctx context.Context, marshaler runtime.Marshaler, server WWApiServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq ContainerCopyParameter +func local_request_WWApi_ImageCopy_0(ctx context.Context, marshaler runtime.Marshaler, server WWApiServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq ImageCopyParameter var metadata runtime.ServerMetadata newReader, berr := utilities.IOReaderFactory(req.Body) @@ -131,13 +131,13 @@ func local_request_WWApi_ContainerCopy_0(ctx context.Context, marshaler runtime. return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } - msg, err := server.ContainerCopy(ctx, &protoReq) + msg, err := server.ImageCopy(ctx, &protoReq) return msg, metadata, err } -func request_WWApi_ContainerImport_0(ctx context.Context, marshaler runtime.Marshaler, client WWApiClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq ContainerImportParameter +func request_WWApi_ImageImport_0(ctx context.Context, marshaler runtime.Marshaler, client WWApiClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq ImageImportParameter var metadata runtime.ServerMetadata newReader, berr := utilities.IOReaderFactory(req.Body) @@ -148,13 +148,13 @@ func request_WWApi_ContainerImport_0(ctx context.Context, marshaler runtime.Mars return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } - msg, err := client.ContainerImport(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + msg, err := client.ImageImport(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) return msg, metadata, err } -func local_request_WWApi_ContainerImport_0(ctx context.Context, marshaler runtime.Marshaler, server WWApiServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq ContainerImportParameter +func local_request_WWApi_ImageImport_0(ctx context.Context, marshaler runtime.Marshaler, server WWApiServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq ImageImportParameter var metadata runtime.ServerMetadata newReader, berr := utilities.IOReaderFactory(req.Body) @@ -165,67 +165,67 @@ func local_request_WWApi_ContainerImport_0(ctx context.Context, marshaler runtim return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } - msg, err := server.ContainerImport(ctx, &protoReq) + msg, err := server.ImageImport(ctx, &protoReq) return msg, metadata, err } -func request_WWApi_ContainerList_0(ctx context.Context, marshaler runtime.Marshaler, client WWApiClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { +func request_WWApi_ImageList_0(ctx context.Context, marshaler runtime.Marshaler, client WWApiClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { var protoReq emptypb.Empty var metadata runtime.ServerMetadata - msg, err := client.ContainerList(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + msg, err := client.ImageList(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) return msg, metadata, err } -func local_request_WWApi_ContainerList_0(ctx context.Context, marshaler runtime.Marshaler, server WWApiServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { +func local_request_WWApi_ImageList_0(ctx context.Context, marshaler runtime.Marshaler, server WWApiServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { var protoReq emptypb.Empty var metadata runtime.ServerMetadata - msg, err := server.ContainerList(ctx, &protoReq) + msg, err := server.ImageList(ctx, &protoReq) return msg, metadata, err } var ( - filter_WWApi_ContainerShow_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)} + filter_WWApi_ImageShow_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)} ) -func request_WWApi_ContainerShow_0(ctx context.Context, marshaler runtime.Marshaler, client WWApiClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq ContainerShowParameter +func request_WWApi_ImageShow_0(ctx context.Context, marshaler runtime.Marshaler, client WWApiClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq ImageShowParameter var metadata runtime.ServerMetadata if err := req.ParseForm(); err != nil { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } - if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_WWApi_ContainerShow_0); err != nil { + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_WWApi_ImageShow_0); err != nil { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } - msg, err := client.ContainerShow(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + msg, err := client.ImageShow(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) return msg, metadata, err } -func local_request_WWApi_ContainerShow_0(ctx context.Context, marshaler runtime.Marshaler, server WWApiServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq ContainerShowParameter +func local_request_WWApi_ImageShow_0(ctx context.Context, marshaler runtime.Marshaler, server WWApiServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq ImageShowParameter var metadata runtime.ServerMetadata if err := req.ParseForm(); err != nil { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } - if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_WWApi_ContainerShow_0); err != nil { + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_WWApi_ImageShow_0); err != nil { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } - msg, err := server.ContainerShow(ctx, &protoReq) + msg, err := server.ImageShow(ctx, &protoReq) return msg, metadata, err } -func request_WWApi_ContainerRename_0(ctx context.Context, marshaler runtime.Marshaler, client WWApiClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq ContainerRenameParameter +func request_WWApi_ImageRename_0(ctx context.Context, marshaler runtime.Marshaler, client WWApiClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq ImageRenameParameter var metadata runtime.ServerMetadata newReader, berr := utilities.IOReaderFactory(req.Body) @@ -236,13 +236,13 @@ func request_WWApi_ContainerRename_0(ctx context.Context, marshaler runtime.Mars return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } - msg, err := client.ContainerRename(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + msg, err := client.ImageRename(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) return msg, metadata, err } -func local_request_WWApi_ContainerRename_0(ctx context.Context, marshaler runtime.Marshaler, server WWApiServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq ContainerRenameParameter +func local_request_WWApi_ImageRename_0(ctx context.Context, marshaler runtime.Marshaler, server WWApiServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq ImageRenameParameter var metadata runtime.ServerMetadata newReader, berr := utilities.IOReaderFactory(req.Body) @@ -253,7 +253,7 @@ func local_request_WWApi_ContainerRename_0(ctx context.Context, marshaler runtim return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } - msg, err := server.ContainerRename(ctx, &protoReq) + msg, err := server.ImageRename(ctx, &protoReq) return msg, metadata, err } @@ -458,7 +458,7 @@ func local_request_WWApi_Version_0(ctx context.Context, marshaler runtime.Marsha // Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterWWApiHandlerFromEndpoint instead. func RegisterWWApiHandlerServer(ctx context.Context, mux *runtime.ServeMux, server WWApiServer) error { - mux.Handle("POST", pattern_WWApi_ContainerBuild_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + mux.Handle("POST", pattern_WWApi_ImageBuild_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() var stream runtime.ServerTransportStream @@ -466,12 +466,12 @@ func RegisterWWApiHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) var err error var annotatedContext context.Context - annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/wwapi.v1.WWApi/ContainerBuild", runtime.WithHTTPPathPattern("/v1/containerbuild")) + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/wwapi.v1.WWApi/ImageBuild", runtime.WithHTTPPathPattern("/v1/imagebuild")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := local_request_WWApi_ContainerBuild_0(annotatedContext, inboundMarshaler, server, req, pathParams) + resp, md, err := local_request_WWApi_ImageBuild_0(annotatedContext, inboundMarshaler, server, req, pathParams) md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) if err != nil { @@ -479,11 +479,11 @@ func RegisterWWApiHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv return } - forward_WWApi_ContainerBuild_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_WWApi_ImageBuild_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) - mux.Handle("DELETE", pattern_WWApi_ContainerDelete_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + mux.Handle("DELETE", pattern_WWApi_ImageDelete_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() var stream runtime.ServerTransportStream @@ -491,12 +491,12 @@ func RegisterWWApiHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) var err error var annotatedContext context.Context - annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/wwapi.v1.WWApi/ContainerDelete", runtime.WithHTTPPathPattern("/v1/container")) + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/wwapi.v1.WWApi/ImageDelete", runtime.WithHTTPPathPattern("/v1/image")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := local_request_WWApi_ContainerDelete_0(annotatedContext, inboundMarshaler, server, req, pathParams) + resp, md, err := local_request_WWApi_ImageDelete_0(annotatedContext, inboundMarshaler, server, req, pathParams) md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) if err != nil { @@ -504,11 +504,11 @@ func RegisterWWApiHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv return } - forward_WWApi_ContainerDelete_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_WWApi_ImageDelete_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) - mux.Handle("POST", pattern_WWApi_ContainerCopy_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + mux.Handle("POST", pattern_WWApi_ImageCopy_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() var stream runtime.ServerTransportStream @@ -516,12 +516,12 @@ func RegisterWWApiHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) var err error var annotatedContext context.Context - annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/wwapi.v1.WWApi/ContainerCopy", runtime.WithHTTPPathPattern("/v1/containercopy")) + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/wwapi.v1.WWApi/ImageCopy", runtime.WithHTTPPathPattern("/v1/imagecopy")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := local_request_WWApi_ContainerCopy_0(annotatedContext, inboundMarshaler, server, req, pathParams) + resp, md, err := local_request_WWApi_ImageCopy_0(annotatedContext, inboundMarshaler, server, req, pathParams) md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) if err != nil { @@ -529,11 +529,11 @@ func RegisterWWApiHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv return } - forward_WWApi_ContainerCopy_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_WWApi_ImageCopy_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) - mux.Handle("POST", pattern_WWApi_ContainerImport_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + mux.Handle("POST", pattern_WWApi_ImageImport_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() var stream runtime.ServerTransportStream @@ -541,12 +541,12 @@ func RegisterWWApiHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) var err error var annotatedContext context.Context - annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/wwapi.v1.WWApi/ContainerImport", runtime.WithHTTPPathPattern("/v1/container")) + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/wwapi.v1.WWApi/ImageImport", runtime.WithHTTPPathPattern("/v1/image")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := local_request_WWApi_ContainerImport_0(annotatedContext, inboundMarshaler, server, req, pathParams) + resp, md, err := local_request_WWApi_ImageImport_0(annotatedContext, inboundMarshaler, server, req, pathParams) md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) if err != nil { @@ -554,11 +554,11 @@ func RegisterWWApiHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv return } - forward_WWApi_ContainerImport_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_WWApi_ImageImport_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) - mux.Handle("GET", pattern_WWApi_ContainerList_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + mux.Handle("GET", pattern_WWApi_ImageList_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() var stream runtime.ServerTransportStream @@ -566,12 +566,12 @@ func RegisterWWApiHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) var err error var annotatedContext context.Context - annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/wwapi.v1.WWApi/ContainerList", runtime.WithHTTPPathPattern("/v1/container")) + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/wwapi.v1.WWApi/ImageList", runtime.WithHTTPPathPattern("/v1/image")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := local_request_WWApi_ContainerList_0(annotatedContext, inboundMarshaler, server, req, pathParams) + resp, md, err := local_request_WWApi_ImageList_0(annotatedContext, inboundMarshaler, server, req, pathParams) md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) if err != nil { @@ -579,11 +579,11 @@ func RegisterWWApiHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv return } - forward_WWApi_ContainerList_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_WWApi_ImageList_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) - mux.Handle("GET", pattern_WWApi_ContainerShow_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + mux.Handle("GET", pattern_WWApi_ImageShow_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() var stream runtime.ServerTransportStream @@ -591,12 +591,12 @@ func RegisterWWApiHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) var err error var annotatedContext context.Context - annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/wwapi.v1.WWApi/ContainerShow", runtime.WithHTTPPathPattern("/v1/containershow")) + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/wwapi.v1.WWApi/ImageShow", runtime.WithHTTPPathPattern("/v1/imageshow")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := local_request_WWApi_ContainerShow_0(annotatedContext, inboundMarshaler, server, req, pathParams) + resp, md, err := local_request_WWApi_ImageShow_0(annotatedContext, inboundMarshaler, server, req, pathParams) md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) if err != nil { @@ -604,11 +604,11 @@ func RegisterWWApiHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv return } - forward_WWApi_ContainerShow_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_WWApi_ImageShow_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) - mux.Handle("POST", pattern_WWApi_ContainerRename_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + mux.Handle("POST", pattern_WWApi_ImageRename_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() var stream runtime.ServerTransportStream @@ -616,12 +616,12 @@ func RegisterWWApiHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) var err error var annotatedContext context.Context - annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/wwapi.v1.WWApi/ContainerRename", runtime.WithHTTPPathPattern("/v1/containerrename")) + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/wwapi.v1.WWApi/ImageRename", runtime.WithHTTPPathPattern("/v1/imagerename")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := local_request_WWApi_ContainerRename_0(annotatedContext, inboundMarshaler, server, req, pathParams) + resp, md, err := local_request_WWApi_ImageRename_0(annotatedContext, inboundMarshaler, server, req, pathParams) md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) if err != nil { @@ -629,7 +629,7 @@ func RegisterWWApiHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv return } - forward_WWApi_ContainerRename_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_WWApi_ImageRename_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -824,157 +824,157 @@ func RegisterWWApiHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc // "WWApiClient" to call the correct interceptors. func RegisterWWApiHandlerClient(ctx context.Context, mux *runtime.ServeMux, client WWApiClient) error { - mux.Handle("POST", pattern_WWApi_ContainerBuild_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + mux.Handle("POST", pattern_WWApi_ImageBuild_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) var err error var annotatedContext context.Context - annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/wwapi.v1.WWApi/ContainerBuild", runtime.WithHTTPPathPattern("/v1/containerbuild")) + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/wwapi.v1.WWApi/ImageBuild", runtime.WithHTTPPathPattern("/v1/imagebuild")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := request_WWApi_ContainerBuild_0(annotatedContext, inboundMarshaler, client, req, pathParams) + resp, md, err := request_WWApi_ImageBuild_0(annotatedContext, inboundMarshaler, client, req, pathParams) annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) if err != nil { runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } - forward_WWApi_ContainerBuild_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_WWApi_ImageBuild_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) - mux.Handle("DELETE", pattern_WWApi_ContainerDelete_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + mux.Handle("DELETE", pattern_WWApi_ImageDelete_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) var err error var annotatedContext context.Context - annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/wwapi.v1.WWApi/ContainerDelete", runtime.WithHTTPPathPattern("/v1/container")) + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/wwapi.v1.WWApi/ImageDelete", runtime.WithHTTPPathPattern("/v1/image")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := request_WWApi_ContainerDelete_0(annotatedContext, inboundMarshaler, client, req, pathParams) + resp, md, err := request_WWApi_ImageDelete_0(annotatedContext, inboundMarshaler, client, req, pathParams) annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) if err != nil { runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } - forward_WWApi_ContainerDelete_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_WWApi_ImageDelete_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) - mux.Handle("POST", pattern_WWApi_ContainerCopy_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + mux.Handle("POST", pattern_WWApi_ImageCopy_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) var err error var annotatedContext context.Context - annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/wwapi.v1.WWApi/ContainerCopy", runtime.WithHTTPPathPattern("/v1/containercopy")) + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/wwapi.v1.WWApi/ImageCopy", runtime.WithHTTPPathPattern("/v1/imagecopy")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := request_WWApi_ContainerCopy_0(annotatedContext, inboundMarshaler, client, req, pathParams) + resp, md, err := request_WWApi_ImageCopy_0(annotatedContext, inboundMarshaler, client, req, pathParams) annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) if err != nil { runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } - forward_WWApi_ContainerCopy_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_WWApi_ImageCopy_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) - mux.Handle("POST", pattern_WWApi_ContainerImport_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + mux.Handle("POST", pattern_WWApi_ImageImport_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) var err error var annotatedContext context.Context - annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/wwapi.v1.WWApi/ContainerImport", runtime.WithHTTPPathPattern("/v1/container")) + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/wwapi.v1.WWApi/ImageImport", runtime.WithHTTPPathPattern("/v1/image")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := request_WWApi_ContainerImport_0(annotatedContext, inboundMarshaler, client, req, pathParams) + resp, md, err := request_WWApi_ImageImport_0(annotatedContext, inboundMarshaler, client, req, pathParams) annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) if err != nil { runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } - forward_WWApi_ContainerImport_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_WWApi_ImageImport_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) - mux.Handle("GET", pattern_WWApi_ContainerList_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + mux.Handle("GET", pattern_WWApi_ImageList_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) var err error var annotatedContext context.Context - annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/wwapi.v1.WWApi/ContainerList", runtime.WithHTTPPathPattern("/v1/container")) + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/wwapi.v1.WWApi/ImageList", runtime.WithHTTPPathPattern("/v1/image")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := request_WWApi_ContainerList_0(annotatedContext, inboundMarshaler, client, req, pathParams) + resp, md, err := request_WWApi_ImageList_0(annotatedContext, inboundMarshaler, client, req, pathParams) annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) if err != nil { runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } - forward_WWApi_ContainerList_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_WWApi_ImageList_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) - mux.Handle("GET", pattern_WWApi_ContainerShow_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + mux.Handle("GET", pattern_WWApi_ImageShow_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) var err error var annotatedContext context.Context - annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/wwapi.v1.WWApi/ContainerShow", runtime.WithHTTPPathPattern("/v1/containershow")) + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/wwapi.v1.WWApi/ImageShow", runtime.WithHTTPPathPattern("/v1/imageshow")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := request_WWApi_ContainerShow_0(annotatedContext, inboundMarshaler, client, req, pathParams) + resp, md, err := request_WWApi_ImageShow_0(annotatedContext, inboundMarshaler, client, req, pathParams) annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) if err != nil { runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } - forward_WWApi_ContainerShow_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_WWApi_ImageShow_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) - mux.Handle("POST", pattern_WWApi_ContainerRename_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + mux.Handle("POST", pattern_WWApi_ImageRename_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) var err error var annotatedContext context.Context - annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/wwapi.v1.WWApi/ContainerRename", runtime.WithHTTPPathPattern("/v1/containerrename")) + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/wwapi.v1.WWApi/ImageRename", runtime.WithHTTPPathPattern("/v1/imagerename")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := request_WWApi_ContainerRename_0(annotatedContext, inboundMarshaler, client, req, pathParams) + resp, md, err := request_WWApi_ImageRename_0(annotatedContext, inboundMarshaler, client, req, pathParams) annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) if err != nil { runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } - forward_WWApi_ContainerRename_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_WWApi_ImageRename_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -1114,19 +1114,19 @@ func RegisterWWApiHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie } var ( - pattern_WWApi_ContainerBuild_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"v1", "containerbuild"}, "")) + pattern_WWApi_ImageBuild_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"v1", "imagebuild"}, "")) - pattern_WWApi_ContainerDelete_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"v1", "container"}, "")) + pattern_WWApi_ImageDelete_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"v1", "image"}, "")) - pattern_WWApi_ContainerCopy_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"v1", "containercopy"}, "")) + pattern_WWApi_ImageCopy_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"v1", "imagecopy"}, "")) - pattern_WWApi_ContainerImport_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"v1", "container"}, "")) + pattern_WWApi_ImageImport_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"v1", "image"}, "")) - pattern_WWApi_ContainerList_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"v1", "container"}, "")) + pattern_WWApi_ImageList_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"v1", "image"}, "")) - pattern_WWApi_ContainerShow_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"v1", "containershow"}, "")) + pattern_WWApi_ImageShow_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"v1", "imageshow"}, "")) - pattern_WWApi_ContainerRename_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"v1", "containerrename"}, "")) + pattern_WWApi_ImageRename_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"v1", "imagerename"}, "")) pattern_WWApi_NodeAdd_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"v1", "node"}, "")) @@ -1142,19 +1142,19 @@ var ( ) var ( - forward_WWApi_ContainerBuild_0 = runtime.ForwardResponseMessage + forward_WWApi_ImageBuild_0 = runtime.ForwardResponseMessage - forward_WWApi_ContainerDelete_0 = runtime.ForwardResponseMessage + forward_WWApi_ImageDelete_0 = runtime.ForwardResponseMessage - forward_WWApi_ContainerCopy_0 = runtime.ForwardResponseMessage + forward_WWApi_ImageCopy_0 = runtime.ForwardResponseMessage - forward_WWApi_ContainerImport_0 = runtime.ForwardResponseMessage + forward_WWApi_ImageImport_0 = runtime.ForwardResponseMessage - forward_WWApi_ContainerList_0 = runtime.ForwardResponseMessage + forward_WWApi_ImageList_0 = runtime.ForwardResponseMessage - forward_WWApi_ContainerShow_0 = runtime.ForwardResponseMessage + forward_WWApi_ImageShow_0 = runtime.ForwardResponseMessage - forward_WWApi_ContainerRename_0 = runtime.ForwardResponseMessage + forward_WWApi_ImageRename_0 = runtime.ForwardResponseMessage forward_WWApi_NodeAdd_0 = runtime.ForwardResponseMessage diff --git a/internal/pkg/api/routes/wwapiv1/routes_grpc.pb.go b/internal/pkg/api/routes/wwapiv1/routes_grpc.pb.go index a322c627..2bb1a1df 100644 --- a/internal/pkg/api/routes/wwapiv1/routes_grpc.pb.go +++ b/internal/pkg/api/routes/wwapiv1/routes_grpc.pb.go @@ -23,19 +23,19 @@ const _ = grpc.SupportPackageIsVersion7 // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. type WWApiClient interface { - // ContainerBuild builds zero or more containers. - ContainerBuild(ctx context.Context, in *ContainerBuildParameter, opts ...grpc.CallOption) (*ContainerListResponse, error) - // ContainerDelete removes one or more container from Warewulf management. - ContainerDelete(ctx context.Context, in *ContainerDeleteParameter, opts ...grpc.CallOption) (*emptypb.Empty, error) - ContainerCopy(ctx context.Context, in *ContainerCopyParameter, opts ...grpc.CallOption) (*emptypb.Empty, error) - // ContainerImport imports a container to Warewulf. - ContainerImport(ctx context.Context, in *ContainerImportParameter, opts ...grpc.CallOption) (*ContainerListResponse, error) - // ContainerList lists ContainerInfo for each container. - ContainerList(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*ContainerListResponse, error) - // ContainerShow lists ContainerShow for each container. - ContainerShow(ctx context.Context, in *ContainerShowParameter, opts ...grpc.CallOption) (*ContainerShowResponse, error) - // ContainerRename renames the container - ContainerRename(ctx context.Context, in *ContainerRenameParameter, opts ...grpc.CallOption) (*emptypb.Empty, error) + // ImageBuild builds zero or more images. + ImageBuild(ctx context.Context, in *ImageBuildParameter, opts ...grpc.CallOption) (*ImageListResponse, error) + // ImageDelete removes one or more image from Warewulf management. + ImageDelete(ctx context.Context, in *ImageDeleteParameter, opts ...grpc.CallOption) (*emptypb.Empty, error) + ImageCopy(ctx context.Context, in *ImageCopyParameter, opts ...grpc.CallOption) (*emptypb.Empty, error) + // ImageImport imports an image to Warewulf. + ImageImport(ctx context.Context, in *ImageImportParameter, opts ...grpc.CallOption) (*ImageListResponse, error) + // ImageList lists ImageInfo for each image. + ImageList(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*ImageListResponse, error) + // ImageShow lists ImageShow for each image. + ImageShow(ctx context.Context, in *ImageShowParameter, opts ...grpc.CallOption) (*ImageShowResponse, error) + // ImageRename renames the image + ImageRename(ctx context.Context, in *ImageRenameParameter, opts ...grpc.CallOption) (*emptypb.Empty, error) // NodeAdd adds one or more nodes for management by Warewulf and returns // the added nodes. Node fields may be shimmed in per profiles. NodeAdd(ctx context.Context, in *NodeAddParameter, opts ...grpc.CallOption) (*NodeListResponse, error) @@ -61,63 +61,63 @@ func NewWWApiClient(cc grpc.ClientConnInterface) WWApiClient { return &wWApiClient{cc} } -func (c *wWApiClient) ContainerBuild(ctx context.Context, in *ContainerBuildParameter, opts ...grpc.CallOption) (*ContainerListResponse, error) { - out := new(ContainerListResponse) - err := c.cc.Invoke(ctx, "/wwapi.v1.WWApi/ContainerBuild", in, out, opts...) +func (c *wWApiClient) ImageBuild(ctx context.Context, in *ImageBuildParameter, opts ...grpc.CallOption) (*ImageListResponse, error) { + out := new(ImageListResponse) + err := c.cc.Invoke(ctx, "/wwapi.v1.WWApi/ImageBuild", in, out, opts...) if err != nil { return nil, err } return out, nil } -func (c *wWApiClient) ContainerDelete(ctx context.Context, in *ContainerDeleteParameter, opts ...grpc.CallOption) (*emptypb.Empty, error) { +func (c *wWApiClient) ImageDelete(ctx context.Context, in *ImageDeleteParameter, opts ...grpc.CallOption) (*emptypb.Empty, error) { out := new(emptypb.Empty) - err := c.cc.Invoke(ctx, "/wwapi.v1.WWApi/ContainerDelete", in, out, opts...) + err := c.cc.Invoke(ctx, "/wwapi.v1.WWApi/ImageDelete", in, out, opts...) if err != nil { return nil, err } return out, nil } -func (c *wWApiClient) ContainerCopy(ctx context.Context, in *ContainerCopyParameter, opts ...grpc.CallOption) (*emptypb.Empty, error) { +func (c *wWApiClient) ImageCopy(ctx context.Context, in *ImageCopyParameter, opts ...grpc.CallOption) (*emptypb.Empty, error) { out := new(emptypb.Empty) - err := c.cc.Invoke(ctx, "/wwapi.v1.WWApi/ContainerCopy", in, out, opts...) + err := c.cc.Invoke(ctx, "/wwapi.v1.WWApi/ImageCopy", in, out, opts...) if err != nil { return nil, err } return out, nil } -func (c *wWApiClient) ContainerImport(ctx context.Context, in *ContainerImportParameter, opts ...grpc.CallOption) (*ContainerListResponse, error) { - out := new(ContainerListResponse) - err := c.cc.Invoke(ctx, "/wwapi.v1.WWApi/ContainerImport", in, out, opts...) +func (c *wWApiClient) ImageImport(ctx context.Context, in *ImageImportParameter, opts ...grpc.CallOption) (*ImageListResponse, error) { + out := new(ImageListResponse) + err := c.cc.Invoke(ctx, "/wwapi.v1.WWApi/ImageImport", in, out, opts...) if err != nil { return nil, err } return out, nil } -func (c *wWApiClient) ContainerList(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*ContainerListResponse, error) { - out := new(ContainerListResponse) - err := c.cc.Invoke(ctx, "/wwapi.v1.WWApi/ContainerList", in, out, opts...) +func (c *wWApiClient) ImageList(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*ImageListResponse, error) { + out := new(ImageListResponse) + err := c.cc.Invoke(ctx, "/wwapi.v1.WWApi/ImageList", in, out, opts...) if err != nil { return nil, err } return out, nil } -func (c *wWApiClient) ContainerShow(ctx context.Context, in *ContainerShowParameter, opts ...grpc.CallOption) (*ContainerShowResponse, error) { - out := new(ContainerShowResponse) - err := c.cc.Invoke(ctx, "/wwapi.v1.WWApi/ContainerShow", in, out, opts...) +func (c *wWApiClient) ImageShow(ctx context.Context, in *ImageShowParameter, opts ...grpc.CallOption) (*ImageShowResponse, error) { + out := new(ImageShowResponse) + err := c.cc.Invoke(ctx, "/wwapi.v1.WWApi/ImageShow", in, out, opts...) if err != nil { return nil, err } return out, nil } -func (c *wWApiClient) ContainerRename(ctx context.Context, in *ContainerRenameParameter, opts ...grpc.CallOption) (*emptypb.Empty, error) { +func (c *wWApiClient) ImageRename(ctx context.Context, in *ImageRenameParameter, opts ...grpc.CallOption) (*emptypb.Empty, error) { out := new(emptypb.Empty) - err := c.cc.Invoke(ctx, "/wwapi.v1.WWApi/ContainerRename", in, out, opts...) + err := c.cc.Invoke(ctx, "/wwapi.v1.WWApi/ImageRename", in, out, opts...) if err != nil { return nil, err } @@ -182,19 +182,19 @@ func (c *wWApiClient) Version(ctx context.Context, in *emptypb.Empty, opts ...gr // All implementations must embed UnimplementedWWApiServer // for forward compatibility type WWApiServer interface { - // ContainerBuild builds zero or more containers. - ContainerBuild(context.Context, *ContainerBuildParameter) (*ContainerListResponse, error) - // ContainerDelete removes one or more container from Warewulf management. - ContainerDelete(context.Context, *ContainerDeleteParameter) (*emptypb.Empty, error) - ContainerCopy(context.Context, *ContainerCopyParameter) (*emptypb.Empty, error) - // ContainerImport imports a container to Warewulf. - ContainerImport(context.Context, *ContainerImportParameter) (*ContainerListResponse, error) - // ContainerList lists ContainerInfo for each container. - ContainerList(context.Context, *emptypb.Empty) (*ContainerListResponse, error) - // ContainerShow lists ContainerShow for each container. - ContainerShow(context.Context, *ContainerShowParameter) (*ContainerShowResponse, error) - // ContainerRename renames the container - ContainerRename(context.Context, *ContainerRenameParameter) (*emptypb.Empty, error) + // ImageBuild builds zero or more images. + ImageBuild(context.Context, *ImageBuildParameter) (*ImageListResponse, error) + // ImageDelete removes one or more image from Warewulf management. + ImageDelete(context.Context, *ImageDeleteParameter) (*emptypb.Empty, error) + ImageCopy(context.Context, *ImageCopyParameter) (*emptypb.Empty, error) + // ImageImport imports an image to Warewulf. + ImageImport(context.Context, *ImageImportParameter) (*ImageListResponse, error) + // ImageList lists ImageInfo for each image. + ImageList(context.Context, *emptypb.Empty) (*ImageListResponse, error) + // ImageShow lists ImageShow for each image. + ImageShow(context.Context, *ImageShowParameter) (*ImageShowResponse, error) + // ImageRename renames the image + ImageRename(context.Context, *ImageRenameParameter) (*emptypb.Empty, error) // NodeAdd adds one or more nodes for management by Warewulf and returns // the added nodes. Node fields may be shimmed in per profiles. NodeAdd(context.Context, *NodeAddParameter) (*NodeListResponse, error) @@ -217,26 +217,26 @@ type WWApiServer interface { type UnimplementedWWApiServer struct { } -func (UnimplementedWWApiServer) ContainerBuild(context.Context, *ContainerBuildParameter) (*ContainerListResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method ContainerBuild not implemented") +func (UnimplementedWWApiServer) ImageBuild(context.Context, *ImageBuildParameter) (*ImageListResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ImageBuild not implemented") } -func (UnimplementedWWApiServer) ContainerDelete(context.Context, *ContainerDeleteParameter) (*emptypb.Empty, error) { - return nil, status.Errorf(codes.Unimplemented, "method ContainerDelete not implemented") +func (UnimplementedWWApiServer) ImageDelete(context.Context, *ImageDeleteParameter) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method ImageDelete not implemented") } -func (UnimplementedWWApiServer) ContainerCopy(context.Context, *ContainerCopyParameter) (*emptypb.Empty, error) { - return nil, status.Errorf(codes.Unimplemented, "method ContainerCopy not implemented") +func (UnimplementedWWApiServer) ImageCopy(context.Context, *ImageCopyParameter) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method ImageCopy not implemented") } -func (UnimplementedWWApiServer) ContainerImport(context.Context, *ContainerImportParameter) (*ContainerListResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method ContainerImport not implemented") +func (UnimplementedWWApiServer) ImageImport(context.Context, *ImageImportParameter) (*ImageListResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ImageImport not implemented") } -func (UnimplementedWWApiServer) ContainerList(context.Context, *emptypb.Empty) (*ContainerListResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method ContainerList not implemented") +func (UnimplementedWWApiServer) ImageList(context.Context, *emptypb.Empty) (*ImageListResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ImageList not implemented") } -func (UnimplementedWWApiServer) ContainerShow(context.Context, *ContainerShowParameter) (*ContainerShowResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method ContainerShow not implemented") +func (UnimplementedWWApiServer) ImageShow(context.Context, *ImageShowParameter) (*ImageShowResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ImageShow not implemented") } -func (UnimplementedWWApiServer) ContainerRename(context.Context, *ContainerRenameParameter) (*emptypb.Empty, error) { - return nil, status.Errorf(codes.Unimplemented, "method ContainerRename not implemented") +func (UnimplementedWWApiServer) ImageRename(context.Context, *ImageRenameParameter) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method ImageRename not implemented") } func (UnimplementedWWApiServer) NodeAdd(context.Context, *NodeAddParameter) (*NodeListResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method NodeAdd not implemented") @@ -269,128 +269,128 @@ func RegisterWWApiServer(s grpc.ServiceRegistrar, srv WWApiServer) { s.RegisterService(&WWApi_ServiceDesc, srv) } -func _WWApi_ContainerBuild_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(ContainerBuildParameter) +func _WWApi_ImageBuild_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ImageBuildParameter) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(WWApiServer).ContainerBuild(ctx, in) + return srv.(WWApiServer).ImageBuild(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/wwapi.v1.WWApi/ContainerBuild", + FullMethod: "/wwapi.v1.WWApi/ImageBuild", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(WWApiServer).ContainerBuild(ctx, req.(*ContainerBuildParameter)) + return srv.(WWApiServer).ImageBuild(ctx, req.(*ImageBuildParameter)) } return interceptor(ctx, in, info, handler) } -func _WWApi_ContainerDelete_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(ContainerDeleteParameter) +func _WWApi_ImageDelete_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ImageDeleteParameter) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(WWApiServer).ContainerDelete(ctx, in) + return srv.(WWApiServer).ImageDelete(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/wwapi.v1.WWApi/ContainerDelete", + FullMethod: "/wwapi.v1.WWApi/ImageDelete", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(WWApiServer).ContainerDelete(ctx, req.(*ContainerDeleteParameter)) + return srv.(WWApiServer).ImageDelete(ctx, req.(*ImageDeleteParameter)) } return interceptor(ctx, in, info, handler) } -func _WWApi_ContainerCopy_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(ContainerCopyParameter) +func _WWApi_ImageCopy_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ImageCopyParameter) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(WWApiServer).ContainerCopy(ctx, in) + return srv.(WWApiServer).ImageCopy(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/wwapi.v1.WWApi/ContainerCopy", + FullMethod: "/wwapi.v1.WWApi/ImageCopy", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(WWApiServer).ContainerCopy(ctx, req.(*ContainerCopyParameter)) + return srv.(WWApiServer).ImageCopy(ctx, req.(*ImageCopyParameter)) } return interceptor(ctx, in, info, handler) } -func _WWApi_ContainerImport_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(ContainerImportParameter) +func _WWApi_ImageImport_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ImageImportParameter) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(WWApiServer).ContainerImport(ctx, in) + return srv.(WWApiServer).ImageImport(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/wwapi.v1.WWApi/ContainerImport", + FullMethod: "/wwapi.v1.WWApi/ImageImport", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(WWApiServer).ContainerImport(ctx, req.(*ContainerImportParameter)) + return srv.(WWApiServer).ImageImport(ctx, req.(*ImageImportParameter)) } return interceptor(ctx, in, info, handler) } -func _WWApi_ContainerList_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { +func _WWApi_ImageList_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(emptypb.Empty) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(WWApiServer).ContainerList(ctx, in) + return srv.(WWApiServer).ImageList(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/wwapi.v1.WWApi/ContainerList", + FullMethod: "/wwapi.v1.WWApi/ImageList", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(WWApiServer).ContainerList(ctx, req.(*emptypb.Empty)) + return srv.(WWApiServer).ImageList(ctx, req.(*emptypb.Empty)) } return interceptor(ctx, in, info, handler) } -func _WWApi_ContainerShow_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(ContainerShowParameter) +func _WWApi_ImageShow_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ImageShowParameter) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(WWApiServer).ContainerShow(ctx, in) + return srv.(WWApiServer).ImageShow(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/wwapi.v1.WWApi/ContainerShow", + FullMethod: "/wwapi.v1.WWApi/ImageShow", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(WWApiServer).ContainerShow(ctx, req.(*ContainerShowParameter)) + return srv.(WWApiServer).ImageShow(ctx, req.(*ImageShowParameter)) } return interceptor(ctx, in, info, handler) } -func _WWApi_ContainerRename_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(ContainerRenameParameter) +func _WWApi_ImageRename_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ImageRenameParameter) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(WWApiServer).ContainerRename(ctx, in) + return srv.(WWApiServer).ImageRename(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/wwapi.v1.WWApi/ContainerRename", + FullMethod: "/wwapi.v1.WWApi/ImageRename", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(WWApiServer).ContainerRename(ctx, req.(*ContainerRenameParameter)) + return srv.(WWApiServer).ImageRename(ctx, req.(*ImageRenameParameter)) } return interceptor(ctx, in, info, handler) } @@ -511,32 +511,32 @@ var WWApi_ServiceDesc = grpc.ServiceDesc{ HandlerType: (*WWApiServer)(nil), Methods: []grpc.MethodDesc{ { - MethodName: "ContainerBuild", - Handler: _WWApi_ContainerBuild_Handler, + MethodName: "ImageBuild", + Handler: _WWApi_ImageBuild_Handler, }, { - MethodName: "ContainerDelete", - Handler: _WWApi_ContainerDelete_Handler, + MethodName: "ImageDelete", + Handler: _WWApi_ImageDelete_Handler, }, { - MethodName: "ContainerCopy", - Handler: _WWApi_ContainerCopy_Handler, + MethodName: "ImageCopy", + Handler: _WWApi_ImageCopy_Handler, }, { - MethodName: "ContainerImport", - Handler: _WWApi_ContainerImport_Handler, + MethodName: "ImageImport", + Handler: _WWApi_ImageImport_Handler, }, { - MethodName: "ContainerList", - Handler: _WWApi_ContainerList_Handler, + MethodName: "ImageList", + Handler: _WWApi_ImageList_Handler, }, { - MethodName: "ContainerShow", - Handler: _WWApi_ContainerShow_Handler, + MethodName: "ImageShow", + Handler: _WWApi_ImageShow_Handler, }, { - MethodName: "ContainerRename", - Handler: _WWApi_ContainerRename_Handler, + MethodName: "ImageRename", + Handler: _WWApi_ImageRename_Handler, }, { MethodName: "NodeAdd", diff --git a/internal/pkg/config/mounts.go b/internal/pkg/config/mounts.go index bc4cf920..80e316cd 100644 --- a/internal/pkg/config/mounts.go +++ b/internal/pkg/config/mounts.go @@ -1,13 +1,13 @@ package config -// A MountEntry represents a bind mount that is applied to a container +// A MountEntry represents a bind mount that is applied to an image // during exec and shell. type MountEntry struct { Source string `yaml:"source"` Dest string `yaml:"dest,omitempty"` ReadOnlyP *bool `yaml:"readonly,omitempty"` Options string `yaml:"options,omitempty"` // ignored at the moment - CopyP *bool `yaml:"copy,omitempty"` // temporarily copy the file into the container + CopyP *bool `yaml:"copy,omitempty"` // temporarily copy the file into the image } func (this MountEntry) ReadOnly() bool { diff --git a/internal/pkg/config/root.go b/internal/pkg/config/root.go index 8655b901..50796e8b 100644 --- a/internal/pkg/config/root.go +++ b/internal/pkg/config/root.go @@ -27,21 +27,21 @@ var cachedConf WarewulfYaml // some information about the Warewulf server locally, and has // [WarewulfConf], [DHCPConf], [TFTPConf], and [NFSConf] sub-sections. type WarewulfYaml struct { - Comment string `yaml:"comment,omitempty"` - Ipaddr string `yaml:"ipaddr,omitempty"` - Ipaddr6 string `yaml:"ipaddr6,omitempty"` - Netmask string `yaml:"netmask,omitempty"` - Network string `yaml:"network,omitempty"` - Ipv6net string `yaml:"ipv6net,omitempty"` - Fqdn string `yaml:"fqdn,omitempty"` - Warewulf *WarewulfConf `yaml:"warewulf,omitempty"` - DHCP *DHCPConf `yaml:"dhcp,omitempty"` - TFTP *TFTPConf `yaml:"tftp,omitempty"` - NFS *NFSConf `yaml:"nfs,omitempty"` - SSH *SSHConf `yaml:"ssh,omitempty"` - MountsContainer []*MountEntry `yaml:"container mounts,omitempty" default:"[{\"source\": \"/etc/resolv.conf\", \"dest\": \"/etc/resolv.conf\"}]"` - Paths *BuildConfig `yaml:"paths,omitempty"` - WWClient *WWClientConf `yaml:"wwclient,omitempty"` + Comment string `yaml:"comment,omitempty"` + Ipaddr string `yaml:"ipaddr,omitempty"` + Ipaddr6 string `yaml:"ipaddr6,omitempty"` + Netmask string `yaml:"netmask,omitempty"` + Network string `yaml:"network,omitempty"` + Ipv6net string `yaml:"ipv6net,omitempty"` + Fqdn string `yaml:"fqdn,omitempty"` + Warewulf *WarewulfConf `yaml:"warewulf,omitempty"` + DHCP *DHCPConf `yaml:"dhcp,omitempty"` + TFTP *TFTPConf `yaml:"tftp,omitempty"` + NFS *NFSConf `yaml:"nfs,omitempty"` + SSH *SSHConf `yaml:"ssh,omitempty"` + MountsImage []*MountEntry `yaml:"image mounts,omitempty" default:"[{\"source\": \"/etc/resolv.conf\", \"dest\": \"/etc/resolv.conf\"}]"` + Paths *BuildConfig `yaml:"paths,omitempty"` + WWClient *WWClientConf `yaml:"wwclient,omitempty"` warewulfconf string } diff --git a/internal/pkg/config/root_test.go b/internal/pkg/config/root_test.go index 0c0e8e86..cb63a0fa 100644 --- a/internal/pkg/config/root_test.go +++ b/internal/pkg/config/root_test.go @@ -35,10 +35,10 @@ func TestDefaultWarewulfYaml(t *testing.T) { assert.Empty(t, conf.NFS.ExportsExtended) assert.Equal(t, "nfsd", conf.NFS.SystemdName) - assert.Equal(t, "/etc/resolv.conf", conf.MountsContainer[0].Source) - assert.Equal(t, "/etc/resolv.conf", conf.MountsContainer[0].Dest) - assert.False(t, conf.MountsContainer[0].ReadOnly()) - assert.Empty(t, conf.MountsContainer[0].Options) + assert.Equal(t, "/etc/resolv.conf", conf.MountsImage[0].Source) + assert.Equal(t, "/etc/resolv.conf", conf.MountsImage[0].Dest) + assert.False(t, conf.MountsImage[0].ReadOnly()) + assert.Empty(t, conf.MountsImage[0].Options) assert.NotEmpty(t, conf.Paths.Bindir) assert.NotEmpty(t, conf.Paths.Sysconfdir) @@ -97,7 +97,7 @@ nfs: - path: /opt export options: ro,sync,no_root_squash systemd name: nfs-server -container mounts: +image mounts: - source: /etc/resolv.conf dest: /etc/resolv.conf readonly: true` @@ -138,9 +138,9 @@ container mounts: assert.Equal(t, "ro,sync,no_root_squash", conf.NFS.ExportsExtended[1].ExportOptions) assert.Equal(t, "nfs-server", conf.NFS.SystemdName) - assert.Equal(t, "/etc/resolv.conf", conf.MountsContainer[0].Source) - assert.Equal(t, "/etc/resolv.conf", conf.MountsContainer[0].Dest) - assert.True(t, conf.MountsContainer[0].ReadOnly()) + assert.Equal(t, "/etc/resolv.conf", conf.MountsImage[0].Source) + assert.Equal(t, "/etc/resolv.conf", conf.MountsImage[0].Dest) + assert.True(t, conf.MountsImage[0].ReadOnly()) } func TestCache(t *testing.T) { diff --git a/internal/pkg/container/build.go b/internal/pkg/image/build.go similarity index 74% rename from internal/pkg/container/build.go rename to internal/pkg/image/build.go index 2f050712..7ae942da 100644 --- a/internal/pkg/container/build.go +++ b/internal/pkg/image/build.go @@ -1,4 +1,4 @@ -package container +package image import ( "fmt" @@ -11,19 +11,19 @@ import ( ) func Build(name string, buildForce bool) error { - wwlog.Info("Building container: %s", name) + wwlog.Info("Building image: %s", name) rootfsPath := RootFsDir(name) imagePath := ImageFile(name) if !ValidSource(name) { - return errors.Errorf("Container does not exist: %s", name) + return errors.Errorf("Image does not exist: %s", name) } if !buildForce { - wwlog.Debug("Checking if there have been any updates to the VNFS directory") + wwlog.Debug("Checking if there have been any updates to the image source directory") if util.PathIsNewer(rootfsPath, imagePath) { - wwlog.Info("Skipping (VNFS is current)") + wwlog.Info("Skipping (Image is current)") return nil } } @@ -39,7 +39,7 @@ func Build(name string, buildForce bool) error { } err := util.BuildFsImage( - "VNFS container "+name, + "Image "+name, rootfsPath, imagePath, []string{"*"}, diff --git a/internal/pkg/container/config.go b/internal/pkg/image/config.go similarity index 88% rename from internal/pkg/container/config.go rename to internal/pkg/image/config.go index 9647f82f..4b271399 100644 --- a/internal/pkg/container/config.go +++ b/internal/pkg/image/config.go @@ -1,4 +1,4 @@ -package container +package image import ( "path" @@ -25,7 +25,7 @@ func RunDir(name string) string { func ImageParentDir() string { conf := warewulfconf.Get() - return path.Join(conf.Paths.WWProvisiondir, "container") + return path.Join(conf.Paths.WWProvisiondir, "image") } func ImageFile(name string) string { diff --git a/internal/pkg/container/imprt.go b/internal/pkg/image/imprt.go similarity index 94% rename from internal/pkg/container/imprt.go rename to internal/pkg/image/imprt.go index 449f32ac..c49f2b1c 100644 --- a/internal/pkg/container/imprt.go +++ b/internal/pkg/image/imprt.go @@ -1,4 +1,4 @@ -package container +package image import ( "context" @@ -24,7 +24,7 @@ func ImportDocker(uri string, name string, sCtx *types.SystemContext) error { } if !ValidName(name) { - return errors.New("VNFS name contains illegal characters: " + name) + return errors.New("Image name contains illegal characters: " + name) } fullPath := RootFsDir(name) diff --git a/internal/pkg/container/imprt_test.go b/internal/pkg/image/imprt_test.go similarity index 81% rename from internal/pkg/container/imprt_test.go rename to internal/pkg/image/imprt_test.go index d95a1b7b..f521bd5b 100644 --- a/internal/pkg/container/imprt_test.go +++ b/internal/pkg/image/imprt_test.go @@ -1,4 +1,4 @@ -package container +package image import ( "path/filepath" @@ -12,12 +12,12 @@ import ( "github.com/warewulf/warewulf/internal/pkg/util" ) -func Test_ImportContainerDir(t *testing.T) { +func Test_ImportImageDir(t *testing.T) { var tests = map[string]struct { files []string sockets []string }{ - "empty container": { + "empty image": { files: nil, sockets: nil, }, @@ -33,7 +33,7 @@ func Test_ImportContainerDir(t *testing.T) { t.Run(name, func(t *testing.T) { env := testenv.New(t) defer env.RemoveAll() - src := "/tmp/testcontainer" + src := "/tmp/testImage" env.CreateFile(filepath.Join(src, "/bin/sh")) for _, file := range tt.files { env.CreateFile(filepath.Join(src, file)) @@ -42,8 +42,8 @@ func Test_ImportContainerDir(t *testing.T) { env.MkdirAll(filepath.Dir(filepath.Join(src, socket))) assert.NoError(t, unix.Mknod(env.GetPath(filepath.Join(src, socket)), unix.S_IFSOCK|0777, 0)) } - assert.NoError(t, ImportDirectory(env.GetPath(src), "testcontainer")) - rootfs := "/var/lib/warewulf/chroots/testcontainer/rootfs" + assert.NoError(t, ImportDirectory(env.GetPath(src), "testImage")) + rootfs := "/var/lib/warewulf/chroots/testImage/rootfs" for _, file := range tt.files { assert.True(t, util.IsFile(env.GetPath(filepath.Join(rootfs, file)))) } diff --git a/internal/pkg/container/initramfs.go b/internal/pkg/image/initramfs.go similarity index 68% rename from internal/pkg/container/initramfs.go rename to internal/pkg/image/initramfs.go index dce238a7..ca8ec561 100644 --- a/internal/pkg/container/initramfs.go +++ b/internal/pkg/image/initramfs.go @@ -1,4 +1,4 @@ -package container +package image import ( "path/filepath" @@ -24,8 +24,8 @@ func init() { } type Initramfs struct { - Path string - ContainerName string + Path string + imageName string } func (this *Initramfs) version() *version.Version { @@ -48,13 +48,13 @@ func (this *Initramfs) Version() string { } func (this *Initramfs) FullPath() string { - root := RootFsDir(this.ContainerName) + root := RootFsDir(this.imageName) return filepath.Join(root, this.Path) } -func FindInitramfsFromPattern(containerName string, version string, pattern string) (initramfs *Initramfs) { - wwlog.Debug("FindInitramfsFromPattern(%v, %v, %v)", containerName, version, pattern) - root := RootFsDir(containerName) +func FindInitramfsFromPattern(imageName string, version string, pattern string) (initramfs *Initramfs) { + wwlog.Debug("FindInitramfsFromPattern(%v, %v, %v)", imageName, version, pattern) + root := RootFsDir(imageName) fullPaths, err := filepath.Glob(filepath.Join(root, pattern)) wwlog.Debug("%v: fullPaths: %v", filepath.Join(root, pattern), fullPaths) if err != nil { @@ -65,7 +65,7 @@ func FindInitramfsFromPattern(containerName string, version string, pattern stri if err != nil { continue } else { - initramfs := &Initramfs{Path: filepath.Join("/", path), ContainerName: containerName} + initramfs := &Initramfs{Path: filepath.Join("/", path), imageName: imageName} wwlog.Info("%v", initramfs) if strings.HasPrefix(initramfs.Version(), version) { return initramfs @@ -75,10 +75,10 @@ func FindInitramfsFromPattern(containerName string, version string, pattern stri return nil } -// FindInitramfs returns the Initramfs for a given container and (kernel) version -func FindInitramfs(containerName string, version string) *Initramfs { +// FindInitramfs returns the Initramfs for a given image and (kernel) version +func FindInitramfs(imageName string, version string) *Initramfs { for _, pattern := range initramfsSearchPaths { - initramfs := FindInitramfsFromPattern(containerName, version, pattern) + initramfs := FindInitramfsFromPattern(imageName, version, pattern) if initramfs != nil { return initramfs } diff --git a/internal/pkg/container/initramfs_test.go b/internal/pkg/image/initramfs_test.go similarity index 99% rename from internal/pkg/container/initramfs_test.go rename to internal/pkg/image/initramfs_test.go index 2f9f7662..ce81c98f 100644 --- a/internal/pkg/container/initramfs_test.go +++ b/internal/pkg/image/initramfs_test.go @@ -1,4 +1,4 @@ -package container +package image import ( "os" diff --git a/internal/pkg/container/mountpoints.go b/internal/pkg/image/mountpoints.go similarity index 98% rename from internal/pkg/container/mountpoints.go rename to internal/pkg/image/mountpoints.go index 07c7b57e..cc78affc 100644 --- a/internal/pkg/container/mountpoints.go +++ b/internal/pkg/image/mountpoints.go @@ -1,4 +1,4 @@ -package container +package image import ( "strings" diff --git a/internal/pkg/container/shimgrub.go b/internal/pkg/image/shimgrub.go similarity index 67% rename from internal/pkg/container/shimgrub.go rename to internal/pkg/image/shimgrub.go index 95a7b590..203a8241 100644 --- a/internal/pkg/container/shimgrub.go +++ b/internal/pkg/image/shimgrub.go @@ -1,4 +1,4 @@ -package container +package image import ( "os" @@ -44,35 +44,35 @@ func grubNames() []string { } /* -find the path of the shim binary in container +find the path of the shim binary in image */ -func ShimFind(container string) string { - var container_path string - if container != "" { - container_path = RootFsDir(container) +func ShimFind(image string) string { + var image_path string + if image != "" { + image_path = RootFsDir(image) } else { - container_path = "/" + image_path = "/" } - wwlog.Debug("Finding shim under paths: %s", container_path) - return BootLoaderFindPath(container_path, shimNames, shimDirs) + wwlog.Debug("Finding shim under paths: %s", image_path) + return BootLoaderFindPath(image_path, shimNames, shimDirs) } /* -find a grub.efi in the used container +find a grub.efi in the used image */ -func GrubFind(container string) string { - var container_path string - if container != "" { - container_path = RootFsDir(container) +func GrubFind(image string) string { + var image_path string + if image != "" { + image_path = RootFsDir(image) } else { - container_path = "/" + image_path = "/" } - wwlog.Debug("Finding grub under paths: %s", container_path) - return BootLoaderFindPath(container_path, grubNames, grubDirs) + wwlog.Debug("Finding grub under paths: %s", image_path) + return BootLoaderFindPath(image_path, grubNames, grubDirs) } /* -find the path of the shim binary in container +find the path of the shim binary in image */ func BootLoaderFindPath(cpath string, names func() []string, paths func() []string) string { for _, bdir := range paths() { diff --git a/internal/pkg/container/shimgrub_test.go b/internal/pkg/image/shimgrub_test.go similarity index 99% rename from internal/pkg/container/shimgrub_test.go rename to internal/pkg/image/shimgrub_test.go index 8921b165..1e088b4d 100644 --- a/internal/pkg/container/shimgrub_test.go +++ b/internal/pkg/image/shimgrub_test.go @@ -1,4 +1,4 @@ -package container +package image import ( "os" diff --git a/internal/pkg/container/syncuids.go b/internal/pkg/image/syncuids.go similarity index 56% rename from internal/pkg/container/syncuids.go rename to internal/pkg/image/syncuids.go index f2e8f2d5..73449a26 100644 --- a/internal/pkg/container/syncuids.go +++ b/internal/pkg/image/syncuids.go @@ -1,4 +1,4 @@ -package container +package image import ( "bufio" @@ -20,30 +20,30 @@ const passwdPath = "/etc/passwd" const groupPath = "/etc/group" // SyncUids updates the /etc/passwd and /etc/group files in the -// container identified by containerName by installing the equivalent +// image identified by imageName by installing the equivalent // files from the host and appending names only in the -// container. Files in the container are updated to match the new +// image. Files in the image are updated to match the new // numeric id assignments. // -// If write is false, the container is not actually updated, but +// If write is false, the image is not actually updated, but // relevant log entries and output are generated. // // Any I/O errors are returned unmodified. // -// A conflict arises if the container has an entry with the same id as +// A conflict arises if the image has an entry with the same id as // an entry in the host and the host does not have an entry with the // same name. In this case, an error is returned. -func SyncUids(containerName string, write bool) error { - wwlog.Debug("SyncUids(containerName=%v, write=%v)", containerName, write) - containerPath := RootFsDir(containerName) - containerPasswdPath := path.Join(containerPath, passwdPath) - containerGroupPath := path.Join(containerPath, groupPath) +func SyncUids(imageName string, write bool) error { + wwlog.Debug("SyncUids(imageName=%v, write=%v)", imageName, write) + imagePath := RootFsDir(imageName) + imagePasswdPath := path.Join(imagePath, passwdPath) + imageGroupPath := path.Join(imagePath, groupPath) passwdSync := make(syncDB) if err := passwdSync.readFromHost(passwdPath); err != nil { return err } - if err := passwdSync.readFromContainer(containerPasswdPath); err != nil { + if err := passwdSync.readFromimage(imagePasswdPath); err != nil { return err } if err := passwdSync.checkConflicts(); err != nil { @@ -54,17 +54,17 @@ func SyncUids(containerName string, write bool) error { if err := groupSync.readFromHost(groupPath); err != nil { return err } - if err := groupSync.readFromContainer(containerGroupPath); err != nil { + if err := groupSync.readFromimage(imageGroupPath); err != nil { return err } if err := groupSync.checkConflicts(); err != nil { return err } - if err := passwdSync.findUserFiles(containerPath); err != nil { + if err := passwdSync.findUserFiles(imagePath); err != nil { return err } - if err := groupSync.findGroupFiles(containerPath); err != nil { + if err := groupSync.findGroupFiles(imagePath); err != nil { return err } @@ -78,16 +78,16 @@ func SyncUids(containerName string, write bool) error { if err := groupSync.chownGroupFiles(); err != nil { return err } - if err := passwdSync.update(containerPasswdPath, passwdPath); err != nil { + if err := passwdSync.update(imagePasswdPath, passwdPath); err != nil { return err } - if err := groupSync.update(containerGroupPath, groupPath); err != nil { + if err := groupSync.update(imageGroupPath, groupPath); err != nil { return err } - wwlog.Info("uid/gid synced for container %s", containerName) + wwlog.Info("uid/gid synced for image %s", imageName) } else { if passwdSync.needsSync() || groupSync.needsSync() { - wwlog.Info("uid/gid not synced: run `wwctl container syncuser --write %s`", containerName) + wwlog.Info("uid/gid not synced: run `wwctl image syncuser --write %s`", imageName) } else { wwlog.Info("uid/gid already synced") } @@ -97,24 +97,24 @@ func SyncUids(containerName string, write bool) error { } // A syncDB maps user or group names to syncInfo instances, which -// correlate IDs between host and container and track affected +// correlate IDs between host and image and track affected // files. This can be used for either /etc/passwd or /etc/group IDs. type syncDB map[string]syncInfo // checkConflicts inspects a syncDB map for irreconcilable -// conflicts. A conflict arises if the container has an entry with the +// conflicts. A conflict arises if the image has an entry with the // same id as an entry in the host and the host does not have an entry // with the same name. func (db syncDB) checkConflicts() error { - for nameInContainer, containerIds := range db { - if !containerIds.inContainer() || containerIds.inHost() { + for nameInimage, imageIds := range db { + if !imageIds.inimage() || imageIds.inHost() { continue } for nameInHost, hostIds := range db { - if hostIds.HostID == containerIds.ContainerID { - wwlog.Warn("syncuser cannot determine what name should be assigned to id number %v: on the local host it is assigned to '%s'; but in the container it is assigned to '%s'. Since '%s' does not exist on the local host, it cannot be reassigned to a different id number. To resolve the conflict, add '%s' to the local host and re-run syncuser.", containerIds.ContainerID, nameInHost, nameInContainer, nameInContainer, nameInContainer) - return errors.New(fmt.Sprintf("id(%v) collision: host(%s) container(%s)", containerIds.ContainerID, nameInHost, nameInContainer)) + if hostIds.HostID == imageIds.imageID { + wwlog.Warn("syncuser cannot determine what name should be assigned to id number %v: on the local host it is assigned to '%s'; but in the image it is assigned to '%s'. Since '%s' does not exist on the local host, it cannot be reassigned to a different id number. To resolve the conflict, add '%s' to the local host and re-run syncuser.", imageIds.imageID, nameInHost, nameInimage, nameInimage, nameInimage) + return errors.New(fmt.Sprintf("id(%v) collision: host(%s) image(%s)", imageIds.imageID, nameInHost, nameInimage)) } } } @@ -127,11 +127,11 @@ func (db syncDB) checkConflicts() error { // for the given syncDB map. (e.g., to differentiate between a user or // group map) func (db syncDB) log(prefix string) { - var onlyContainer, onlyHost, match, differ []string + var onlyimage, onlyHost, match, differ []string for name, ids := range db { - wwlog.Debug("%s: %s: host(%v) container(%v) files: %v", prefix, name, ids.HostID, ids.ContainerID, ids.ContainerFiles) - if ids.onlyContainer() { - onlyContainer = append(onlyContainer, name) + wwlog.Debug("%s: %s: host(%v) image(%v) files: %v", prefix, name, ids.HostID, ids.imageID, ids.imageFiles) + if ids.onlyimage() { + onlyimage = append(onlyimage, name) } if ids.onlyHost() { onlyHost = append(onlyHost, name) @@ -144,7 +144,7 @@ func (db syncDB) log(prefix string) { } } - wwlog.Verbose("%s: container only: %v", prefix, onlyContainer) + wwlog.Verbose("%s: image only: %v", prefix, onlyimage) wwlog.Verbose("%s: host only: %v", prefix, onlyHost) wwlog.Verbose("%s: match: %v", prefix, match) wwlog.Verbose("%s: differ: %v", prefix, differ) @@ -154,10 +154,10 @@ func (db syncDB) log(prefix string) { // syncDB map. Since the name and numerical id for both files are // stored at fields 0 and 2, the same function can read both files. // -// fromContainer identifies whether the given fileName includes -// entries from the host or the container. -func (db syncDB) read(fileName string, fromContainer bool) error { - wwlog.Debug("read %s (container: %t)", fileName, fromContainer) +// fromimage identifies whether the given fileName includes +// entries from the host or the image. +func (db syncDB) read(fileName string, fromimage bool) error { + wwlog.Debug("read %s (image: %t)", fileName, fromimage) if file, err := os.Open(fileName); err != nil { return err } else { @@ -186,14 +186,14 @@ func (db syncDB) read(fileName string, fromContainer bool) error { } entry, ok := db[name] if !ok { - entry = syncInfo{HostID: -1, ContainerID: -1} + entry = syncInfo{HostID: -1, imageID: -1} } - if fromContainer { - if entry.ContainerID == -1 { - entry.ContainerID = id - } else if entry.ContainerID != id { - wwlog.Warn("Ignoring container id(%v) for %s from %s after existing value %v", id, name, fileName, entry.ContainerID) + if fromimage { + if entry.imageID == -1 { + entry.imageID = id + } else if entry.imageID != id { + wwlog.Warn("Ignoring image id(%v) for %s from %s after existing value %v", id, name, fileName, entry.imageID) continue } } else { @@ -216,27 +216,27 @@ func (db syncDB) read(fileName string, fromContainer bool) error { // Equivalent to read(fileName, false) func (db syncDB) readFromHost(fileName string) error { return db.read(fileName, false) } -// readFromContainer reads fileName into a syncDB map. +// readFromimage reads fileName into a syncDB map. // // Equivalent to read(fileName, true) -func (db syncDB) readFromContainer(fileName string) error { return db.read(fileName, true) } +func (db syncDB) readFromimage(fileName string) error { return db.read(fileName, true) } -// findFiles finds files under containerPath that are owned by each -// tracked container ID. +// findFiles finds files under imagePath that are owned by each +// tracked image ID. // // If byGid is true, files with a matching gid are // recorded. Otherwise, files with a matching uid are recorded. -func (db syncDB) findFiles(containerPath string, byGid bool) error { - wwlog.Debug("findFiles(containerPath=%v, byGid=%v)", containerPath, byGid) +func (db syncDB) findFiles(imagePath string, byGid bool) error { + wwlog.Debug("findFiles(imagePath=%v, byGid=%v)", imagePath, byGid) syncIDs := make(map[int]string) for name, info := range db { - if info.inHost() && info.inContainer() && !info.match() { - wwlog.Debug("syncID[%v] = %v", info.ContainerID, name) - syncIDs[info.ContainerID] = name + if info.inHost() && info.inimage() && !info.match() { + wwlog.Debug("syncID[%v] = %v", info.imageID, name) + syncIDs[info.imageID] = name } } - return filepath.Walk(containerPath, func(filePath string, fileInfo fs.FileInfo, err error) error { + return filepath.Walk(imagePath, func(filePath string, fileInfo fs.FileInfo, err error) error { if stat, ok := fileInfo.Sys().(*syscall.Stat_t); ok { var id int if byGid { @@ -246,8 +246,8 @@ func (db syncDB) findFiles(containerPath string, byGid bool) error { } if name, ok := syncIDs[id]; ok { info := db[name] - wwlog.Debug("findFiles: %s: (%v -> %v, gid: %v)", filePath, info.ContainerID, info.HostID, byGid) - info.ContainerFiles = append(info.ContainerFiles, filePath) + wwlog.Debug("findFiles: %s: (%v -> %v, gid: %v)", filePath, info.imageID, info.HostID, byGid) + info.imageFiles = append(info.imageFiles, filePath) db[name] = info } else { wwlog.Debug("findFiles: %s", filePath) @@ -257,11 +257,11 @@ func (db syncDB) findFiles(containerPath string, byGid bool) error { }) } -// findUserFiles is equivalent to findFiles(containerPath, false) -func (db syncDB) findUserFiles(containerPath string) error { return db.findFiles(containerPath, false) } +// findUserFiles is equivalent to findFiles(imagePath, false) +func (db syncDB) findUserFiles(imagePath string) error { return db.findFiles(imagePath, false) } -// findGroupFiles is equivalent to findFiles(containerPath, true) -func (db syncDB) findGroupFiles(containerPath string) error { return db.findFiles(containerPath, true) } +// findGroupFiles is equivalent to findFiles(imagePath, true) +func (db syncDB) findGroupFiles(imagePath string) error { return db.findFiles(imagePath, true) } // chownFiles updates found files (see findFiles) to reflect ownership // using host ids. @@ -283,13 +283,13 @@ func (db syncDB) chownUserFiles() error { return db.chownFiles(false) } // chownUserFiles is equivalent to chownFiles(true) func (db syncDB) chownGroupFiles() error { return db.chownFiles(true) } -// getOnlyContainerLines returns the lines from fileName (either an +// getOnlyimageLines returns the lines from fileName (either an // /etc/passwd or /etc/group file) for names that occur only in the -// container. +// image. // // These lines are added to the respective file from the host when -// updating the container. -func (db syncDB) getOnlyContainerLines(fileName string) ([]string, error) { +// updating the image. +func (db syncDB) getOnlyimageLines(fileName string) ([]string, error) { file, err := os.Open(fileName) if err != nil { return nil, err @@ -303,34 +303,34 @@ func (db syncDB) getOnlyContainerLines(fileName string) ([]string, error) { fields := strings.Split(line, ":") for name, ids := range db { if fields[0] == name { - if ids.onlyContainer() { + if ids.onlyimage() { lines = append(lines, line) } break } } } - wwlog.Debug("file: %s, entries only in container: %v", fileName, lines) + wwlog.Debug("file: %s, entries only in image: %v", fileName, lines) return lines, nil } -// update replaces containerPath with hostPath and adds lines from -// getOnlyContainerLines to the end of containerPath. This is used to -// replace /etc/passwd (or /etc/group) in the container with the +// update replaces imagePath with hostPath and adds lines from +// getOnlyimageLines to the end of imagePath. This is used to +// replace /etc/passwd (or /etc/group) in the image with the // equivalent file from the host while retaining names unique to the -// container. -func (db syncDB) update(containerPath string, hostPath string) error { - wwlog.Debug("update %s from %s)", containerPath, hostPath) - if lines, err := db.getOnlyContainerLines(containerPath); err != nil { +// image. +func (db syncDB) update(imagePath string, hostPath string) error { + wwlog.Debug("update %s from %s)", imagePath, hostPath) + if lines, err := db.getOnlyimageLines(imagePath); err != nil { return err } else { - if err := os.Remove(containerPath); err != nil { + if err := os.Remove(imagePath); err != nil { return err } - if err := util.CopyFile(hostPath, containerPath); err != nil { + if err := util.CopyFile(hostPath, imagePath); err != nil { return err } - if err := util.AppendLines(containerPath, lines); err != nil { + if err := util.AppendLines(imagePath, lines); err != nil { return err } return nil @@ -338,7 +338,7 @@ func (db syncDB) update(containerPath string, hostPath string) error { } // needsSync returns true if the syncDB map indicates that ids between -// the container and host are out-of-sync. +// the image and host are out-of-sync. func (db syncDB) needsSync() bool { for name, ids := range db { if ids.onlyHost() { @@ -346,7 +346,7 @@ func (db syncDB) needsSync() bool { return true } if ids.differ() { - wwlog.Debug("sync required: %s is %v in host and %v in container", name, ids.HostID, ids.ContainerID) + wwlog.Debug("sync required: %s is %v in host and %v in image", name, ids.HostID, ids.imageID) return true } } @@ -354,13 +354,13 @@ func (db syncDB) needsSync() bool { } // sycncInfo correlates the numerical id of a name on the host -// (HostID) and the container (ContainerID), along with the files in -// the container that are owned by that name. This allows affected -// files to be updated when the HostID is applied to the container. +// (HostID) and the image (imageID), along with the files in +// the image that are owned by that name. This allows affected +// files to be updated when the HostID is applied to the image. type syncInfo struct { - HostID int `access:"r,w"` - ContainerID int `access:"r,w"` - ContainerFiles []string `access:"r,w"` + HostID int `access:"r,w"` + imageID int `access:"r,w"` + imageFiles []string `access:"r,w"` } // inHost returns true if info has a record of an id for this name in @@ -369,43 +369,43 @@ func (info *syncInfo) inHost() bool { return info.HostID != -1 } -// inContainer returns true if info has a record of an id for this -// name in the container. -func (info *syncInfo) inContainer() bool { - return info.ContainerID != -1 +// inimage returns true if info has a record of an id for this +// name in the image. +func (info *syncInfo) inimage() bool { + return info.imageID != -1 } // onlyHost returns true if info has a record of an id for this name -// in the host and not in the container. +// in the host and not in the image. func (info *syncInfo) onlyHost() bool { - return info.inHost() && !info.inContainer() + return info.inHost() && !info.inimage() } // onlyHost returns true if info has a record of an id for this name -// in the container and not in the host. -func (info *syncInfo) onlyContainer() bool { - return info.inContainer() && !info.inHost() +// in the image and not in the host. +func (info *syncInfo) onlyimage() bool { + return info.inimage() && !info.inHost() } // match returns true if info represents a name that exists with the -// same numerical id in both the host and the container. +// same numerical id in both the host and the image. func (info *syncInfo) match() bool { - return info.inContainer() && info.inHost() && info.HostID == info.ContainerID + return info.inimage() && info.inHost() && info.HostID == info.imageID } // differ returns true if info represents a name that exists in both -// the host and the container but with different numerical ids. +// the host and the image but with different numerical ids. func (info *syncInfo) differ() bool { - return info.inContainer() && info.inHost() && info.HostID != info.ContainerID + return info.inimage() && info.inHost() && info.HostID != info.imageID } -// chownFiles updates the files recorded in info.ContainerFiles to use +// chownFiles updates the files recorded in info.imageFiles to use // the numerical IDs from the host. // // If byGid is true, the file's gid is updated; otherwise, the file's // uid is updated. func (info *syncInfo) chownFiles(byGid bool) error { - for _, file := range info.ContainerFiles { + for _, file := range info.imageFiles { if fileInfo, err := os.Stat(file); err != nil { return err } else { diff --git a/internal/pkg/container/syncuids_test.go b/internal/pkg/image/syncuids_test.go similarity index 77% rename from internal/pkg/container/syncuids_test.go rename to internal/pkg/image/syncuids_test.go index 75a6401f..16fb07a9 100644 --- a/internal/pkg/container/syncuids_test.go +++ b/internal/pkg/image/syncuids_test.go @@ -1,4 +1,4 @@ -package container +package image import ( "bytes" @@ -18,16 +18,16 @@ func writeTempFile(t *testing.T, input string) string { return tempFile.Name() } -func makeSyncDB(t *testing.T, hostInput string, containerInput string) syncDB { +func makeSyncDB(t *testing.T, hostInput string, imageInput string) syncDB { hostFileName := writeTempFile(t, hostInput) defer os.Remove(hostFileName) - containerFileName := writeTempFile(t, containerInput) - defer os.Remove(containerFileName) + imageFileName := writeTempFile(t, imageInput) + defer os.Remove(imageFileName) db := make(syncDB) var err error err = db.readFromHost(hostFileName) assert.NoError(t, err) - err = db.readFromContainer(containerFileName) + err = db.readFromimage(imageFileName) assert.NoError(t, err) return db } @@ -42,7 +42,7 @@ func Test_readFromHost_single(t *testing.T) { assert.Len(t, db, 1) assert.Equal(t, 1001, db["testuser"].HostID) - assert.Equal(t, -1, db["testuser"].ContainerID) + assert.Equal(t, -1, db["testuser"].imageID) } func Test_readFromHost_multiple(t *testing.T) { @@ -58,47 +58,47 @@ testuser2:x:1002:1002::/home/testuser:/bin/bash assert.Len(t, db, 2) assert.Equal(t, 1001, db["testuser1"].HostID) - assert.Equal(t, -1, db["testuser1"].ContainerID) + assert.Equal(t, -1, db["testuser1"].imageID) assert.Equal(t, 1002, db["testuser2"].HostID) - assert.Equal(t, -1, db["testuser2"].ContainerID) + assert.Equal(t, -1, db["testuser2"].imageID) } -func Test_readFromContainer_single(t *testing.T) { - containerFileName := writeTempFile(t, `testuser:x:1001:1001::/home/testuser:/bin/bash`) - defer os.Remove(containerFileName) +func Test_readFromimage_single(t *testing.T) { + imageFileName := writeTempFile(t, `testuser:x:1001:1001::/home/testuser:/bin/bash`) + defer os.Remove(imageFileName) db := make(syncDB) - err := db.readFromContainer(containerFileName) + err := db.readFromimage(imageFileName) assert.NoError(t, err) assert.Len(t, db, 1) - assert.Equal(t, 1001, db["testuser"].ContainerID) + assert.Equal(t, 1001, db["testuser"].imageID) assert.Equal(t, -1, db["testuser"].HostID) } -func Test_readFromContainer_multiple(t *testing.T) { - containerFileName := writeTempFile(t, ` +func Test_readFromimage_multiple(t *testing.T) { + imageFileName := writeTempFile(t, ` testuser1:x:1001:1001::/home/testuser:/bin/bash testuser2:x:1002:1002::/home/testuser:/bin/bash `) - defer os.Remove(containerFileName) + defer os.Remove(imageFileName) db := make(syncDB) - err := db.readFromContainer(containerFileName) + err := db.readFromimage(imageFileName) assert.NoError(t, err) assert.Len(t, db, 2) - assert.Equal(t, 1001, db["testuser1"].ContainerID) + assert.Equal(t, 1001, db["testuser1"].imageID) assert.Equal(t, -1, db["testuser1"].HostID) - assert.Equal(t, 1002, db["testuser2"].ContainerID) + assert.Equal(t, 1002, db["testuser2"].imageID) assert.Equal(t, -1, db["testuser2"].HostID) } func Test_readFromBoth_multiple(t *testing.T) { - containerFileName := writeTempFile(t, ` + imageFileName := writeTempFile(t, ` testuser1:x:1001:1001::/home/testuser:/bin/bash testuser2:x:1002:1002::/home/testuser:/bin/bash `) - defer os.Remove(containerFileName) + defer os.Remove(imageFileName) hostFileName := writeTempFile(t, ` testuser1:x:2001:2001::/home/testuser:/bin/bash @@ -108,16 +108,16 @@ testuser3:x:2003:2003::/home/testuser:/bin/bash db := make(syncDB) var err error - err = db.readFromContainer(containerFileName) + err = db.readFromimage(imageFileName) assert.NoError(t, err) err = db.readFromHost(hostFileName) assert.NoError(t, err) assert.Len(t, db, 3) - assert.Equal(t, 1001, db["testuser1"].ContainerID) + assert.Equal(t, 1001, db["testuser1"].imageID) assert.Equal(t, 2001, db["testuser1"].HostID) - assert.Equal(t, 1002, db["testuser2"].ContainerID) + assert.Equal(t, 1002, db["testuser2"].imageID) assert.Equal(t, -1, db["testuser2"].HostID) - assert.Equal(t, -1, db["testuser3"].ContainerID) + assert.Equal(t, -1, db["testuser3"].imageID) assert.Equal(t, 2003, db["testuser3"].HostID) } @@ -145,12 +145,12 @@ func Test_checkConflicts_conflict(t *testing.T) { assert.Error(t, db.checkConflicts()) } -func Test_getOnlyContainerLines(t *testing.T) { - containerFileName := writeTempFile(t, ` +func Test_getOnlyimageLines(t *testing.T) { + imageFileName := writeTempFile(t, ` testuser1:x:1001:1001::/home/testuser:/bin/bash testuser2:x:1002:1002::/home/testuser:/bin/bash `) - defer os.Remove(containerFileName) + defer os.Remove(imageFileName) hostFileName := writeTempFile(t, ` testuser1:x:2001:2001::/home/testuser:/bin/bash @@ -160,12 +160,12 @@ testuser3:x:2003:2003::/home/testuser:/bin/bash db := make(syncDB) var err error - err = db.readFromContainer(containerFileName) + err = db.readFromimage(imageFileName) assert.NoError(t, err) err = db.readFromHost(hostFileName) assert.NoError(t, err) - lines, err := db.getOnlyContainerLines(containerFileName) + lines, err := db.getOnlyimageLines(imageFileName) assert.NoError(t, err) assert.Len(t, lines, 1) @@ -177,7 +177,7 @@ func Test_needsSync_empty(t *testing.T) { assert.False(t, db.needsSync()) } -func Test_needsSync_containerOnly(t *testing.T) { +func Test_needsSync_imageOnly(t *testing.T) { db := makeSyncDB(t, "", ` testuser1:x:1001:1001::/home/testuser:/bin/bash testuser2:x:1002:1002::/home/testuser:/bin/bash`) @@ -217,20 +217,20 @@ func Test_onlyHost(t *testing.T) { db := makeSyncDB(t, "testuser1:x:2001:2001::/home/testuser:/bin/bash", "") entry := db["testuser1"] assert.True(t, entry.inHost()) - assert.False(t, entry.inContainer()) + assert.False(t, entry.inimage()) assert.True(t, entry.onlyHost()) - assert.False(t, entry.onlyContainer()) + assert.False(t, entry.onlyimage()) assert.False(t, entry.match()) assert.False(t, entry.differ()) } -func Test_onlyContainer(t *testing.T) { +func Test_onlyimage(t *testing.T) { db := makeSyncDB(t, "", "testuser1:x:2001:2001::/home/testuser:/bin/bash") entry := db["testuser1"] assert.False(t, entry.inHost()) - assert.True(t, entry.inContainer()) + assert.True(t, entry.inimage()) assert.False(t, entry.onlyHost()) - assert.True(t, entry.onlyContainer()) + assert.True(t, entry.onlyimage()) assert.False(t, entry.match()) assert.False(t, entry.differ()) } @@ -241,9 +241,9 @@ func Test_match(t *testing.T) { "testuser1:x:2001:2001::/home/testuser:/bin/bash") entry := db["testuser1"] assert.True(t, entry.inHost()) - assert.True(t, entry.inContainer()) + assert.True(t, entry.inimage()) assert.False(t, entry.onlyHost()) - assert.False(t, entry.onlyContainer()) + assert.False(t, entry.onlyimage()) assert.True(t, entry.match()) assert.False(t, entry.differ()) } @@ -254,9 +254,9 @@ func Test_differ(t *testing.T) { "testuser1:x:2001:2001::/home/testuser:/bin/bash") entry := db["testuser1"] assert.True(t, entry.inHost()) - assert.True(t, entry.inContainer()) + assert.True(t, entry.inimage()) assert.False(t, entry.onlyHost()) - assert.False(t, entry.onlyContainer()) + assert.False(t, entry.onlyimage()) assert.False(t, entry.match()) assert.True(t, entry.differ()) } diff --git a/internal/pkg/container/util.go b/internal/pkg/image/util.go similarity index 66% rename from internal/pkg/container/util.go rename to internal/pkg/image/util.go index 38531c9f..3baa337f 100644 --- a/internal/pkg/container/util.go +++ b/internal/pkg/image/util.go @@ -1,4 +1,4 @@ -package container +package image import ( "os" @@ -12,7 +12,7 @@ import ( func ValidName(name string) bool { if !util.ValidString(name, "^[\\w\\-\\.\\:]+$") { - wwlog.Warn("VNFS name has illegal characters: %s", name) + wwlog.Warn("Image name has illegal characters: %s", name) return false } return true @@ -23,9 +23,9 @@ func ListSources() ([]string, error) { err := os.MkdirAll(SourceParentDir(), 0755) if err != nil { - return ret, errors.New("Could not create VNFS source parent directory: " + SourceParentDir()) + return ret, errors.New("Could not create image source parent directory: " + SourceParentDir()) } - wwlog.Debug("Searching for VNFS Rootfs directories: %s", SourceParentDir()) + wwlog.Debug("Searching for image rootfs directories: %s", SourceParentDir()) sources, err := os.ReadDir(SourceParentDir()) if err != nil { @@ -33,7 +33,7 @@ func ListSources() ([]string, error) { } for _, source := range sources { - wwlog.Verbose("Found VNFS source: %s", source.Name()) + wwlog.Verbose("Found image source: %s", source.Name()) if !ValidName(source.Name()) { continue @@ -60,7 +60,7 @@ func ValidSource(name string) bool { } if !DoesSourceExist(name) { - wwlog.Verbose("Location is not a VNFS source directory: %s", name) + wwlog.Verbose("Location is not an image source directory: %s", name) return false } @@ -68,7 +68,7 @@ func ValidSource(name string) bool { } /* -Delete the chroot of a container +Delete the chroot of an image */ func DeleteSource(name string) error { fullPath := SourceDir(name) @@ -91,24 +91,24 @@ func Duplicate(name string, destination string) error { } /* -Delete the image of a container +Delete the image of an image */ func DeleteImage(name string) error { imageFile := ImageFile(name) if util.IsFile(imageFile) { - wwlog.Verbose("removing %s for container %s", imageFile, name) + wwlog.Verbose("removing %s for image %s", imageFile, name) errImg := os.Remove(imageFile) - wwlog.Verbose("removing %s for container %s", imageFile+".gz", name) + wwlog.Verbose("removing %s for image %s", imageFile+".gz", name) errGz := os.Remove(imageFile + ".gz") if errImg != nil { - return errors.Errorf("Problems delete %s for container %s: %s\n", imageFile, name, errImg) + return errors.Errorf("Problems delete %s for image %s: %s\n", imageFile, name, errImg) } if errGz != nil { - return errors.Errorf("Problems delete %s for container %s: %s\n", imageFile+".gz", name, errGz) + return errors.Errorf("Problems delete %s for image %s: %s\n", imageFile+".gz", name, errGz) } return nil } - return errors.Errorf("Image %s of container %s doesn't exist\n", imageFile, name) + return errors.Errorf("Image %s of image %s doesn't exist\n", imageFile, name) } func IsWriteAble(name string) bool { diff --git a/internal/pkg/kernel/kernel.go b/internal/pkg/kernel/kernel.go index 3da2d21a..31408c64 100644 --- a/internal/pkg/kernel/kernel.go +++ b/internal/pkg/kernel/kernel.go @@ -7,7 +7,7 @@ import ( "github.com/hashicorp/go-version" - "github.com/warewulf/warewulf/internal/pkg/container" + "github.com/warewulf/warewulf/internal/pkg/image" "github.com/warewulf/warewulf/internal/pkg/node" "github.com/warewulf/warewulf/internal/pkg/util" "github.com/warewulf/warewulf/internal/pkg/wwlog" @@ -67,29 +67,29 @@ func (k collection) Version(version string) *Kernel { } type Kernel struct { - Path string - ContainerName string + Path string + ImageName string } func FromNode(node *node.Node) *Kernel { wwlog.Debug("FromNode(%v)", node) - if node.ContainerName == "" { + if node.ImageName == "" { return nil } else if node.Kernel != nil && node.Kernel.Version != "" { - kernel := &Kernel{ContainerName: node.ContainerName, Path: filepath.Join("/", node.Kernel.Version)} + kernel := &Kernel{ImageName: node.ImageName, Path: filepath.Join("/", node.Kernel.Version)} if util.IsFile(kernel.FullPath()) { return kernel } else { - return FindKernels(node.ContainerName).Version(node.Kernel.Version) + return FindKernels(node.ImageName).Version(node.Kernel.Version) } } else { - return FindKernels(node.ContainerName).Default() + return FindKernels(node.ImageName).Default() } } -func FindKernelsFromPattern(containerName string, pattern string) (kernels collection) { - wwlog.Debug("FindKernelsFromPattern(%v, %v)", containerName, pattern) - root := container.RootFsDir(containerName) +func FindKernelsFromPattern(imageName string, pattern string) (kernels collection) { + wwlog.Debug("FindKernelsFromPattern(%v, %v)", imageName, pattern) + root := image.RootFsDir(imageName) fullPaths, err := filepath.Glob(filepath.Join(root, pattern)) wwlog.Debug("%v: fullPaths: %v", filepath.Join(root, pattern), fullPaths) if err != nil { @@ -100,23 +100,23 @@ func FindKernelsFromPattern(containerName string, pattern string) (kernels colle if err != nil { continue } else { - kernels = append(kernels, &Kernel{ContainerName: containerName, Path: filepath.Join("/", path)}) + kernels = append(kernels, &Kernel{ImageName: imageName, Path: filepath.Join("/", path)}) } } return kernels } -func FindKernels(containerName string) (kernels collection) { - wwlog.Debug("FindKernels(%v)", containerName) +func FindKernels(imageName string) (kernels collection) { + wwlog.Debug("FindKernels(%v)", imageName) for _, pattern := range kernelSearchPaths { - kernels = append(kernels, FindKernelsFromPattern(containerName, pattern)...) + kernels = append(kernels, FindKernelsFromPattern(imageName, pattern)...) } return kernels } func FindAllKernels() (kernels collection) { wwlog.Debug("FindAllKernels()") - if sources, err := container.ListSources(); err == nil { + if sources, err := image.ListSources(); err == nil { for _, source := range sources { kernels = append(kernels, FindKernels(source)...) } @@ -148,6 +148,6 @@ func (this *Kernel) IsRescue() bool { } func (this *Kernel) FullPath() string { - root := container.RootFsDir(this.ContainerName) + root := image.RootFsDir(this.ImageName) return filepath.Join(root, this.Path) } diff --git a/internal/pkg/kernel/kernel_test.go b/internal/pkg/kernel/kernel_test.go index 5d7e7938..0609d478 100644 --- a/internal/pkg/kernel/kernel_test.go +++ b/internal/pkg/kernel/kernel_test.go @@ -89,18 +89,18 @@ func Test_FindKernel(t *testing.T) { t.Run(name, func(t *testing.T) { env := testenv.New(t) defer env.RemoveAll() - rootfs := "/var/lib/warewulf/chroots/testcontainer/rootfs" + rootfs := "/var/lib/warewulf/chroots/testimage/rootfs" for _, file := range tt.files { env.CreateFile(filepath.Join(rootfs, file)) } - kernels := FindKernels("testcontainer") + kernels := FindKernels("testimage") assert.Equal(t, len(tt.files), len(kernels)) kernel := kernels.Default() if tt.version == "" && tt.path == "" { assert.Nil(t, kernel) } else { - assert.Equal(t, "testcontainer", kernel.ContainerName) + assert.Equal(t, "testimage", kernel.ImageName) assert.Equal(t, tt.version, kernel.Version()) assert.Equal(t, tt.path, kernel.Path) assert.Equal(t, env.GetPath(filepath.Join(rootfs, tt.path)), kernel.FullPath()) @@ -152,18 +152,18 @@ func Test_FromNode(t *testing.T) { t.Run(name, func(t *testing.T) { env := testenv.New(t) defer env.RemoveAll() - rootfs := "/var/lib/warewulf/chroots/testcontainer/rootfs" + rootfs := "/var/lib/warewulf/chroots/testimage/rootfs" for _, file := range tt.files { env.CreateFile(filepath.Join(rootfs, file)) } node := node.EmptyNode() - node.ContainerName = "testcontainer" + node.ImageName = "testimage" node.Kernel.Version = tt.version kernel := FromNode(&node) if tt.path == "" { assert.Nil(t, kernel) } else { - assert.Equal(t, "testcontainer", kernel.ContainerName) + assert.Equal(t, "testimage", kernel.ImageName) assert.Equal(t, tt.path, kernel.Path) } }) @@ -175,14 +175,14 @@ func Test_FindAllKernels(t *testing.T) { files map[string][]string count int }{ - "two containers": { + "two images": { files: map[string][]string{ - "container1": []string{ + "image1": []string{ "/boot/vmlinuz-5.14.0-427.18.1.el9_4.x86_64", "/boot/vmlinuz-5.14.0-427.24.1.el9_4.x86_64", "/boot/vmlinuz-4.14.0-427.18.1.el8_4.x86_64", }, - "container2": []string{ + "image2": []string{ "/boot/vmlinuz-0-rescue-eb46964329b146e39518c625feab3ea0", "/boot/vmlinuz-5.14.0-362.24.1.el9_3.aarch64", "/boot/vmlinuz-5.14.0-427.31.1.el9_4.aarch64+debug", @@ -201,8 +201,8 @@ func Test_FindAllKernels(t *testing.T) { t.Run(name, func(t *testing.T) { env := testenv.New(t) defer env.RemoveAll() - for container, files := range tt.files { - rootfs := filepath.Join(filepath.Join("/var/lib/warewulf/chroots", container), "rootfs") + for image, files := range tt.files { + rootfs := filepath.Join(filepath.Join("/var/lib/warewulf/chroots", image), "rootfs") for _, file := range files { env.CreateFile(filepath.Join(rootfs, file)) } @@ -237,7 +237,7 @@ func Test_IsDebugOrRescue(t *testing.T) { } for name, tt := range tests { t.Run(name, func(t *testing.T) { - kernel := &Kernel{ContainerName: "", Path: tt.path} + kernel := &Kernel{ImageName: "", Path: tt.path} assert.Equal(t, tt.debug, kernel.IsDebug()) assert.Equal(t, tt.rescue, kernel.IsRescue()) }) diff --git a/internal/pkg/node/datastructure.go b/internal/pkg/node/datastructure.go index 912e3583..b6a657ef 100644 --- a/internal/pkg/node/datastructure.go +++ b/internal/pkg/node/datastructure.go @@ -40,13 +40,13 @@ type Profile struct { Profiles []string `yaml:"profiles,omitempty" lopt:"profile" sopt:"P" comment:"Set the node's profile members (comma separated)"` Comment string `yaml:"comment,omitempty" lopt:"comment" comment:"Set arbitrary string comment"` ClusterName string `yaml:"cluster name,omitempty" lopt:"cluster" sopt:"c" comment:"Set cluster group"` - ContainerName string `yaml:"container name,omitempty" lopt:"container" sopt:"C" comment:"Set container name"` + ImageName string `yaml:"image name,omitempty" lopt:"image" comment:"Set image name"` Ipxe string `yaml:"ipxe template,omitempty" lopt:"ipxe" comment:"Set the iPXE template name"` RuntimeOverlay []string `yaml:"runtime overlay,omitempty" lopt:"runtime" sopt:"R" comment:"Set the runtime overlay"` SystemOverlay []string `yaml:"system overlay,omitempty" lopt:"wwinit" sopt:"O" comment:"Set the system overlay"` Kernel *KernelConf `yaml:"kernel,omitempty"` Ipmi *IpmiConf `yaml:"ipmi,omitempty"` - Init string `yaml:"init,omitempty" lopt:"init" sopt:"i" comment:"Define the init process to boot the container"` + Init string `yaml:"init,omitempty" lopt:"init" sopt:"i" comment:"Define the init process to boot the image"` Root string `yaml:"root,omitempty" lopt:"root" comment:"Define the rootfs" ` NetDevs map[string]*NetDev `yaml:"network devices,omitempty"` Tags map[string]string `yaml:"tags,omitempty"` diff --git a/internal/pkg/node/fields_test.go b/internal/pkg/node/fields_test.go index 8010d7a9..9ac53595 100644 --- a/internal/pkg/node/fields_test.go +++ b/internal/pkg/node/fields_test.go @@ -114,7 +114,7 @@ func Test_listFields(t *testing.T) { "Profiles", "Comment", "ClusterName", - "ContainerName", + "ImageName", "Ipxe", "RuntimeOverlay", "SystemOverlay", @@ -168,7 +168,7 @@ func Test_listFields(t *testing.T) { "Profiles", "Comment", "ClusterName", - "ContainerName", + "ImageName", "Ipxe", "RuntimeOverlay", "SystemOverlay", diff --git a/internal/pkg/node/methods.go b/internal/pkg/node/methods.go index 2483f825..78cb343d 100644 --- a/internal/pkg/node/methods.go +++ b/internal/pkg/node/methods.go @@ -311,6 +311,16 @@ func (node *Profile) Id() string { return node.id } +// ContainerName returns the value of the ImageName field for backwards-compatibility. +func (node *Node) ContainerName() string { + return node.ImageName +} + +// ContainerName returns the value of the ImageName field for backwards-compatibility. +func (profile *Profile) ContainerName() string { + return profile.ImageName +} + /* Returns if the node is a valid in the database */ diff --git a/internal/pkg/oci/defaults.go b/internal/pkg/oci/defaults.go index e3a516bf..03f29614 100644 --- a/internal/pkg/oci/defaults.go +++ b/internal/pkg/oci/defaults.go @@ -6,7 +6,7 @@ import ( warewulfconf "github.com/warewulf/warewulf/internal/pkg/config" ) -var defaultCachePath = filepath.Join(warewulfconf.Get().Paths.Datadir, "/container-cache/oci/") +var defaultCachePath = filepath.Join(warewulfconf.Get().Paths.Datadir, "/image-cache/oci/") const ( blobPrefix = "blobs" diff --git a/internal/pkg/overlay/datastructure.go b/internal/pkg/overlay/datastructure.go index 471a6899..c720f8f5 100644 --- a/internal/pkg/overlay/datastructure.go +++ b/internal/pkg/overlay/datastructure.go @@ -39,8 +39,9 @@ type TemplateStruct struct { AllNodes []node.Node node.Node // backward compatiblity - Container string - ThisNode *node.Node + Container string + ContainerName string + ThisNode *node.Node } /* @@ -74,7 +75,8 @@ func InitStruct(overlayName string, nodeData node.Node, allNodes []node.Node) (T // init some convenience vars tstruct.Id = nodeData.Id() tstruct.Hostname = nodeData.Id() - tstruct.Container = nodeData.ContainerName + tstruct.Container = nodeData.ImageName + tstruct.ContainerName = nodeData.ImageName // Backwards compatibility for templates using "Keys" tstruct.AllNodes = allNodes dt := time.Now() diff --git a/internal/pkg/overlay/funcmap.go b/internal/pkg/overlay/funcmap.go index 374e4c2d..d9e51a1a 100644 --- a/internal/pkg/overlay/funcmap.go +++ b/internal/pkg/overlay/funcmap.go @@ -10,7 +10,7 @@ import ( "strings" warewulfconf "github.com/warewulf/warewulf/internal/pkg/config" - "github.com/warewulf/warewulf/internal/pkg/container" + "github.com/warewulf/warewulf/internal/pkg/image" "github.com/warewulf/warewulf/internal/pkg/node" "github.com/warewulf/warewulf/internal/pkg/util" "github.com/warewulf/warewulf/internal/pkg/wwlog" @@ -73,32 +73,32 @@ func templateFileBlock(inc string, abortStr string) (string, error) { } /* -Reads a file relative to given container. +Reads a file relative to given image. Templates in the file are no evaluated. */ -func templateContainerFileInclude(containername string, filepath string) string { - wwlog.Verbose("Including file from Container into template: %s:%s", containername, filepath) +func templateImageFileInclude(imagename string, filepath string) string { + wwlog.Verbose("Including file from Image into template: %s:%s", imagename, filepath) - if containername == "" { - wwlog.Warn("Container is not defined for node: %s", filepath) + if imagename == "" { + wwlog.Warn("Image is not defined for node: %s", filepath) return "" } - if !container.ValidSource(containername) { - wwlog.Warn("Template requires file(s) from non-existant container: %s:%s", containername, filepath) + if !image.ValidSource(imagename) { + wwlog.Warn("Template requires file(s) from non-existant image: %s:%s", imagename, filepath) return "" } - containerDir := container.RootFsDir(containername) + imageDir := image.RootFsDir(imagename) - wwlog.Debug("Including file from container: %s:%s", containerDir, filepath) + wwlog.Debug("Including file from image: %s:%s", imageDir, filepath) - if !util.IsFile(path.Join(containerDir, filepath)) { - wwlog.Warn("Requested file from container does not exist: %s:%s", containername, filepath) + if !util.IsFile(path.Join(imageDir, filepath)) { + wwlog.Warn("Requested file from image does not exist: %s:%s", imagename, filepath) return "" } - content, err := os.ReadFile(path.Join(containerDir, filepath)) + content, err := os.ReadFile(path.Join(imageDir, filepath)) if err != nil { wwlog.Error("Template include failed: %s", err) diff --git a/internal/pkg/overlay/overlay.go b/internal/pkg/overlay/overlay.go index e0eba792..1f13a9d4 100644 --- a/internal/pkg/overlay/overlay.go +++ b/internal/pkg/overlay/overlay.go @@ -227,7 +227,7 @@ func FindOverlays() (overlayList []string, err error) { } /* -Build the given overlays for a node and create a Image for them +Build the given overlays for a node and create an image for them */ func BuildOverlay(nodeConf node.Node, allNodes []node.Node, context string, overlayNames []string) error { if len(overlayNames) == 0 && context == "" { @@ -469,7 +469,7 @@ func RenderTemplateFile(fileName string, data TemplateStruct) ( // Build our FuncMap funcMap := template.FuncMap{ "Include": templateFileInclude, - "IncludeFrom": templateContainerFileInclude, + "IncludeFrom": templateImageFileInclude, "IncludeBlock": templateFileBlock, "ImportLink": importSoftlink, "basename": path.Base, diff --git a/internal/pkg/upgrade/config.go b/internal/pkg/upgrade/config.go index dfddfd29..f10f8cca 100644 --- a/internal/pkg/upgrade/config.go +++ b/internal/pkg/upgrade/config.go @@ -29,6 +29,7 @@ type WarewulfYaml struct { TFTP *TFTPConf `yaml:"tftp"` NFS *NFSConf `yaml:"nfs"` SSH *SSHConf `yaml:"ssh"` + MountsImage []*MountEntry `yaml:"image mounts"` MountsContainer []*MountEntry `yaml:"container mounts"` Paths *BuildConfig `yaml:"paths"` WWClient *WWClientConf `yaml:"wwclient"` @@ -61,9 +62,14 @@ func (this *WarewulfYaml) Upgrade() (upgraded *config.WarewulfYaml) { if this.SSH != nil { upgraded.SSH = this.SSH.Upgrade() } - upgraded.MountsContainer = make([]*config.MountEntry, 0) - for _, mount := range this.MountsContainer { - upgraded.MountsContainer = append(upgraded.MountsContainer, mount.Upgrade()) + upgraded.MountsImage = make([]*config.MountEntry, 0) + for _, mount := range this.MountsImage { + upgraded.MountsImage = append(upgraded.MountsImage, mount.Upgrade()) + } + if len(upgraded.MountsImage) == 0 { + for _, mount := range this.MountsContainer { + upgraded.MountsImage = append(upgraded.MountsImage, mount.Upgrade()) + } } if this.Paths != nil { upgraded.Paths = this.Paths.Upgrade() diff --git a/internal/pkg/upgrade/config_test.go b/internal/pkg/upgrade/config_test.go index c0de5c30..d15bf939 100644 --- a/internal/pkg/upgrade/config_test.go +++ b/internal/pkg/upgrade/config_test.go @@ -388,7 +388,7 @@ ssh: - dsa - ecdsa - ed25519 -container mounts: +image mounts: - source: /etc/resolv.conf dest: /etc/resolv.conf readonly: true @@ -482,7 +482,7 @@ ssh: - dsa - ecdsa - ed25519 -container mounts: +image mounts: - source: /etc/resolv.conf dest: /etc/resolv.conf readonly: true diff --git a/internal/pkg/upgrade/node.go b/internal/pkg/upgrade/node.go index 8bea20c6..ccbff429 100644 --- a/internal/pkg/upgrade/node.go +++ b/internal/pkg/upgrade/node.go @@ -154,7 +154,10 @@ func (this *Node) Upgrade(addDefaults bool, replaceOverlays bool) (upgraded *nod upgraded.AssetKey = this.AssetKey upgraded.ClusterName = this.ClusterName upgraded.Comment = this.Comment - upgraded.ContainerName = this.ContainerName + upgraded.ImageName = this.ImageName + if upgraded.ImageName == "" { + upgraded.ImageName = this.ContainerName + } if this.Disabled != "" { logIgnore("Disabled", this.Disabled, "obsolete") } @@ -206,14 +209,14 @@ func (this *Node) Upgrade(addDefaults bool, replaceOverlays bool) (upgraded *nod } upgraded.Ipxe = this.Ipxe if this.Kernel != nil { - upgraded.Kernel = this.Kernel.Upgrade(this.ContainerName) + upgraded.Kernel = this.Kernel.Upgrade(upgraded.ImageName) } else { inlineKernel := &KernelConf{ Args: this.KernelArgs, Version: this.KernelVersion, Override: this.KernelOverride, } - upgraded.Kernel = inlineKernel.Upgrade(this.ContainerName) + upgraded.Kernel = inlineKernel.Upgrade(upgraded.ImageName) } if this.Keys != nil { for key, value := range this.Keys { @@ -298,6 +301,7 @@ type Profile struct { AssetKey string `yaml:"asset key,omitempty"` ClusterName string `yaml:"cluster name,omitempty"` Comment string `yaml:"comment,omitempty"` + ImageName string `yaml:"image name,omitempty"` ContainerName string `yaml:"container name,omitempty"` Disabled string `yaml:"disabled,omitempty"` Discoverable string `yaml:"discoverable,omitempty"` @@ -342,7 +346,10 @@ func (this *Profile) Upgrade(addDefaults bool, replaceOverlays bool) (upgraded * } upgraded.ClusterName = this.ClusterName upgraded.Comment = this.Comment - upgraded.ContainerName = this.ContainerName + upgraded.ImageName = this.ImageName + if upgraded.ImageName == "" { + upgraded.ImageName = this.ContainerName + } if this.Disabled != "" { logIgnore("Disabled", this.Disabled, "obsolete") } @@ -395,14 +402,14 @@ func (this *Profile) Upgrade(addDefaults bool, replaceOverlays bool) (upgraded * } upgraded.Ipxe = this.Ipxe if this.Kernel != nil { - upgraded.Kernel = this.Kernel.Upgrade(this.ContainerName) + upgraded.Kernel = this.Kernel.Upgrade(upgraded.ImageName) } else { inlineKernel := &KernelConf{ Args: this.KernelArgs, Version: this.KernelVersion, Override: this.KernelOverride, } - upgraded.Kernel = inlineKernel.Upgrade(this.ContainerName) + upgraded.Kernel = inlineKernel.Upgrade(upgraded.ImageName) } if this.Keys != nil { for key, value := range this.Keys { @@ -525,29 +532,29 @@ type KernelConf struct { Version string `yaml:"version,omitempty"` } -func (this *KernelConf) Upgrade(containerName string) (upgraded *node.KernelConf) { +func (this *KernelConf) Upgrade(imageName string) (upgraded *node.KernelConf) { upgraded = new(node.KernelConf) upgraded.Args = this.Args - kernels := kernel.FindKernels(containerName) - wwlog.Debug("referencing kernels: %v (containerName: %v)", kernels, containerName) + kernels := kernel.FindKernels(imageName) + wwlog.Debug("referencing kernels: %v (imageName: %v)", kernels, imageName) if this.Override != "" { if version := util.ParseVersion(legacyKernelVersion(this.Override)); version != nil { for _, kernel_ := range kernels { - wwlog.Debug("checking if kernel '%v' version '%v' from container '%v' matches override '%v'", kernel_, kernel_.Version(), containerName, this.Override) + wwlog.Debug("checking if kernel '%v' version '%v' from image '%v' matches override '%v'", kernel_, kernel_.Version(), imageName, this.Override) if kernel_.Version() == version.String() { upgraded.Version = kernel_.Path - wwlog.Info("kernel override %v -> version %v (container %v)", this.Override, upgraded.Version, containerName) + wwlog.Info("kernel override %v -> version %v (image %v)", this.Override, upgraded.Version, imageName) } } - } else if util.IsFile((&kernel.Kernel{ContainerName: containerName, Path: this.Override}).FullPath()) { + } else if util.IsFile((&kernel.Kernel{ImageName: imageName, Path: this.Override}).FullPath()) { upgraded.Version = this.Override } if upgraded.Version == "" { - containerDisplay := "unknown" - if containerName != "" { - containerDisplay = containerName + imageDisplay := "unknown" + if imageName != "" { + imageDisplay = imageName } - wwlog.Warn("unable to resolve kernel override %v (container %v)", this.Override, containerDisplay) + wwlog.Warn("unable to resolve kernel override %v (image %v)", this.Override, imageDisplay) } } if upgraded.Version == "" { diff --git a/internal/pkg/upgrade/node_test.go b/internal/pkg/upgrade/node_test.go index 74fce843..8b035e65 100644 --- a/internal/pkg/upgrade/node_test.go +++ b/internal/pkg/upgrade/node_test.go @@ -688,30 +688,30 @@ nodes: addDefaults: false, replaceOverlays: false, files: map[string]string{ - "/srv/warewulf/kernel/mykernel/version": "1.2.3", - "/var/lib/warewulf/chroots/mycontainer/rootfs/boot/vmlinuz-1.2.3": "", + "/srv/warewulf/kernel/mykernel/version": "1.2.3", + "/var/lib/warewulf/chroots/myimage/rootfs/boot/vmlinuz-1.2.3": "", }, legacyYaml: ` nodeprofiles: default: - container name: mycontainer + container name: myimage kernel: override: mykernel nodes: n1: - container name: mycontainer + container name: myimage kernel: override: mykernel `, upgradedYaml: ` nodeprofiles: default: - container name: mycontainer + image name: myimage kernel: version: /boot/vmlinuz-1.2.3 nodes: n1: - container name: mycontainer + image name: myimage kernel: version: /boot/vmlinuz-1.2.3 `, @@ -721,30 +721,30 @@ nodes: addDefaults: false, replaceOverlays: false, files: map[string]string{ - "/srv/warewulf/kernel/mykernel/version": "1.2.3", - "/var/lib/warewulf/chroots/mycontainer/rootfs/boot/vmlinuz-1.2.3": "", + "/srv/warewulf/kernel/mykernel/version": "1.2.3", + "/var/lib/warewulf/chroots/myimage/rootfs/boot/vmlinuz-1.2.3": "", }, legacyYaml: ` nodeprofiles: default: - container name: mycontainer + container name: myimage kernel: override: /boot/vmlinuz-1.2.3 nodes: n1: - container name: mycontainer + container name: myimage kernel: override: /boot/vmlinuz-1.2.3 `, upgradedYaml: ` nodeprofiles: default: - container name: mycontainer + image name: myimage kernel: version: /boot/vmlinuz-1.2.3 nodes: n1: - container name: mycontainer + image name: myimage kernel: version: /boot/vmlinuz-1.2.3 `, diff --git a/internal/pkg/warewulfd/copyshim.go b/internal/pkg/warewulfd/copyshim.go index 4f085017..0ba3ea66 100644 --- a/internal/pkg/warewulfd/copyshim.go +++ b/internal/pkg/warewulfd/copyshim.go @@ -8,7 +8,7 @@ import ( warewulfconf "github.com/warewulf/warewulf/internal/pkg/config" "github.com/warewulf/warewulf/internal/pkg/wwlog" - "github.com/warewulf/warewulf/internal/pkg/container" + "github.com/warewulf/warewulf/internal/pkg/image" "github.com/warewulf/warewulf/internal/pkg/util" ) @@ -20,7 +20,7 @@ to the tftp directory func CopyShimGrub() (err error) { conf := warewulfconf.Get() wwlog.Debug("copy shim and grub binaries from host") - shimPath := container.ShimFind("") + shimPath := image.ShimFind("") if shimPath == "" { return fmt.Errorf("no shim found on the host os") } @@ -29,7 +29,7 @@ func CopyShimGrub() (err error) { return err } _ = os.Chmod(path.Join(conf.TFTP.TftpRoot, "warewulf", "shim.efi"), 0o755) - grubPath := container.GrubFind("") + grubPath := image.GrubFind("") if grubPath == "" { return fmt.Errorf("no grub found on host os") } diff --git a/internal/pkg/warewulfd/parser.go b/internal/pkg/warewulfd/parser.go index 2d3e846d..eea3c190 100644 --- a/internal/pkg/warewulfd/parser.go +++ b/internal/pkg/warewulfd/parser.go @@ -63,8 +63,8 @@ func parseReq(req *http.Request) (parserInfo, error) { ret.stage = "ipxe" } else if stage == "kernel" { ret.stage = "kernel" - } else if stage == "container" { - ret.stage = "container" + } else if stage == "image" { + ret.stage = "image" } else if stage == "overlay-system" { ret.stage = "system" } else if stage == "overlay-runtime" { diff --git a/internal/pkg/warewulfd/provision.go b/internal/pkg/warewulfd/provision.go index 1ee831d7..3af3aca6 100644 --- a/internal/pkg/warewulfd/provision.go +++ b/internal/pkg/warewulfd/provision.go @@ -13,7 +13,7 @@ import ( "github.com/Masterminds/sprig/v3" warewulfconf "github.com/warewulf/warewulf/internal/pkg/config" - "github.com/warewulf/warewulf/internal/pkg/container" + "github.com/warewulf/warewulf/internal/pkg/image" "github.com/warewulf/warewulf/internal/pkg/kernel" "github.com/warewulf/warewulf/internal/pkg/node" "github.com/warewulf/warewulf/internal/pkg/overlay" @@ -28,7 +28,7 @@ type templateVars struct { Fqdn string Id string Cluster string - ContainerName string + ImageName string Hwaddr string Ipaddr string Port string @@ -106,7 +106,7 @@ func ProvisionSend(w http.ResponseWriter, req *http.Request) { Port: strconv.Itoa(conf.Warewulf.Port), Hostname: remoteNode.Id(), Hwaddr: rinfo.hwaddr, - ContainerName: remoteNode.ContainerName, + ImageName: remoteNode.ImageName, KernelArgs: remoteNode.Kernel.Args, KernelVersion: remoteNode.Kernel.Version, NetDevs: remoteNode.NetDevs, @@ -122,11 +122,11 @@ func ProvisionSend(w http.ResponseWriter, req *http.Request) { } } - } else if rinfo.stage == "container" { - if remoteNode.ContainerName != "" { - stage_file = container.ImageFile(remoteNode.ContainerName) + } else if rinfo.stage == "image" { + if remoteNode.ImageName != "" { + stage_file = image.ImageFile(remoteNode.ImageName) } else { - wwlog.Warn("No container set for node %s", remoteNode.Id()) + wwlog.Warn("No image set for node %s", remoteNode.Id()) } } else if rinfo.stage == "system" || rinfo.stage == "runtime" { @@ -156,19 +156,19 @@ func ProvisionSend(w http.ResponseWriter, req *http.Request) { } } else if rinfo.stage == "efiboot" { wwlog.Debug("requested method: %s", req.Method) - containerName := remoteNode.ContainerName + imageName := remoteNode.ImageName switch rinfo.efifile { case "shim.efi": - stage_file = container.ShimFind(containerName) + stage_file = image.ShimFind(imageName) if stage_file == "" { - wwlog.Error("couldn't find shim.efi for %s", containerName) + wwlog.Error("couldn't find shim.efi for %s", imageName) w.WriteHeader(http.StatusNotFound) return } case "grub.efi", "grub-tpm.efi", "grubx64.efi", "grubia32.efi", "grubaa64.efi", "grubarm.efi": - stage_file = container.GrubFind(containerName) + stage_file = image.GrubFind(imageName) if stage_file == "" { - wwlog.Error("could't find grub*.efi for %s", containerName) + wwlog.Error("could't find grub*.efi for %s", imageName) w.WriteHeader(http.StatusNotFound) return } @@ -188,13 +188,13 @@ func ProvisionSend(w http.ResponseWriter, req *http.Request) { Port: strconv.Itoa(conf.Warewulf.Port), Hostname: remoteNode.Id(), Hwaddr: rinfo.hwaddr, - ContainerName: remoteNode.ContainerName, + ImageName: remoteNode.ImageName, KernelArgs: kernelArgs, KernelVersion: kernelVersion, NetDevs: remoteNode.NetDevs, Tags: remoteNode.Tags} if stage_file == "" { - wwlog.Error("could't find grub.cfg template for %s", containerName) + wwlog.Error("could't find grub.cfg template for %s", imageName) w.WriteHeader(http.StatusNotFound) return } @@ -202,20 +202,20 @@ func ProvisionSend(w http.ResponseWriter, req *http.Request) { wwlog.ErrorExc(fmt.Errorf("could't find efiboot file: %s", rinfo.efifile), "") } } else if rinfo.stage == "shim" { - if remoteNode.ContainerName != "" { - stage_file = container.ShimFind(remoteNode.ContainerName) + if remoteNode.ImageName != "" { + stage_file = image.ShimFind(remoteNode.ImageName) if stage_file == "" { - wwlog.Error("No kernel found for container %s", remoteNode.ContainerName) + wwlog.Error("No kernel found for image %s", remoteNode.ImageName) } } else { - wwlog.Warn("No container set for this %s", remoteNode.Id()) + wwlog.Warn("No image set for this %s", remoteNode.Id()) } } else if rinfo.stage == "grub" { - if remoteNode.ContainerName != "" { - stage_file = container.GrubFind(remoteNode.ContainerName) + if remoteNode.ImageName != "" { + stage_file = image.GrubFind(remoteNode.ImageName) if stage_file == "" { - wwlog.Error("No grub found for container %s", remoteNode.ContainerName) + wwlog.Error("No grub found for image %s", remoteNode.ImageName) } } else { wwlog.Warn("No conainer set for node %s", remoteNode.Id()) @@ -223,10 +223,10 @@ func ProvisionSend(w http.ResponseWriter, req *http.Request) { } else if rinfo.stage == "initramfs" { if kernel_ := kernel.FromNode(&remoteNode); kernel_ != nil { if kver := kernel_.Version(); kver != "" { - if initramfs := container.FindInitramfs(remoteNode.ContainerName, kver); initramfs != nil { + if initramfs := image.FindInitramfs(remoteNode.ImageName, kver); initramfs != nil { stage_file = initramfs.FullPath() } else { - wwlog.Error("No initramfs found for kernel %s in container %s", kver, remoteNode.ContainerName) + wwlog.Error("No initramfs found for kernel %s in image %s", kver, remoteNode.ImageName) } } else { wwlog.Error("No initramfs found: unable to determine kernel version for node %s", remoteNode.Id()) diff --git a/internal/pkg/warewulfd/provision_test.go b/internal/pkg/warewulfd/provision_test.go index 3072e94a..9833b139 100644 --- a/internal/pkg/warewulfd/provision_test.go +++ b/internal/pkg/warewulfd/provision_test.go @@ -40,7 +40,7 @@ func Test_ProvisionSend(t *testing.T) { env.WriteFile("etc/warewulf/nodes.conf", `nodeprofiles: default: - container name: suse + image name: suse nodes: n1: network devices: @@ -52,7 +52,7 @@ nodes: network devices: default: hwaddr: 00:00:00:00:ff:ff - container name: none + image name: none tags: GrubMenuEntry: dracut n3: diff --git a/internal/pkg/warewulfd/warewulfd.go b/internal/pkg/warewulfd/warewulfd.go index 15dc4220..8b0709b4 100644 --- a/internal/pkg/warewulfd/warewulfd.go +++ b/internal/pkg/warewulfd/warewulfd.go @@ -70,7 +70,7 @@ func RunServer() error { wwHandler.HandleFunc("/ipxe/", ProvisionSend) wwHandler.HandleFunc("/efiboot/", ProvisionSend) wwHandler.HandleFunc("/kernel/", ProvisionSend) - wwHandler.HandleFunc("/container/", ProvisionSend) + wwHandler.HandleFunc("/image/", ProvisionSend) wwHandler.HandleFunc("/overlay-system/", ProvisionSend) wwHandler.HandleFunc("/overlay-runtime/", ProvisionSend) wwHandler.HandleFunc("/status", StatusSend) diff --git a/overlays/debug/internal/debug_test.go b/overlays/debug/internal/debug_test.go index 16107854..dce506b6 100644 --- a/overlays/debug/internal/debug_test.go +++ b/overlays/debug/internal/debug_test.go @@ -75,7 +75,7 @@ data from other structures. - Hostname: node1 - Comment: - ClusterName: -- ContainerName: rockylinux-9 +- ImageName: rockylinux-9 - Ipxe: default - RuntimeOverlay: hosts,ssh.authorized_keys,syncuser - SystemOverlay: wwinit,wwclient,fstab,hostname,ssh.host_keys,issue,resolv,udev.netname,systemd.netname,ifcfg,NetworkManager,debian.interfaces,wicked,ignition @@ -187,7 +187,7 @@ data from other structures. - Id: node1 - Comment: - ClusterName: - - ContainerName: rockylinux-9 + - ImageName: rockylinux-9 - Ipxe: default - RuntimeOverlay: [hosts ssh.authorized_keys syncuser] - SystemOverlay: [wwinit wwclient fstab hostname ssh.host_keys issue resolv udev.netname systemd.netname ifcfg NetworkManager debian.interfaces wicked ignition] @@ -244,7 +244,7 @@ data from other structures. - Id: node2 - Comment: - ClusterName: - - ContainerName: + - ImageName: - Ipxe: default - RuntimeOverlay: [hosts ssh.authorized_keys syncuser] - SystemOverlay: [wwinit wwclient fstab hostname ssh.host_keys issue resolv udev.netname systemd.netname ifcfg NetworkManager debian.interfaces wicked ignition] diff --git a/overlays/debug/internal/nodes.conf b/overlays/debug/internal/nodes.conf index 0aeadbcf..0054cf21 100644 --- a/overlays/debug/internal/nodes.conf +++ b/overlays/debug/internal/nodes.conf @@ -28,7 +28,7 @@ nodes: node1: profiles: - default - container name: rockylinux-9 + image name: rockylinux-9 network devices: default: device: wwnet0 diff --git a/overlays/debug/rootfs/warewulf/template-variables.md.ww b/overlays/debug/rootfs/warewulf/template-variables.md.ww index 810996ae..f3c39325 100644 --- a/overlays/debug/rootfs/warewulf/template-variables.md.ww +++ b/overlays/debug/rootfs/warewulf/template-variables.md.ww @@ -17,7 +17,7 @@ data from other structures. - Hostname: {{ .Hostname }} - Comment: {{ .Comment }} - ClusterName: {{ .ClusterName }} -- ContainerName: {{ .ContainerName }} +- ImageName: {{ .ImageName }} - Ipxe: {{ .Ipxe }} - RuntimeOverlay: {{ range $index, $value := .RuntimeOverlay }}{{ if $index }},{{ end }}{{ $value }}{{ end }} - SystemOverlay: {{ range $index, $value := .SystemOverlay }}{{ if $index }},{{ end }}{{ $value }}{{ end }} @@ -130,7 +130,7 @@ data from other structures. - Id: {{ $node.Id }} - Comment: {{ $node.Comment }} - ClusterName: {{ $node.ClusterName }} - - ContainerName: {{ $node.ContainerName }} + - ImageName: {{ $node.ImageName }} - Ipxe: {{ $node.Ipxe }} - RuntimeOverlay: {{ $node.RuntimeOverlay }} - SystemOverlay: {{ $node.SystemOverlay }} diff --git a/overlays/issue/internal/issue_test.go b/overlays/issue/internal/issue_test.go index d24eea14..7855f185 100644 --- a/overlays/issue/internal/issue_test.go +++ b/overlays/issue/internal/issue_test.go @@ -51,7 +51,7 @@ const issue string = `backupFile: true writeFile: true Filename: etc/issue Warewulf Node: node1 -Container: rockylinux-9 +Image: rockylinux-9 Kernelargs: quiet crashkernel=no vga=791 net.naming-scheme=v238 Network: diff --git a/overlays/issue/internal/nodes.conf b/overlays/issue/internal/nodes.conf index fac3a0be..82bba252 100644 --- a/overlays/issue/internal/nodes.conf +++ b/overlays/issue/internal/nodes.conf @@ -1,6 +1,6 @@ nodes: node1: - container name: rockylinux-9 + image name: rockylinux-9 kernel: args: quiet crashkernel=no vga=791 net.naming-scheme=v238 network devices: diff --git a/overlays/issue/rootfs/etc/issue.ww b/overlays/issue/rootfs/etc/issue.ww index c6f4fe7e..65c910e7 100644 --- a/overlays/issue/rootfs/etc/issue.ww +++ b/overlays/issue/rootfs/etc/issue.ww @@ -1,5 +1,5 @@ Warewulf Node: {{.Id}} -Container: {{.Container}} +Image: {{.ImageName}} {{ if .Kernel.Version }}Kernel: {{.Kernel.Version}} {{ end -}} Kernelargs: {{.Kernel.Args}} diff --git a/overlays/syncuser/rootfs/etc/group.ww b/overlays/syncuser/rootfs/etc/group.ww index ec6e50b2..007ca265 100644 --- a/overlays/syncuser/rootfs/etc/group.ww +++ b/overlays/syncuser/rootfs/etc/group.ww @@ -1,2 +1,2 @@ -{{IncludeFrom $.Container "/etc/group"}} -{{Include "/etc/group"}} \ No newline at end of file +{{IncludeFrom $.ImageName "/etc/group"}} +{{Include "/etc/group"}} diff --git a/overlays/syncuser/rootfs/etc/passwd.ww b/overlays/syncuser/rootfs/etc/passwd.ww index 70a04234..ec3c9964 100644 --- a/overlays/syncuser/rootfs/etc/passwd.ww +++ b/overlays/syncuser/rootfs/etc/passwd.ww @@ -1,4 +1,4 @@ # Uncomment the following line to enable passwordless root login # root::0:0:root:/root:/bin/bash -{{IncludeFrom $.Container "/etc/passwd"}} -{{Include "/etc/passwd"}} \ No newline at end of file +{{IncludeFrom $.ImageName "/etc/passwd"}} +{{Include "/etc/passwd"}} diff --git a/overlays/wwinit/internal/nodes.conf b/overlays/wwinit/internal/nodes.conf index 0174efe0..c217eff8 100644 --- a/overlays/wwinit/internal/nodes.conf +++ b/overlays/wwinit/internal/nodes.conf @@ -3,7 +3,7 @@ nodes: init: /sbin/init root: initramfs ipxe template: default - container name: rockylinux-9 + image name: rockylinux-9 ipmi: username: user password: password diff --git a/overlays/wwinit/internal/wwinit_test.go b/overlays/wwinit/internal/wwinit_test.go index 56bd1e09..a09b9f14 100644 --- a/overlays/wwinit/internal/wwinit_test.go +++ b/overlays/wwinit/internal/wwinit_test.go @@ -85,7 +85,7 @@ nfs: const wwinit_config string = `backupFile: true writeFile: true Filename: warewulf/config -WWCONTAINER=rockylinux-9 +WWIMAGE=rockylinux-9 WWHOSTNAME=node1 WWROOT=initramfs WWINIT=/sbin/init diff --git a/overlays/wwinit/rootfs/warewulf/config.ww b/overlays/wwinit/rootfs/warewulf/config.ww index cb1e3a77..d583902d 100644 --- a/overlays/wwinit/rootfs/warewulf/config.ww +++ b/overlays/wwinit/rootfs/warewulf/config.ww @@ -1,4 +1,4 @@ -WWCONTAINER={{$.Container}} +WWIMAGE={{$.ImageName}} WWHOSTNAME={{$.Id}} WWROOT={{$.Root}} WWINIT={{$.Init}} diff --git a/userdocs/contents/boot-management.rst b/userdocs/contents/boot-management.rst index 272d5740..f246298c 100644 --- a/userdocs/contents/boot-management.rst +++ b/userdocs/contents/boot-management.rst @@ -6,7 +6,7 @@ Warewulf uses iPXE to for network boot by default. As a tech preview, support for GRUB is also available, which adds support for secure boot. Also as a tech preview, Warewulf may also use iPXE to boot a dracut -initramfs as an initial stage before loading the container image. +initramfs as an initial stage before loading the image. Booting with iPXE ================= @@ -28,7 +28,7 @@ Booting with iPXE bios->iPXE [lhead=cluster0,label="iPXE.efi"]; - kernel [shape=record label="{kernel|ramdisk (root fs)|wwinit overlay}|extracted from node container"]; + kernel [shape=record label="{kernel|ramdisk (root fs)|wwinit overlay}|extracted from node image"]; ipxe_cfg->kernel[ltail=cluster0,label="http"]; } @@ -216,7 +216,7 @@ Warewulf as a technology preview. grubcfg[shape=record label="{grub.cfg|static under TFTP root}"]; grub->grubcfg[label="TFTP"]; } - kernel [shape=record label="{kernel|ramdisk (root fs)|wwinit overlay}|extracted from node container"]; + kernel [shape=record label="{kernel|ramdisk (root fs)|wwinit overlay}|extracted from node image"]; grubcfg->kernel[ltail=cluster1,label="http"]; } @@ -258,22 +258,22 @@ If secure boot is enabled at every step a signature is checked and the boot process fails if this check fails. The shim typically only includes the key for a single operating system, which means that each distribution needs separate `shim` and `grub` executables. Warewulf extracts these binaries from the -containers. If the node is unknown to Warewulf or can't be identified during +images. If the node is unknown to Warewulf or can't be identified during the TFTP boot phase, the shim/grub binaries of the host in which Warewulf is running are used. Install shim and efi -------------------- -`shim.efi` and `grub.efi` must be installed in the container for it to be +`shim.efi` and `grub.efi` must be installed in the image for it to be booted by GRUB. .. code-block:: console - # wwctl container shell leap15.5 + # wwctl image shell leap15.5 [leap15.5] Warewulf> zypper install grub2 shim - # wwctl container shell rocky9 + # wwctl image shell rocky9 [rocky9] Warewulf> dnf install shim-x64.x86_64 grub2-efi-x64.x86_64 These packages must also be installed on the Warewulf server host to enable @@ -290,16 +290,16 @@ is the following: digraph G{ node [shape=box]; efi [shape=record label="{EFI|boots from URI defined in filename}"]; - shim [shape=record label="{shim.efi|replaces shim.efi with grubx64.efi in URI|extracted from node container}"]; - grub [shape=record label="{grub.efi|checks for grub.cfg|extracted from node container}"] - kernel [shape=record label="{kernel|ramdisk (root fs)|wwinit overlay}|extracted from node container"]; + shim [shape=record label="{shim.efi|replaces shim.efi with grubx64.efi in URI|extracted from node image}"]; + grub [shape=record label="{grub.efi|checks for grub.cfg|extracted from node image}"] + kernel [shape=record label="{kernel|ramdisk (root fs)|wwinit overlay}|extracted from node image"]; efi->shim [label="http"]; shim->grub [label="http"]; grub->kernel [label="http"]; } Warewulf delivers the initial `shim.efi` and `grub.efi` via http as taken -directly from the node's assigned container. +directly from the node's assigned image. .. _booting with dracut: @@ -307,19 +307,19 @@ Booting with dracut =================== Some systems, typically due to limitations in their BIOS or EFI -firmware, are unable to load container image of a certain size +firmware, are unable to load image of a certain size directly with a traditional bootloader, either iPXE or GRUB. As a workaround for such systems, Warewulf can be configured to load a -dracut initramfs from the container and to use that initramfs to load -the full container image. +dracut initramfs from the image and to use that initramfs to load +the full image. Warewulf provides a dracut module to configure the dracut initramfs to -load the container image. This module is available in the +load the image. This module is available in the ``warewulf-dracut`` subpackage, which must be installed in the -container image. +image. With the ``warewulf-dracut`` package installed, you can build an -initramfs inside the container. +initramfs inside the image. .. code-block:: shell @@ -369,9 +369,9 @@ dracut semantics, set a ``GrubMenuEntry`` tag for the node. The ``GrubMenuEntry`` variable may be set at the node or profile level. During boot, ``warewulfd`` will detect and dynamically serve an -initramfs from a node's container image in much the same way that it -can serve a kernel from a container image. This image is loaded by -iPXE (or GRUB) which directs dracut to fetch the node's container image +initramfs from a node's image in much the same way that it +can serve a kernel from an image. This image is loaded by +iPXE (or GRUB) which directs dracut to fetch the node's image during boot. The wwinit module provisions to tmpfs. By default, tmpfs is permitted diff --git a/userdocs/contents/configuration.rst b/userdocs/contents/configuration.rst index 1cc2c897..67a22d82 100644 --- a/userdocs/contents/configuration.rst +++ b/userdocs/contents/configuration.rst @@ -40,7 +40,7 @@ Warewulf (4.5.8): - path: /opt export options: ro,sync,no_root_squash systemd name: nfs-server - container mounts: + image mounts: - source: /etc/resolv.conf dest: /etc/resolv.conf readonly: true @@ -114,8 +114,8 @@ explained as follows: * ``nfs:export paths``: Warewulf can automatically set up these NFS exports. -* ``container mounts``: These paths are mounted into the container - during ``container exec`` or ``container shell``, typically to allow +* ``image mounts``: These paths are mounted into the image + during ``image exec`` or ``image shell``, typically to allow them to operate in the host environment prior to deployment. Paths @@ -123,7 +123,7 @@ Paths *New in Warewulf v4.5.0* -Default paths to containers, overlays, and other Warewulf components +Default paths to images, overlays, and other Warewulf components may be overridden using ``warewulf.conf:paths``. .. code-block:: yaml @@ -145,9 +145,9 @@ may be overridden using ``warewulf.conf:paths``. * ``wwoverlaydir``: The source for Warewulf overlays. -* ``wwchrootdir``: The source for Warewulf containers. +* ``wwchrootdir``: The source for Warewulf images. -* ``wwprovisiondir``: Where to store built overlays, built containers, and imported kernels. +* ``wwprovisiondir``: Where to store built overlays, built images, and imported kernels. * ``wwclientdir``: Where the Warewulf client looks for its configuration on a provisioned node. @@ -192,7 +192,7 @@ command. .. note:: - When ``nodes.conf`` is edited directly, ``warewulfd`` does not know that the container profile has been changed. Therefore the changes to ``nodes.conf`` are not taken into account by ``warewulfd`` until it is restarted. + When ``nodes.conf`` is edited directly, ``warewulfd`` does not know that the image profile has been changed. Therefore the changes to ``nodes.conf`` are not taken into account by ``warewulfd`` until it is restarted. Once you restart ``warewulfd``, the ``nodes.conf`` file is then successfully reloaded. This also goes for ``warewulf.conf`` as well - any changes made also require ``warewulfd`` to be restarted. The restart should be done using the following command: ``systemctl restart warewulfd`` diff --git a/userdocs/contents/disks.rst b/userdocs/contents/disks.rst index 0c2ebd81..b17eb244 100644 --- a/userdocs/contents/disks.rst +++ b/userdocs/contents/disks.rst @@ -17,7 +17,7 @@ Warewulf can be used, for example, to create ``swap`` partitions or ``/scratch`` Requirements ============ -Partition and file system creation requires both ``ignition`` and ``sgdisk`` to be installed in the container image. +Partition and file system creation requires both ``ignition`` and ``sgdisk`` to be installed in the image. Rocky Linux ----------- @@ -55,7 +55,7 @@ Each partition has the switches ``should_exist`` and ``wipe_partition_entry`` wh File systems are identified by their underlying block device, preferably using the ``/dev/by-partlabel`` format. Except for a ``swap`` partition, an absolute path for the mount point must be specified for each file system. -Depending on the container used, valid formats are ``btrfs``, ``ext3``, ``ext4``, and ``xfs``. +Depending on the image used, valid formats are ``btrfs``, ``ext3``, ``ext4``, and ``xfs``. Each file system has the switch ``wipe_filesystem`` to control whether an existing file system is wiped. Ignition Implementation diff --git a/userdocs/contents/glossary.rst b/userdocs/contents/glossary.rst index 8ff34bc7..7d7bf9c5 100644 --- a/userdocs/contents/glossary.rst +++ b/userdocs/contents/glossary.rst @@ -2,15 +2,12 @@ Glossary ======== -Container - Warewulf containers are the node images that it manages and provisions. - The use of the term "container" alludes to Warewulf's support for importing OCI containers, OCI container archives, and Apptainer sandboxes to initialize its node images. +Image + The node images that Warewulf manages and provisions. + Images may be mported from OCI image registries, OCI image archives, Apptainer sandboxes, and manual chroot directories. - Warewulf containers are maintained as an uncompressed "virtual node file system" or VNFS, (sometimes also referred to as a "chroot"). - These containers are then built as images which may then be used to provision a node. - - It is important to note, however, that Warewulf does not provision virtualized or nested "containers" in the common sense; - Warewulf nodes run a decompressed image on "bare metal" loaded directly into system memory. + Warewulf images are maintained as an uncompressed "virtual node file system" or VNFS, (sometimes also referred to as a "chroot"). + These images are then built as images which may then be used to provision a node. Controller The Warewulf controller runs the Warewulf daemon (``warewulfd``) and is responsible for the management, control, and administration of the cluster. @@ -20,11 +17,11 @@ Controller though these services may be managed separately and on separate servers. Kernel - In addition to a container, Warewulf also requires a kernel (typically a Linux kernel) in order to provision a node. + In addition to an image, Warewulf also requires a kernel (typically a Linux kernel) in order to provision a node. - Kernels may be imported independently into Warewulf, either from the controller or from a container; - however, recent versions of Warewulf (after v4.3.0) support automatically provisioning with a kernel detected and extracted from the container itself. - In most cases, kernels may be installed in the container using normal system packages, and no special consideration is necessary. + Kernels may be imported independently into Warewulf, either from the controller or from an image; + however, recent versions of Warewulf (after v4.3.0) support automatically provisioning with a kernel detected and extracted from the image itself. + In most cases, kernels may be installed in the image using normal system packages, and no special consideration is necessary. Node Warewulf nodes are the systems that are being provisioned by Warewulf. @@ -32,10 +29,10 @@ Node nodes.conf One of two primary Warewulf configuration files, ``nodes.conf`` is a YAML document which records all configuration parameters for Warewulf's nodes and profiles. - It does not contain the containers or overlays, but refers to them by name. + It does not contain the images or overlays, but refers to them by name. Overlay - Warewulf overlays provide customization for the provisioned container image. + Warewulf overlays provide customization for the provisioned image. Overlays may be configured on nodes or profiles, as either **system** or **runtime** overlays. **System overlays** are applied only once, when a node is first provisioned. @@ -49,7 +46,7 @@ Profile and this configuration may be mixed with configuration from other profiles. wwctl - The main administrative interface for Warewulf is the ``wwctl`` command, which provides commands to manage nodes, profiles, containers, overlays, kernels, and more. + The main administrative interface for Warewulf is the ``wwctl`` command, which provides commands to manage nodes, profiles, images, overlays, kernels, and more. wwinit Warewulf performs some setup during the provisioning process before control is passed to the provisioned operating system. diff --git a/userdocs/contents/containers.rst b/userdocs/contents/images.rst similarity index 67% rename from userdocs/contents/containers.rst rename to userdocs/contents/images.rst index c68de260..9ae0b7d4 100644 --- a/userdocs/contents/containers.rst +++ b/userdocs/contents/images.rst @@ -1,6 +1,6 @@ -==================== -Container Management -==================== +================ +Image Management +================ Since the inception of Warewulf over 20 years ago, Warewulf has used the model of the "Virtual Node File System" (VNFS) as a template image @@ -8,12 +8,11 @@ for the compute nodes. This is similar to a golden master image, except that the node file system exists within a directory on the Warewulf control node (e.g. a ``chroot()``). -In hindsight, we've been using containers all along, but the buzzword -just didn't exist. Over the last 5-6 years, the enterprise has created +Meanwhile, the enterprise has created a lot of tooling and standards around defining, building, distributing, securing, and managing containers, so Warewulf v4 now integrates directly within the container ecosystem to facilitate the -process of VNFS image management. +process of image management. If you are not currently leveraging the container ecosystem in any other way, you can still build your own chroot directories and use @@ -21,24 +20,24 @@ Warewulf as before. It is important to understand that Warewulf is not running a container runtime on cluster nodes. While it is absolutely possible to run -containers on cluster nodes, Warewulf is provisioning the container -image to the bare metal and booting it. This container will be used as +containers on cluster nodes, Warewulf is provisioning the +image to the bare metal and booting it. This image will be used as the base operating system and, by default, it will run entirely in memory. This means that when you reboot the node, the node retains no information about Warewulf or how it booted. -Container Tools -=============== +Tools +===== There are different container managment tools available. Docker is probably the most recognizable one in the enterprise. Podman is another one that is gaining traction on the RHEL platforms. In HPC, -Apptainer is the most utilized container management tool. You can use +Apptainer is the most utilized image management tool. You can use any of these to create and manage the containers to be later imported into Warewulf. -Importing Containers -==================== +Importing Images +================ Warewulf supports importing an image from any OCI compliant registry. This means you can import from a public registry or from a @@ -48,32 +47,32 @@ Here is an example of importing from Docker Hub. .. code-block:: console - # wwctl container import docker://ghcr.io/warewulf/warewulf-rockylinux:8 rocky-8 + # wwctl image import docker://ghcr.io/warewulf/warewulf-rockylinux:8 rocky-8 Getting image source signatures Copying blob d7f16ed6f451 done Copying config da2ca70704 done Writing manifest to image destination Storing signatures [LOG] info unpack layer: sha256:d7f16ed6f45129c7f4adb3773412def4ba2bf9902de42e86e77379a65d90a984 - Updating the container's /etc/resolv.conf - Building container: rocky-8 + Updating the image's /etc/resolv.conf + Building image: rocky-8 .. note:: - Most containers in Docker Hub are not "bootable", in that, they + Most images in Docker Hub are not "bootable", in that, they have a limited version of Systemd to make them lighter weight for - container purposes. For this reason, don't expect any base Docker - container (e.g. ``docker://rockylinux`` or ``docker://debian``) to + image purposes. For this reason, don't expect any base Docker + image (e.g. ``docker://rockylinux`` or ``docker://debian``) to boot properly. They will not, as they will get stuck into a single - user mode. The containers in `https://hub.docker.com/u/warewulf - `_ are not limited and thus + user mode. The images in `https://github.com/warewulf/warewulf-node-images + `_ are not limited and thus they boot as you would expect. Platform -------- By default, -Warewulf will try to import a container of the same platform +Warewulf will try to import an image of the same platform (e.g., amd64, arm64) as the local system. To specify the platform to import, @@ -115,7 +114,7 @@ table. Local Files ----------- -It is also possible to import a container from a local file or +It is also possible to import an image from a local file or directory. For example, Podman can save a `.tar` archive of an OCI image. This archive can be directly imported into Warewulf, no registry required. @@ -123,7 +122,7 @@ registry required. .. code-block:: console # podman save alpine:latest >alpine.tar - # wwctl container import alpine.tar alpine + # wwctl image import alpine.tar alpine Chroot directories and Apptainer sandbox images can also be imported directly. @@ -131,7 +130,7 @@ directly. .. code-block:: console $ apptainer build --sandbox ./rockylinux-8/ docker://ghcr.io/warewulf/warewulf-rockylinux:8 - $ sudo wwctl container import ./rockylinux-8/ rockylinux-8 + $ sudo wwctl image import ./rockylinux-8/ rockylinux-8 .. note:: @@ -152,12 +151,12 @@ HTTP proxies ------------ You can set ``HTTP_PROXY``, ``HTTPS_PROXY``, and ``NO_PROXY`` (or their -lower-case versions) to use a proxy during ``wwctl container import``. +lower-case versions) to use a proxy during ``wwctl image import``. .. code-block:: shell export HTTPS_PROXY=squid.localdomain - wwctl container import docker://ghcr.io/warewulf/warewulf-rockylinux:8 + wwctl image import docker://ghcr.io/warewulf/warewulf-rockylinux:8 See ProxyFromEnvironment_ For more information. @@ -172,64 +171,64 @@ Syncuser ======== At import time Warewulf checks if the names of the users on the host -match the users and UIDs/GIDs in the imported container. If there is +match the users and UIDs/GIDs in the imported image. If there is mismatch, the import command will print out a warning. By setting the ``--syncuser`` flag you advise Warewulf to try to syncronize the users -from the host to the container, which means that ``/etc/passwd`` and -``/etc/group`` of the imported container are updated and all the files +from the host to the image, which means that ``/etc/passwd`` and +``/etc/group`` of the imported image are updated and all the files belonging to these UIDs and GIDs will also be updated. -A check if the users of the host and container matches can be +A check if the users of the host and image matches can be triggered with the ``syncuser`` command. .. code-block:: console - # wwctl container syncuser container-name + # wwctl image syncuser image-name -With the ``--write`` flag it will update the container to match the +With the ``--write`` flag it will update the image to match the user database of the host as described above. .. code-block:: console - wwctl container syncuser --write container-name + wwctl image syncuser --write image-name -Listing All Imported Containers -=============================== +Listing All Imported Images +=========================== -Once the container has been imported, you can list them all with the +Once the image has been imported, you can list them all with the following command: .. code-block:: console - # wwctl container list - CONTAINER NAME BUILT NODES - rocky-8 true 0 + # wwctl image list + IMAGE NAME + ---------- + rocky-8 -Once a container has been imported and showing up in this list you can +Once an image has been imported and showing up in this list you can configure it to boot compute nodes. -Making Changes To Containers -============================ +Making Changes To Images +======================== -Warewulf has a minimal container runtime built into it. This means you -can run commands inside of any of the containers and make changes to +You can run commands inside of any of the images and make changes to them as follows: .. code-block:: console - # wwctl container exec rocky-8 /bin/sh + # wwctl image exec rocky-8 /bin/sh [rocky-8] Warewulf> cat /etc/rocky-release Rocky Linux release 8.4 (Green Obsidian) [rocky-8] Warewulf> exit - Rebuilding container... - [INFO] Skipping (VNFS is current) + Rebuilding image... + [INFO] Skipping (image is current) -You can also ``--bind`` directories from your host into the container +You can also ``--bind`` directories from your host into the image when using the exec command. This works as follows: .. code-block:: console - # wwctl container shell --bind /tmp:/mnt rocky-8 + # wwctl image shell --bind /tmp:/mnt rocky-8 [rocky-8] Warewulf> .. note:: @@ -239,12 +238,12 @@ when using the exec command. This works as follows: location, as it is almost always present and empty in every Linux distribution (as prescribed by the LSB file hierarchy standard). -Files which should always be present in a container image like ``resolv.conf`` +Files which should always be present in an image like ``resolv.conf`` can be specified in ``warewulf.conf``: .. code-block:: yaml - container mounts: + image mounts: - source: /etc/resolv.conf dest: /etc/resolv.conf readonly: true @@ -252,26 +251,26 @@ can be specified in ``warewulf.conf``: .. note:: Instead of ``readonly: true`` you can set ``copy: true``. This causes the - source file to be copied to the container and removed if it was not + source file to be copied to the image and removed if it was not modified. This can be useful for files used for registrations. -When the command completes, if anything within the container changed, -the container will be rebuilt into a bootable static object -automatically. (To skip the automatic container rebuild, specify ``--build=false``.) +When the command completes, if anything within the image changed, +the image will be rebuilt into a bootable static object +automatically. (To skip the automatic image rebuild, specify ``--build=false``.) If the files ``/etc/passwd`` or ``/etc/group`` were updated, there will be an additional check to confirm if the users are in sync as described in `Syncuser`_ section. -Excluding Files from a Container --------------------------------- +Excluding Files from an Image +----------------------------- -Warewulf can exclude files from a source container to prevent them +Warewulf can exclude files from an image source to prevent them from being delivered to the compute node. This is typically used to reduce the size of the image when some files are unnecessary. Patterns for excluded files are read from the file -``/etc/warewulf/excludes`` in the container image itself. For example, +``/etc/warewulf/excludes`` in the image itself. For example, the default Rocky Linux images exclude these paths: .. code-block:: @@ -282,11 +281,11 @@ the default Rocky Linux images exclude these paths: ``/etc/warewulf/excludes`` supports the patterns implemented by `filepath.Match `_. -Preparing a container for build -------------------------------- +Preparing an image for build +---------------------------- -Warewulf executes the script ``/etc/warewulf/container_exit.sh`` after -a ``wwctl container shell`` or ``wwctl container exec`` and prior to +Warewulf executes the script ``/etc/warewulf/image_exit.sh`` after +a ``wwctl image shell`` or ``wwctl image exec`` and prior to (re)building the final node image for delivery. This is typically used to remove cache or log files that may have been generated by the executed command or interactive session. @@ -294,18 +293,18 @@ executed command or interactive session. For example, the default Rocky Linux images runs ``dnf clean all`` to remove any package repository caches that may have been generated. -Creating Containers From Scratch -================================ +Creating Images From Scratch +============================ -You can also create containers from scratch and import those -containers into Warewulf as previous versions of Warewulf did. +You can also create images from scratch and import those +images into Warewulf as previous versions of Warewulf did. -Building A Container From Your Host ------------------------------------ +Building An Image From Your Host +-------------------------------- RPM based distributions, as well as Debian variants can all bootstrap mini ``chroot()`` directories which can then be used to bootstrap your -node's container. +node's image. For example, on an RPM based Linux distribution with YUM or DNF, you can do something like the following: @@ -333,21 +332,21 @@ import it into Warewulf with the following command: .. code-block:: console - # wwctl container import /tmp/newroot containername + # wwctl image import /tmp/newroot imagename -Building A Container Using Apptainer ------------------------------------- +Building An Image Using Apptainer +--------------------------------- -Apptainer, a container platform for HPC and performance intensive -applications, can also be used to create node containers for -Warewulf. There are several Apptainer container recipes in the -``containers/Apptainer/`` directory and can be found on GitHub at -`https://github.com/warewulf/warewulf/tree/main/containers/Apptainer -`_. +Apptainer, an image platform for HPC and performance intensive +applications, can also be used to create node images for +Warewulf. There are several Apptainer image recipes in the +``images/Apptainer/`` directory and can be found on GitHub at +`https://github.com/warewulf/warewulf/tree/main/images/Apptainer +`_. You can use these as starting points and adding any additional steps you want in the ``%post`` section of the recipe file. Once you've done -that, installing Apptainer, building a container sandbox and importing +that, installing Apptainer, building an image sandbox and importing into Warewulf can be done with the following steps: .. code-block:: console @@ -355,26 +354,26 @@ into Warewulf can be done with the following steps: # yum install epel-release # yum install Apptainer # Apptainer build --sandbox /tmp/newroot /path/to/Apptainer/recipe.def - # wwctl container import /tmp/newroot containername + # wwctl image import /tmp/newroot imagename -Building A Container Using Podman ---------------------------------- +Building An Image Using Podman +------------------------------ -You can also build a container using podman via a ``Dockerfile``. For -this step the container must be exported to a tar archive, which then +You can also build an image using podman via a ``Dockerfile``. For +this step the image must be exported to a tar archive, which then can be imported to Warewulf. The following steps will create an -openSUSE Leap container and import it to Warewulf: +openSUSE Leap image and import it to Warewulf: .. code-block:: console - # podman build -f containers/Docker/openSUSE/Containerfile --tag leap-ww + # podman build -f images/Docker/openSUSE/Imagefile --tag leap-ww # podman save localhost/leap-ww:latest -o ~/leap-ww.tar - # wwctl container import file://root/leap-ww.tar leap-ww + # wwctl image import file://root/leap-ww.tar leap-ww -Container Size Considerations -============================= +Image Size Considerations +========================= -Base compute node container images start quite small (a few hundred +Base compute node images start quite small (a few hundred megabytes), but can grow quickly as packages and other files are added to them. Even these larger images are typically not an issue in modern environments; but some architectural limits exist that can impede the @@ -409,38 +408,38 @@ issues in most circumstances: device" errors, try disabling any "memory hole" features or updating your system BIOS or firmware. -Duplicating a container -======================= +Duplicating an image +==================== It is possible to duplicate an installed image by using: .. code-block:: console - # wwctl container copy CONTAINER_NAME DUPLICATED_CONTAINER_NAME + # wwctl image copy IMAGE_NAME DUPLICATED_IMAGE_NAME This kind of duplication can be useful if you are looking for canary tests. .. note:: - If a source container includes persistent sockets, these sockets may cause the copy operation to fail. + If an image source includes persistent sockets, these sockets may cause the copy operation to fail. .. code-block:: console Copying sources... ERROR : could not duplicate image: lchown /var/lib/warewulf/chroots/rocky-8/rootfs/run/user/0/gnupg/d.kg8ijih5tq41ixoeag4p1qup/S.gpg-agent: no such file or directory - To resolve this, remove the sockets from the source container. + To resolve this, remove the sockets from the image source. .. code-block:: bash - find $(wwctl container show rocky-8) -type s -delete + find $(wwctl image show rocky-8) -type s -delete -Multi-arch container management -=============================== +Multi-arch image management +=========================== -It is possible to build, edit, and provision containers of different +It is possible to build, edit, and provision images of different architectures (i.e. aarch64) from an x86_64 host by using QEMU. Simply -run the appropriate command below based on your container management tools. +run the appropriate command below based on your image management tools. .. code-block:: console @@ -448,10 +447,10 @@ run the appropriate command below based on your container management tools. # sudo podman run --rm --privileged multiarch/qemu-user-static --reset -p yes # sudo singularity run docker://multiarch/qemu-user-static --reset -p yes -Then, ``wwctl container exec`` will work regardless of the architecture of the container. +Then, ``wwctl image exec`` will work regardless of the architecture of the image. For more information about QEMU, see their `GitHub `_ -To use wwclient on a booted container using a different architecture, +To use wwclient on a booted image using a different architecture, wwclient must be compiled for the specific architecture. This requires GOLang build tools 1.21 or newer. Below is an example for building wwclient for arm64: @@ -465,13 +464,13 @@ tools 1.21 or newer. Below is an example for building wwclient for arm64: Then, apply the new "wwclient_arm64" system overlay to your arm64 node/profile -Read-only containers -==================== +Read-only images +================ -A container may be marked "read-only" by creating a ``readonly`` file in its +An image may be marked "read-only" by creating a ``readonly`` file in its source directory, typically next to ``rootfs``. .. note:: - Read-only containers are a preview feature primarily meant to enable future - support for container subscriptions and updates. + Read-only images are a preview feature primarily meant to enable future + support for image subscriptions and updates. diff --git a/userdocs/contents/introduction.rst b/userdocs/contents/introduction.rst index fa57791d..3aa62152 100644 --- a/userdocs/contents/introduction.rst +++ b/userdocs/contents/introduction.rst @@ -28,8 +28,7 @@ administration around virtual node images which are used to provision out to the cluster nodes. This means you can have hundreds or thousands of cluster nodes all booting and running on the same, identical virtual node file system image. As of Warewulf v4, the -virtual node image is a standard container image which means all -compute resources within a cluster can be managed using any existing +virtual node image can be managed using any existing container tooling and/or CI pipelines that are being used. This can be as simple as DockerHub or your own private GitLab CI infrastructure. @@ -67,8 +66,8 @@ Features CentOS, and RHEL, Warewulf can do it all. * **Secure**: Warewulf is the only stateless provisioning system that - will support SELinux out of the box. Just enable your node operating - system container to support SELinux, and Warewulf do the rest! + will support SELinux out of the box. Just enable your node image to + support SELinux, and let Warewulf do the rest! * **Open Source**: For the last 20 years, Warewulf has remained open source and continues to be the golden standard for cluster diff --git a/userdocs/contents/ipmi.rst b/userdocs/contents/ipmi.rst index 08a0fa5e..b62e9256 100644 --- a/userdocs/contents/ipmi.rst +++ b/userdocs/contents/ipmi.rst @@ -69,7 +69,7 @@ Profile View default Id -- default default comment -- This profile is automatically included for each node default cluster -- -- - default container -- sle-micro-5.3 + default image -- sle-micro-5.3 default ipxe -- -- default runtime -- -- default wwinit -- -- @@ -101,7 +101,7 @@ Node View n001 Id -- n001 n001 comment default This profile is automatically included for each node n001 cluster -- -- - n001 container default sle-micro-5.3 + n001 image default sle-micro-5.3 n001 ipxe -- (default) n001 runtime -- (hosts,ssh.authorized_keys,syncuser) n001 wwinit -- (wwinit,wwclient,fstab,hostname,ssh.host_keys,issue,resolv,udev.netname,systemd.netname,ifcfg,NetworkManager,debian.interfaces,wicked,ignition) diff --git a/userdocs/contents/kernel.rst b/userdocs/contents/kernel.rst index 6d5d91f8..86099ea6 100644 --- a/userdocs/contents/kernel.rst +++ b/userdocs/contents/kernel.rst @@ -3,18 +3,18 @@ Kernel Management ================= Warewulf nodes require a Linux kernel to boot. As of Warewulf v4.6, the kernel -you wish to use must be present in the relevant container. Warewulf locates and +you wish to use must be present in the relevant image. Warewulf locates and provisions the kernel automatically for any node configured to use that -container image. +image. -You can see what kernels are available in imported containers by using the -``wwctl container kernels`` command: +You can see what kernels are available in imported images by using the +``wwctl image kernels`` command: .. code-block:: console - # wwctl container kernels - Container Kernel Version Default Nodes - --------- ------ ------- ------- ----- + # wwctl image kernels + Image Kernel Version Default Nodes + ----- ------ ------- ------- ----- newroot-test /boot/vmlinuz-5.14.0-427.37.1.el9_4.aarch64 5.14.0-427.37.1 true 0 newroot-test /lib/modules/5.14.0-427.37.1.el9_4.aarch64/vmlinuz 5.14.0-427.37.1 false 0 rocky-8 /boot/vmlinuz-4.18.0-372.13.1.el8_6.x86_64 4.18.0-372.13.1 true 2 @@ -25,7 +25,7 @@ You can see what kernels are available in imported containers by using the Kernel Version ============== -If a container includes multiple kernels, the desired kernel may be selected by +If an image includes multiple kernels, the desired kernel may be selected by specifying the desired version or an explicit path. .. code-block:: console diff --git a/userdocs/contents/known-issues.rst b/userdocs/contents/known-issues.rst index 438a5665..b15687ab 100644 --- a/userdocs/contents/known-issues.rst +++ b/userdocs/contents/known-issues.rst @@ -17,21 +17,21 @@ To ensure that dracut runs the full ``wwinit`` process, pass ``init=/init`` or # wwctl profile set default --kernelargs="init=/init" -Containers are read-only -======================== +Images are read-only +==================== -Warewulf v4.5 uses the permissions on a container's ``rootfs/`` to determine a "read-only" state of -the container: if the root directory of the container image is ``u-w``, it will be mounted read-only -during ``wwctl container Controlling Warewulf (wwctl) Warewulf Initialization - Container Management + Image Management Kernel Management Boot Management Node Configuration diff --git a/userdocs/quickstart/debian12.rst b/userdocs/quickstart/debian12.rst index abb5c698..b6e621f1 100644 --- a/userdocs/quickstart/debian12.rst +++ b/userdocs/quickstart/debian12.rst @@ -126,16 +126,16 @@ instructions. to run ``$ sudo restorecon -Rv /var/lib/tftpboot/`` if there are errors with TFTP still. -Pull and build the VNFS container (including the kernel) -======================================================== +Pull and build the image (including the kernel) +=============================================== -This will pull a basic VNFS container from Docker Hub and import the +This will pull a basic image from Docker Hub and import the default running kernel from the controller node and set both in the "default" node profile. .. code-block:: bash - wwctl container import docker://ghcr.io/warewulf/warewulf-debian:12.0 debian-12.0 + wwctl image import docker://ghcr.io/warewulf/warewulf-debian:12.0 debian-12.0 Set up the default node profile @@ -145,12 +145,12 @@ Node configurations can be set via node profiles. Each node by default is configured to be part of the ``default`` node profile, so any changes you make to that profile will affect all nodes. -The following command will set the container we just imported above to +The following command will set the image we just imported above to the ``default`` node profile: .. code-block:: bash - sudo wwctl profile set --yes --container debian-12.0 "default" + sudo wwctl profile set --yes --image debian-12.0 "default" Next we set some default networking configurations for the first diff --git a/userdocs/quickstart/el.rst b/userdocs/quickstart/el.rst index 40718fe5..feb2f860 100644 --- a/userdocs/quickstart/el.rst +++ b/userdocs/quickstart/el.rst @@ -93,7 +93,7 @@ address of your cluster's private network interface. - path: /opt export options: ro,sync,no_root_squash systemd name: nfs-server - container mounts: + image mounts: - source: /etc/resolv.conf dest: /etc/resolv.conf readonly: true @@ -143,17 +143,17 @@ configure --all``. you may need to run ``restorecon -Rv /var/lib/tftpboot/`` to label files written to q`tftpboot``. -Add a base node image container -=============================== +Add a base node image +===================== -This will pull a basic node image container from Docker Hub and import the +This will pull a basic node image from Docker Hub and import the default running kernel from the controller node and set both in the "default" node profile. .. code-block:: bash - wwctl container import docker://ghcr.io/warewulf/warewulf-rockylinux:9 rockylinux-9 --build - wwctl profile set default --container rockylinux-9 + wwctl image import docker://ghcr.io/warewulf/warewulf-rockylinux:9 rockylinux-9 --build + wwctl profile set default --image rockylinux-9 Configure the default node profile ================================== diff --git a/userdocs/quickstart/suse15.rst b/userdocs/quickstart/suse15.rst index ac963010..23e3ddda 100644 --- a/userdocs/quickstart/suse15.rst +++ b/userdocs/quickstart/suse15.rst @@ -72,7 +72,7 @@ address of your cluster's private network interface: - path: /opt export options: ro,sync,no_root_squash systemd name: nfs-server - container mounts: + image mounts: - source: /etc/resolv.conf dest: /etc/resolv.conf readonly: true @@ -109,16 +109,16 @@ instructions. sudo wwctl configure --all -Pull and build the VNFS container and kernel -============================================ +Pull and build the image and kernel +=================================== -This will pull a basic VNFS container from Docker Hub and import the +This will pull a basic image from Docker Hub and import the default running kernel from the controller node and set both in the "default" node profile. .. code-block:: bash - $ sudo wwctl container import docker://registry.opensuse.org/science/warewulf/leap-15.4/containers/kernel:latest leap15.4 --setdefault + $ sudo wwctl image import docker://registry.opensuse.org/science/warewulf/leap-15.4/images/kernel:latest leap15.4 --setdefault Set up the default node profile =============================== diff --git a/warewulf.spec.in b/warewulf.spec.in index ad943158..631f398a 100644 --- a/warewulf.spec.in +++ b/warewulf.spec.in @@ -79,11 +79,11 @@ BuildRequires: libassuan-devel Recommends: logrotate %description -Warewulf is a stateless and diskless container operating system provisioning +Warewulf is a stateless and diskless provisioning system for large clusters of bare metal and/or virtual systems. %package dracut -Summary: dracut module for loading a Warewulf container image +Summary: dracut module for loading a Warewulf image BuildArch: noarch Requires: dracut @@ -96,11 +96,11 @@ Requires: cpio Requires: dmidecode %description dracut -Warewulf is a stateless and diskless container operating system provisioning +Warewulf is a stateless and diskless provisioning system for large clusters of bare metal and/or virtual systems. This subpackage contains a dracut module that can be used to generate -an initramfs that can fetch and boot a Warewulf container image from a +an initramfs that can fetch and boot a Warewulf node image from a Warewulf server. %prep