From 852ad6fb38f9bfc3fefe940478446e204c63806f Mon Sep 17 00:00:00 2001 From: Gregory Kurtzer Date: Sat, 23 Oct 2021 19:38:34 -0700 Subject: [PATCH 01/25] Fix error WRT deleting file in default overlay --- internal/app/wwctl/overlay/delete/main.go | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/internal/app/wwctl/overlay/delete/main.go b/internal/app/wwctl/overlay/delete/main.go index 7a3a17a5..69d20226 100644 --- a/internal/app/wwctl/overlay/delete/main.go +++ b/internal/app/wwctl/overlay/delete/main.go @@ -24,10 +24,6 @@ func CobraRunE(cmd *cobra.Command, args []string) error { fileName = args[2] } - if overlayName == "default" { - return errors.New("refusing to delete the default overlay") - } - if overlayKind != "system" && overlayKind != "runtime" { return errors.New("overlay kind must be of type 'system' or 'runtime'") } @@ -49,6 +45,9 @@ func CobraRunE(cmd *cobra.Command, args []string) error { } if fileName == "" { + if overlayName == "default" { + return errors.New("refusing to delete the default overlay") + } if Force { err := os.RemoveAll(overlayPath) if err != nil { From e62c4c78d94b89ae66ba57bc0d0dc7d03aed541a Mon Sep 17 00:00:00 2001 From: Gregory Kurtzer Date: Sat, 23 Oct 2021 19:56:19 -0700 Subject: [PATCH 02/25] Readme links update --- README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index c5f2b056..696d80c9 100644 --- a/README.md +++ b/README.md @@ -4,8 +4,10 @@ #### Quick Links: -* [Documentation](https://warewulf.hpcng.org) -* [GitHub](http://github.com/hpcng/warewulf) +* [Website](https://warewulf.org) +* [Documentation](https://warewulf.org/docs) +* [Download / Releases](http://github.com/hpcng/warewulf/releases) +* [Support](http://www.ciq.co/warewulf) ## About Warewulf From 17c71993d372c0a5a8acb8565e6d4806f035148f Mon Sep 17 00:00:00 2001 From: "Michael L. Young" Date: Tue, 26 Oct 2021 22:25:50 -0400 Subject: [PATCH 03/25] Add GitHub action to build new release assets and upload them --- .github/workflows/releasebuild.yml | 88 ++++++++++++++++++++++++++++++ Makefile | 9 ++- ci/mockbuild.sh | 17 ++++++ warewulf.spec.in | 2 +- 4 files changed, 113 insertions(+), 3 deletions(-) create mode 100644 .github/workflows/releasebuild.yml create mode 100644 ci/mockbuild.sh diff --git a/.github/workflows/releasebuild.yml b/.github/workflows/releasebuild.yml new file mode 100644 index 00000000..92d41c77 --- /dev/null +++ b/.github/workflows/releasebuild.yml @@ -0,0 +1,88 @@ +--- +name: releasebuild + +on: + release: + types: + - published + +jobs: + + distbuild: + name: Checkout code and build tar.gz + runs-on: ubuntu-latest + steps: + - name: Set the version + id: version_number + run: | + echo "VERSION=${GITHUB_REF#refs/tags/v}" >> $GITHUB_ENV + - name: Set the git source location + id: source_loc + run: | + echo "SRC=${GITHUB_REF}" >> $GITHUB_ENV + - name: Checkout Code + uses: actions/checkout@v2 + - name: Install Go + uses: actions/setup-go@v2 + - uses: actions/cache@v2 + with: + path: ~/go/pkg/mod + key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} + restore-keys: | + ${{ runner.os }}-go- + - name: Build tar.gz + run: make dist + - name: Upload mock script + uses: actions/upload-artifact@v2 + with: + name: mockbuild.sh + path: ci/mockbuild.sh + - name: Upload tar.gz + uses: actions/upload-artifact@v2 + with: + name: warewulf-${{ env.VERSION }}.tar.gz + path: warewulf-${{ env.VERSION }}.tar.gz + + rpmbuild: + name: Build using Rocky Linux + needs: distbuild + runs-on: ubuntu-latest + container: + image: rockylinux/rockylinux + options: --privileged + steps: + - name: Set the version + id: version_number + run: | + echo "VERSION=${GITHUB_REF#refs/tags/v}" >> $GITHUB_ENV + - name: Download mock build script + uses: actions/download-artifact@v2 + with: + name: mockbuild.sh + - name: Download tar.gz + uses: actions/download-artifact@v2 + with: + name: warewulf-${{ env.VERSION }}.tar.gz + - name: Set execute bit + run: chmod +x mockbuild.sh + - name: Run rpm build script + run: ./mockbuild.sh ${{ env.VERSION }} + - name: Upload EL8 RPM + uses: actions/upload-artifact@v2 + with: + name: warewulf-${{ env.VERSION }}-${{ env.RELEASE }}.el8.x86_64.rpm + path: warewulf-${{ env.VERSION }}-${{ env.RELEASE }}.el8.x86_64.rpm + - name: Upload EL7 RPM + uses: actions/upload-artifact@v2 + with: + name: warewulf-${{ env.VERSION }}-${{ env.RELEASE }}.el7.x86_64.rpm + path: warewulf-${{ env.VERSION }}-${{ env.RELEASE }}.el7.x86_64.rpm + - name: Upload Assets To Release + uses: xresloader/upload-to-github-release@master + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + file: 'warewulf-${{ env.VERSION }}.tar.gz;warewulf-${{ env.VERSION }}-${{ env.RELEASE }}.*.rpm' + draft: false + update_latest_release: true + tags: true diff --git a/Makefile b/Makefile index 0babd543..5154f204 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,11 @@ .PHONY: all VERSION := 4.2.0 +RELEASE := 1 + +ifndef SRC + SRC := main +endif # auto installed tooling TOOLS_DIR := .tools @@ -103,9 +108,9 @@ man_page: dist: vendor rm -rf _dist/warewulf-$(VERSION) mkdir -p _dist/warewulf-$(VERSION) - git archive --format=tar main | tar -xf - -C _dist/warewulf-$(VERSION) + git archive --format=tar $(SRC) | tar -xf - -C _dist/warewulf-$(VERSION) cp -r vendor _dist/warewulf-$(VERSION)/ - sed -e 's/@VERSION@/$(VERSION)/g' warewulf.spec.in > _dist/warewulf-$(VERSION)/warewulf.spec + sed -e 's/@VERSION@/$(VERSION)/g; s/@RELEASE@/$(RELEASE)/g' warewulf.spec.in > _dist/warewulf-$(VERSION)/warewulf.spec cd _dist; tar -czf ../warewulf-$(VERSION).tar.gz warewulf-$(VERSION) clean: diff --git a/ci/mockbuild.sh b/ci/mockbuild.sh new file mode 100644 index 00000000..1547310a --- /dev/null +++ b/ci/mockbuild.sh @@ -0,0 +1,17 @@ +#!/usr/bin/bash + +VERSION=$1 + +dnf install -y epel-release +dnf install -y mock + +tar -xf warewulf-${VERSION}.tar.gz warewulf-${VERSION}/warewulf.spec + +RELEASE=$(grep 'Release: ' warewulf-${VERSION}/warewulf.spec | cut -d ':' -f2 | awk -F'%' '{print $1}' | tr -d ' ') +echo RELEASE=${RELEASE} >> $GITHUB_ENV + +mock -r epel-8-x86_64 --rebuild --spec=warewulf-${VERSION}/warewulf.spec --sources=. +mv /var/lib/mock/epel-8-x86_64/result/warewulf-${VERSION}-${RELEASE}.el8.x86_64.rpm . + +mock -r epel-7-x86_64 --rebuild --spec=warewulf-${VERSION}/warewulf.spec --sources=. +mv /var/lib/mock/epel-7-x86_64/result/warewulf-${VERSION}-${RELEASE}.el7.x86_64.rpm . \ No newline at end of file diff --git a/warewulf.spec.in b/warewulf.spec.in index 7e771cc1..c9464eae 100644 --- a/warewulf.spec.in +++ b/warewulf.spec.in @@ -3,7 +3,7 @@ Name: warewulf Summary: A suite of tools for bare metal provisioning of containers Version: @VERSION@ -Release: 1%{?dist} +Release: @RELEASE@%{?dist} License: BSD Source: https://github.com/hpcng/warewulf/archive/refs/tags/%{name}-%{version}.tar.gz ExclusiveOS: linux From de2c882ba1ee729138b32364c4b20ad645012824 Mon Sep 17 00:00:00 2001 From: jcsiadal Date: Thu, 28 Oct 2021 17:48:16 -0700 Subject: [PATCH 04/25] Replace HTML in help Signed-off-by: jcsiadal --- internal/app/wwctl/overlay/build/root.go | 2 +- internal/app/wwctl/overlay/chmod/root.go | 2 +- internal/app/wwctl/overlay/chown/root.go | 2 +- internal/app/wwctl/overlay/create/root.go | 2 +- internal/app/wwctl/overlay/delete/root.go | 2 +- internal/app/wwctl/overlay/edit/root.go | 2 +- internal/app/wwctl/overlay/imprt/root.go | 2 +- internal/app/wwctl/overlay/list/root.go | 2 +- internal/app/wwctl/overlay/mkdir/root.go | 2 +- internal/app/wwctl/overlay/show/root.go | 2 +- internal/app/wwctl/power/cycle/root.go | 2 +- internal/app/wwctl/profile/add/root.go | 2 +- internal/app/wwctl/profile/delete/root.go | 2 +- internal/app/wwctl/profile/set/root.go | 2 +- 14 files changed, 14 insertions(+), 14 deletions(-) diff --git a/internal/app/wwctl/overlay/build/root.go b/internal/app/wwctl/overlay/build/root.go index a6901f87..197c9f5e 100644 --- a/internal/app/wwctl/overlay/build/root.go +++ b/internal/app/wwctl/overlay/build/root.go @@ -4,7 +4,7 @@ import "github.com/spf13/cobra" var ( baseCmd = &cobra.Command{ - Use: "build [flags] ", + Use: "build [flags] (overlay kind) (overlay name)", Short: "(Re)build an overlay", Long: "This command will build a system or runtime overlay.", RunE: CobraRunE, diff --git a/internal/app/wwctl/overlay/chmod/root.go b/internal/app/wwctl/overlay/chmod/root.go index b9a254d6..d9755157 100644 --- a/internal/app/wwctl/overlay/chmod/root.go +++ b/internal/app/wwctl/overlay/chmod/root.go @@ -4,7 +4,7 @@ import "github.com/spf13/cobra" var ( baseCmd = &cobra.Command{ - Use: "chmod [flags] ", + Use: "chmod [flags] (overlay kind) (overlay name) (path) (mode)", Short: "Change file permissions within an overlay", Long: "This command will allow you to change the permissions of a file within an\n" + "overlay.", diff --git a/internal/app/wwctl/overlay/chown/root.go b/internal/app/wwctl/overlay/chown/root.go index 941328f0..970434dd 100644 --- a/internal/app/wwctl/overlay/chown/root.go +++ b/internal/app/wwctl/overlay/chown/root.go @@ -4,7 +4,7 @@ import "github.com/spf13/cobra" var ( baseCmd = &cobra.Command{ - Use: "chown [flags] []", + Use: "chown [flags] (overlay kind) (overlay name) (path) (UID) [(GID)]", Short: "Change file ownership within an overlay", Long: "This command will allow you to change the ownership of a file within an\n" + "overlay.", diff --git a/internal/app/wwctl/overlay/create/root.go b/internal/app/wwctl/overlay/create/root.go index 15242009..9b671b3b 100644 --- a/internal/app/wwctl/overlay/create/root.go +++ b/internal/app/wwctl/overlay/create/root.go @@ -6,7 +6,7 @@ import ( var ( baseCmd = &cobra.Command{ - Use: "create [flags] ", + Use: "create [flags] (overlay kind) (overlay name)", Short: "Initialize a new Overlay", Long: "This command will create a new empty overlay.", RunE: CobraRunE, diff --git a/internal/app/wwctl/overlay/delete/root.go b/internal/app/wwctl/overlay/delete/root.go index bfe9299c..da636e8d 100644 --- a/internal/app/wwctl/overlay/delete/root.go +++ b/internal/app/wwctl/overlay/delete/root.go @@ -6,7 +6,7 @@ import ( var ( baseCmd = &cobra.Command{ - Use: "delete [flags] [overlay file]", + Use: "delete [flags] (overlay kind) (overlay name) [overlay file]", Short: "Delete Warewulf Overlay or files", Long: "This command will delete files within an overlay or an entire overlay if no\n" + "files are given to remove (use with caution).", diff --git a/internal/app/wwctl/overlay/edit/root.go b/internal/app/wwctl/overlay/edit/root.go index 3ec6add2..e1b5c2cf 100644 --- a/internal/app/wwctl/overlay/edit/root.go +++ b/internal/app/wwctl/overlay/edit/root.go @@ -6,7 +6,7 @@ import ( var ( baseCmd = &cobra.Command{ - Use: "edit [flags] ", + Use: "edit [flags] (overlay kind) (overlay name) (file path)", Short: "Edit/Create a file within a Warewulf Overlay", Long: "This command will allow you to edit or create a new file within a given\n" + "overlay. Note: when creating files ending in a '.ww' suffix this will always be\n" + diff --git a/internal/app/wwctl/overlay/imprt/root.go b/internal/app/wwctl/overlay/imprt/root.go index 983052b8..c0fcbad9 100644 --- a/internal/app/wwctl/overlay/imprt/root.go +++ b/internal/app/wwctl/overlay/imprt/root.go @@ -4,7 +4,7 @@ import "github.com/spf13/cobra" var ( baseCmd = &cobra.Command{ - Use: "import [flags] [overlay target]", + Use: "import [flags] (overlay kind) (overlay name) (host source) [overlay target]", Short: "Import a file into a Warewulf Overlay", Long: "This command will import a file into a given Warewulf overlay.", RunE: CobraRunE, diff --git a/internal/app/wwctl/overlay/list/root.go b/internal/app/wwctl/overlay/list/root.go index 9643845b..ea2310e9 100644 --- a/internal/app/wwctl/overlay/list/root.go +++ b/internal/app/wwctl/overlay/list/root.go @@ -6,7 +6,7 @@ import ( var ( baseCmd = &cobra.Command{ - Use: "list [flags] [overlay name]", + Use: "list [flags] (overlay kind) [overlay name]", Short: "List Warewulf Overlays and files", Long: "This command will show you information about Warewulf overlays and the\n" + "files contained within.", diff --git a/internal/app/wwctl/overlay/mkdir/root.go b/internal/app/wwctl/overlay/mkdir/root.go index 8a557079..148d0514 100644 --- a/internal/app/wwctl/overlay/mkdir/root.go +++ b/internal/app/wwctl/overlay/mkdir/root.go @@ -6,7 +6,7 @@ import ( var ( baseCmd = &cobra.Command{ - Use: "mkdir [flags] ", + Use: "mkdir [flags] (overlay kind) (overlay name) (directory path)", Short: "Create a new directory within an Overlay", Long: "This command will allow you to create a new file within a given Warewulf overlay.", RunE: CobraRunE, diff --git a/internal/app/wwctl/overlay/show/root.go b/internal/app/wwctl/overlay/show/root.go index a8c51efc..fe58f714 100644 --- a/internal/app/wwctl/overlay/show/root.go +++ b/internal/app/wwctl/overlay/show/root.go @@ -6,7 +6,7 @@ import ( var ( baseCmd = &cobra.Command{ - Use: "show [flags] ", + Use: "show [flags] (overlay kind) (overlay name) (overlay file)", Short: "Show (cat) a file within a Warewulf Overlay", Long: "This command will output the contents of a file within a given\n" + "Warewulf overlay.", diff --git a/internal/app/wwctl/power/cycle/root.go b/internal/app/wwctl/power/cycle/root.go index e89899fc..fcd9093d 100644 --- a/internal/app/wwctl/power/cycle/root.go +++ b/internal/app/wwctl/power/cycle/root.go @@ -6,7 +6,7 @@ import ( var ( powerCmd = &cobra.Command{ - Use: "cycle [flags] ...", + Use: "cycle [flags] (node pattern)...", Short: "Power cycle the given node(s)", Long: "This command will cycle the power for a given set of nodes.", RunE: CobraRunE, diff --git a/internal/app/wwctl/profile/add/root.go b/internal/app/wwctl/profile/add/root.go index 85d1ac42..f560128c 100644 --- a/internal/app/wwctl/profile/add/root.go +++ b/internal/app/wwctl/profile/add/root.go @@ -4,7 +4,7 @@ import "github.com/spf13/cobra" var ( baseCmd = &cobra.Command{ - Use: "add ", + Use: "add (profile name)", Short: "Add a new node profile", Long: "This command will add a new node profile.", RunE: CobraRunE, diff --git a/internal/app/wwctl/profile/delete/root.go b/internal/app/wwctl/profile/delete/root.go index 44f3afe0..aaf92662 100644 --- a/internal/app/wwctl/profile/delete/root.go +++ b/internal/app/wwctl/profile/delete/root.go @@ -4,7 +4,7 @@ import "github.com/spf13/cobra" var ( baseCmd = &cobra.Command{ - Use: "delete [flags] ", + Use: "delete [flags] (profile pattern)", Short: "Delete a node profile", Long: "This command will delete a node profile.", RunE: CobraRunE, diff --git a/internal/app/wwctl/profile/set/root.go b/internal/app/wwctl/profile/set/root.go index cb0b765a..6e533b5f 100644 --- a/internal/app/wwctl/profile/set/root.go +++ b/internal/app/wwctl/profile/set/root.go @@ -12,7 +12,7 @@ import ( var ( baseCmd = &cobra.Command{ - Use: "set [flags] ...", + Use: "set [flags] (profile pattern)...", Short: "Configure node profile properties", Long: "This command will allow you to set configuration properties for node profiles.\n\n" + "Note: use the string 'UNSET' to remove a configuration", From f7396ae5bebc75eb8566ca7e87112030160a238f Mon Sep 17 00:00:00 2001 From: jcsiadal Date: Mon, 1 Nov 2021 11:32:59 -0700 Subject: [PATCH 05/25] Updates to build an RPM Signed-off-by: jcsiadal --- Makefile | 23 ++++++--- etc/nodes.conf | 4 ++ internal/pkg/node/datastructure.go | 23 ++------- warewulf.spec.in | 83 +++++++++++++++++++++--------- 4 files changed, 81 insertions(+), 52 deletions(-) create mode 100644 etc/nodes.conf diff --git a/Makefile b/Makefile index 0babd543..053a7d94 100644 --- a/Makefile +++ b/Makefile @@ -61,6 +61,7 @@ files: all install -d -m 0755 $(DESTDIR)/usr/share/man/man1 test -f $(DESTDIR)/etc/warewulf/warewulf.conf || install -m 644 etc/warewulf.conf $(DESTDIR)/etc/warewulf/ test -f $(DESTDIR)/etc/warewulf/hosts.tmpl || install -m 644 etc/hosts.tmpl $(DESTDIR)/etc/warewulf/ + test -f $(DESTDIR)/etc/warewulf/nodes.conf || install -m 640 etc/nodes.conf $(DESTDIR)/etc/warewulf/ cp -r etc/dhcp $(DESTDIR)/etc/warewulf/ cp -r etc/ipxe $(DESTDIR)/etc/warewulf/ cp -r overlays $(DESTDIR)/var/warewulf/ @@ -74,12 +75,13 @@ files: all install -c -m 0644 include/firewalld/warewulf.xml $(DESTDIR)/usr/lib/firewalld/services mkdir -p $(DESTDIR)/usr/lib/systemd/system install -c -m 0644 include/systemd/warewulfd.service $(DESTDIR)/usr/lib/systemd/system - ./bash_completion $(DESTDIR)/etc/bash_completion.d/warewulf - ./man_page $(DESTDIR)/usr/share/man/man1 - gzip --force $(DESTDIR)/usr/share/man/man1/wwctl*1 -# systemctl daemon-reload -# cp -r tftpboot/* /var/lib/tftpboot/warewulf/ipxe/ -# restorecon -r /var/lib/tftpboot/warewulf + cp etc/bash_completion.d/warewulf $(DESTDIR)/etc/bash_completion.d/ + cp usr/share/man/man1/* $(DESTDIR)/usr/share/man/man1/ + +init: + systemctl daemon-reload + cp -r tftpboot/* /var/lib/tftpboot/warewulf/ipxe/ + restorecon -r /var/lib/tftpboot/warewulf debfiles: debian chmod +x $(DESTDIR)/var/warewulf/overlays/system/debian/init @@ -95,10 +97,15 @@ wwclient: cd cmd/wwclient; CGO_ENABLED=0 GOOS=linux go build -mod vendor -a -ldflags '-extldflags -static' -o ../../wwclient bash_completion: - cd cmd/bash_completion; go build -mod vendor -tags "$(WW_BUILD_GO_BUILD_TAGS)" -o ../../bash_completion + cd cmd/bash_completion && go build -mod vendor -tags "$(WW_BUILD_GO_BUILD_TAGS)" -o ../../bash_completion + install -d -m 0755 ./etc/bash_completion.d/ + ./bash_completion ./etc/bash_completion.d/warewulf man_page: - cd cmd/man_page; go build -mod vendor -tags "$(WW_BUILD_GO_BUILD_TAGS)" -o ../../man_page + cd cmd/man_page && go build -mod vendor -tags "$(WW_BUILD_GO_BUILD_TAGS)" -o ../../man_page + install -d -m 0755 ./usr/share/man/man1 + ./man_page ./usr/share/man/man1 + gzip --force ./usr/share/man/man1/wwctl*1 dist: vendor rm -rf _dist/warewulf-$(VERSION) diff --git a/etc/nodes.conf b/etc/nodes.conf new file mode 100644 index 00000000..3999a8cd --- /dev/null +++ b/etc/nodes.conf @@ -0,0 +1,4 @@ +nodeprofiles: + default: + comment: This profile is automatically included for each node +nodes: {} diff --git a/internal/pkg/node/datastructure.go b/internal/pkg/node/datastructure.go index a7f55ae6..17be4d41 100644 --- a/internal/pkg/node/datastructure.go +++ b/internal/pkg/node/datastructure.go @@ -1,9 +1,6 @@ package node import ( - "fmt" - "os" - "github.com/hpcng/warewulf/internal/pkg/util" "github.com/hpcng/warewulf/internal/pkg/wwlog" ) @@ -104,22 +101,10 @@ type NetDevEntry struct { } func init() { - //TODO: Check to make sure nodes.conf is found + // Check that nodes.conf is found if !util.IsFile(ConfigFile) { - c, err := os.OpenFile(ConfigFile, os.O_RDWR|os.O_CREATE, 0640) - if err != nil { - wwlog.Printf(wwlog.ERROR, "Could not create new configuration file: %s\n", err) - // just return silently, as init is also called for bash_completion - return - } - - fmt.Fprintf(c, "nodeprofiles:\n") - fmt.Fprintf(c, " default:\n") - fmt.Fprintf(c, " comment: This profile is automatically included for each node\n") - fmt.Fprintf(c, "nodes: {}\n") - - c.Close() - - wwlog.Printf(wwlog.INFO, "Created default node configuration\n") + wwlog.Printf(wwlog.WARN, "Missing node configuration file\n") + // just return silently, as init is also called for bash_completion + return } } diff --git a/warewulf.spec.in b/warewulf.spec.in index 7e771cc1..eca239a7 100644 --- a/warewulf.spec.in +++ b/warewulf.spec.in @@ -1,74 +1,107 @@ +%global wwgroup warewulf +%{!?wwshared: %global wwshared %{_localstatedir}} %define debug_package %{nil} Name: warewulf -Summary: A suite of tools for bare metal provisioning of containers +Summary: A provisioning system for large clusters of bare metal and/or virtual systems Version: @VERSION@ -Release: 1%{?dist} -License: BSD -Source: https://github.com/hpcng/warewulf/archive/refs/tags/%{name}-%{version}.tar.gz +Release: 1 +License: BSD-3-Clause +URL: https://github.com/hpcng/warewulf +Source: https://github.com/hpcng/warewulf/archive/refs/tags/v%{version}.tar.gz + ExclusiveOS: linux +Conflicts: warewulf < 4 +Conflicts: warewulf-common +Conflicts: warewulf-cluster +Conflicts: warewulf-vnfs +Conflicts: warewulf-provision +Conflicts: warewulf-ipmi + BuildRequires: make -BuildRequires: golang %if 0%{?rhel} BuildRequires: systemd +BuildRequires: golang +Requires: tftp-server +Requires: nfs-utils %else +# sle_version BuildRequires: systemd-rpm-macros +BuildRequires: go +Requires: tftp +Requires: nfs-kernel-server %endif -%if 0%{?rhel} > 7 +%if 0%{?rhel} >= 8 || 0%{?sle_version} Requires: dhcp-server %else +# rhel < 8 Requires: dhcp %endif -Requires: tftp-server -Requires: nfs-utils - %description -Warewulf is a bare metal container provisioning system. +Warewulf is a stateless and diskless container operating system provisioning +system for large clusters of bare metal and/or virtual systems. + %prep -%setup -q +%setup -q -n %{name}-%{version} + %build make all + %install %make_install DESTDIR=%{buildroot} %{?mflags_install} + %pre -getent group warewulf >/dev/null || groupadd -r warewulf +getent group %{wwgroup} >/dev/null || groupadd -r %{wwgroup} + %post %systemd_post warewulfd.service + %preun %systemd_preun warewulfd.service + %postun %systemd_postun_with_restart warewulfd.service -%files -%attr(0755, root, warewulf) %dir %{_sysconfdir}/%{name} -%config(noreplace) %{_sysconfdir}/%{name}/* +%files +%defattr(-, root, %{wwgroup}) +%dir %{_sysconfdir}/%{name} +%config(noreplace) %{_sysconfdir}/%{name}/* +%config(noreplace) %attr(0640,-,-) %{_sysconfdir}/%{name}/nodes.conf %{_sysconfdir}/bash_completion.d/warewulf -%{_bindir}/wwctl +%dir %{wwshared}/%{name} +%{wwshared}/%{name}/overlays/runtime/* +%{wwshared}/%{name}/overlays/system/* -%{_prefix}/lib/firewalld/services/warewulf.xml - -%{_unitdir}/warewulfd.service - -%attr(0755, root, warewulf) %dir %{_localstatedir}/%{name} -%{_localstatedir}/%{name}/overlays/runtime/* -%{_localstatedir}/%{name}/overlays/system/* - -%{_mandir}/man1/wwctl* +%attr(-, root, root) %{_bindir}/wwctl +%if 0%{?rhel} +%attr(-, root, root) %{_prefix}/lib/firewalld/services/warewulf.xml +%else +# sle_version +%attr(-, root, root) %{_libexecdir}/firewalld/services/warewulf.xml +%endif +%attr(-, root, root) %{_unitdir}/warewulfd.service +%attr(-, root, root) %{_mandir}/man1/wwctl* %changelog +* Mon Nov 1 2021 Jeremy Siadal - 4.2.0-1 +- Add support for OpenSUSE +- Update file attribs +- Update license string +- Make shared store relocatable + * Fri Sep 24 2021 Michael L. Young - 4.2.0-1 - Update spec file to use systemd macros - Use macros to refer to system paths From 9b2f47ed9587704ca30afc4b7975a743b1899cc5 Mon Sep 17 00:00:00 2001 From: jcsiadal Date: Tue, 2 Nov 2021 08:36:20 -0700 Subject: [PATCH 06/25] Add dist macro back Signed-off-by: jcsiadal --- warewulf.spec.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/warewulf.spec.in b/warewulf.spec.in index eca239a7..0a9e877b 100644 --- a/warewulf.spec.in +++ b/warewulf.spec.in @@ -5,7 +5,7 @@ Name: warewulf Summary: A provisioning system for large clusters of bare metal and/or virtual systems Version: @VERSION@ -Release: 1 +Release: 1%{?dist} License: BSD-3-Clause URL: https://github.com/hpcng/warewulf Source: https://github.com/hpcng/warewulf/archive/refs/tags/v%{version}.tar.gz From 02500ad56d218e4aca57c743f77b73ce43c08e8e Mon Sep 17 00:00:00 2001 From: Niko Kivel Date: Wed, 3 Nov 2021 11:51:35 +0100 Subject: [PATCH 07/25] moved node utils to util.go added tests for FindByHwaddr and FindByIpaddr --- Makefile | 18 ++++ internal/pkg/node/constructors.go | 40 +-------- internal/pkg/node/util.go | 47 +++++++++++ internal/pkg/node/util_test.go | 135 ++++++++++++++++++++++++++++++ 4 files changed, 203 insertions(+), 37 deletions(-) create mode 100644 internal/pkg/node/util.go create mode 100644 internal/pkg/node/util_test.go diff --git a/Makefile b/Makefile index 0babd543..a1734120 100644 --- a/Makefile +++ b/Makefile @@ -21,6 +21,8 @@ WW_BUILD_GO_BUILD_TAGS := containers_image_openpgp containers_image_ostree all: vendor wwctl wwclient bash_completion man_page +build: lint test-it vet all + # set the go tools into the tools bin. setup_tools: $(GO_TOOLS_BIN) $(GOLANGCI_LINT) @@ -48,6 +50,22 @@ lint: setup_tools @echo Running golangci-lint... @$(GOLANGCI_LINT) run --build-tags "$(WW_BUILD_GO_BUILD_TAGS)" --skip-dirs internal/pkg/staticfiles ./... +vet: + go vet ./... + +test-it: + go test -v ./... + +# Generate test coverage +test-cover: ## Run test coverage and generate html report + rm -fr coverage + mkdir coverage + go list -f '{{if gt (len .TestGoFiles) 0}}"go test -covermode count -coverprofile {{.Name}}.coverprofile -coverpkg ./... {{.ImportPath}}"{{end}}' ./... | xargs -I {} bash -c {} + echo "mode: count" > coverage/cover.out + grep -h -v "^mode:" *.coverprofile >> "coverage/cover.out" + rm *.coverprofile + go tool cover -html=coverage/cover.out -o=coverage/cover.html + debian: all files: all diff --git a/internal/pkg/node/constructors.go b/internal/pkg/node/constructors.go index 596a6b43..27007dec 100644 --- a/internal/pkg/node/constructors.go +++ b/internal/pkg/node/constructors.go @@ -1,15 +1,13 @@ package node import ( + "errors" "fmt" + "github.com/hpcng/warewulf/internal/pkg/wwlog" + "gopkg.in/yaml.v2" "io/ioutil" "sort" "strings" - - "github.com/pkg/errors" - "gopkg.in/yaml.v2" - - "github.com/hpcng/warewulf/internal/pkg/wwlog" ) const ConfigFile = "/etc/warewulf/nodes.conf" @@ -266,35 +264,3 @@ func (config *nodeYaml) FindDiscoverableNode() (NodeInfo, string, error) { return ret, "", errors.New("No unconfigured nodes found") } - -func (config *nodeYaml) FindByHwaddr(hwa string) (NodeInfo, error) { - var ret NodeInfo - - n, _ := config.FindAllNodes() - - for _, node := range n { - for _, dev := range node.NetDevs { - if dev.Hwaddr.Get() == hwa { - return node, nil - } - } - } - - return ret, errors.New("No nodes found with HW Addr: " + hwa) -} - -func (config *nodeYaml) FindByIpaddr(ipaddr string) (NodeInfo, error) { - var ret NodeInfo - - n, _ := config.FindAllNodes() - - for _, node := range n { - for _, dev := range node.NetDevs { - if dev.Ipaddr.Get() == ipaddr { - return node, nil - } - } - } - - return ret, errors.New("No nodes found with IP Addr: " + ipaddr) -} diff --git a/internal/pkg/node/util.go b/internal/pkg/node/util.go new file mode 100644 index 00000000..4b8bb9b3 --- /dev/null +++ b/internal/pkg/node/util.go @@ -0,0 +1,47 @@ +package node + +import ( + "errors" + "net" + "strings" +) + +func (config *nodeYaml) FindByHwaddr(hwa string) (NodeInfo, error) { + if _, err := net.ParseMAC(hwa); err != nil { + return NodeInfo{}, errors.New("invalid hardware address: " + hwa) + } + + var ret NodeInfo + + n, _ := config.FindAllNodes() + + for _, node := range n { + for _, dev := range node.NetDevs { + if strings.EqualFold(dev.Hwaddr.Get(), hwa) { + return node, nil + } + } + } + + return ret, errors.New("No nodes found with HW Addr: " + hwa) +} + +func (config *nodeYaml) FindByIpaddr(ipaddr string) (NodeInfo, error) { + if net.ParseIP(ipaddr) == nil { + return NodeInfo{}, errors.New("invalid IP:" + ipaddr) + } + + var ret NodeInfo + + n, _ := config.FindAllNodes() + + for _, node := range n { + for _, dev := range node.NetDevs { + if dev.Ipaddr.Get() == ipaddr { + return node, nil + } + } + } + + return ret, errors.New("No nodes found with IP Addr: " + ipaddr) +} diff --git a/internal/pkg/node/util_test.go b/internal/pkg/node/util_test.go new file mode 100644 index 00000000..78f4127c --- /dev/null +++ b/internal/pkg/node/util_test.go @@ -0,0 +1,135 @@ +package node + +import ( + "gopkg.in/yaml.v2" + "testing" +) + +func NewTestNode() (nodeYaml, error) { + var data = ` +nodeprofiles: + default: + comment: This profile is automatically included for each node +nodes: + test_node: + profiles: + - default + network devices: + eth0: + default: true + hwaddr: 00:00:00:00:12:34 + ipaddr: 1.2.3.4 + ipcidr: "" + prefix: "" + netmask: "" + eno1: + default: true + hwaddr: ab:cd:ef:00:12:34 + ipaddr: 1.2.3.4 + ipcidr: "" + prefix: "" + netmask: "" + eno2: + default: true + hwaddr: aB:Cd:eF:12:34:56 + ipaddr: 1.2.3.4 + ipcidr: "" + prefix: "" + netmask: "" + test_node_IPv6: + profiles: + - default + network devices: + eth1: + default: false + hwaddr: "" + ipaddr: fd1a:2b3c:4d5e:06f0:1234:5678:90ab:cdef + ipcidr: "" + prefix: "" + netmask: "" +` + var ret nodeYaml + err := yaml.Unmarshal([]byte(data), &ret) + if err != nil { + return ret, err + } + return ret, nil +} + +func Test_nodeYaml_FindByHwaddr(t *testing.T) { + c, _ := NewTestNode() + //type fields struct { + // NodeProfiles map[string]*NodeConf + // Nodes map[string]*NodeConf + //} + type args struct { + hwa string + } + tests := []struct { + name string + //fields fields + config nodeYaml + args args + want string + wantErr bool + }{ + {"emptyString", c, args{hwa: ""}, "", true}, + {"noIpString", c, args{hwa: "this is not a MAC"}, "", true}, + {"intString", c, args{hwa: "4294967296"}, "", true}, + {"invalidMAC", c, args{hwa: "xx:00:00:00:12:34"}, "", true}, + {"validMACNotFound", c, args{hwa: "aa:FF:ee:65:43:21"}, "", true}, + {"validMAC", c, args{hwa: "ab:cd:ef:00:12:34"}, "test_node", false}, + {"validMAC2", c, args{hwa: "aB:Cd:eF:00:12:34"}, "test_node", false}, + {"validMAC3", c, args{hwa: "Ab:cD:Ef:12:34:56"}, "test_node", false}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + config := tt.config + got, err := config.FindByHwaddr(tt.args.hwa) + if (err != nil) != tt.wantErr { + t.Errorf("FindByHwaddr() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !(got.Id.Get() == tt.want) { + t.Errorf("FindByHwaddr() got = %v, want %v", got, tt.want) + } + }) + } +} + +func Test_nodeYaml_FindByIpaddr(t *testing.T) { + c, _ := NewTestNode() + type args struct { + ipaddr string + } + tests := []struct { + name string + config nodeYaml + args args + want string + wantErr bool + }{ + {"emptyString", c, args{ipaddr: ""}, "", true}, + {"noIpString", c, args{ipaddr: "this is not an IP"}, "", true}, + {"intString", c, args{ipaddr: "4294967296"}, "", true}, + {"invalidIPv4", c, args{ipaddr: "1.2.3.256"}, "", true}, + {"invalidIPv6", c, args{ipaddr: "xd1a:2b3c:4d5e:06f0:1234:5678:90ab:cdef"}, "", true}, + {"validIPv4NotFound", c, args{ipaddr: "1.1.1.1"}, "", true}, + {"validIPv6NotFound", c, args{ipaddr: "fd1a:2b3c:4d5e:06f0:1234:5678:90ab:fedc"}, "", true}, + {"validIPv4", c, args{ipaddr: "1.2.3.4"}, "test_node", false}, + {"validIPv6", c, args{ipaddr: "fd1a:2b3c:4d5e:06f0:1234:5678:90ab:cdef"}, "test_node_IPv6", false}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + config := tt.config + got, err := config.FindByIpaddr(tt.args.ipaddr) + if (err != nil) != tt.wantErr { + t.Errorf("FindByIpaddr() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !(got.Id.Get() == tt.want) { + t.Errorf("FindByHwaddr() got = %v, want %v", got, tt.want) + } + }) + } +} From d6909080fc93b89e31f55ef8847a9e06cf245c67 Mon Sep 17 00:00:00 2001 From: "Michael L. Young" Date: Mon, 8 Nov 2021 08:48:15 -0500 Subject: [PATCH 08/25] Change pattern for setting VERSION and RELEASE to allow them to be overriden. --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 83b9c837..5e06dd90 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ .PHONY: all -VERSION := 4.2.0 -RELEASE := 1 +VERSION ?= 4.2.0 +RELEASE ?= 1 ifndef SRC SRC := main From fafbb810faf755a4249cde04fb14de10bedab634 Mon Sep 17 00:00:00 2001 From: "Michael L. Young" Date: Mon, 8 Nov 2021 08:54:22 -0500 Subject: [PATCH 09/25] Remove ifndef --- Makefile | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 5e06dd90..61d1687e 100644 --- a/Makefile +++ b/Makefile @@ -3,9 +3,7 @@ VERSION ?= 4.2.0 RELEASE ?= 1 -ifndef SRC - SRC := main -endif +SRC ?= main # auto installed tooling TOOLS_DIR := .tools From 0b93d6c277a754d827a40ef5d54a1b9129530183 Mon Sep 17 00:00:00 2001 From: jcsiadal Date: Mon, 8 Nov 2021 11:36:21 -0800 Subject: [PATCH 10/25] Update help Signed-off-by: jcsiadal --- cmd/man_page/man_page.go | 3 +- internal/app/wwctl/configure/dhcp/root.go | 3 +- internal/app/wwctl/configure/hosts/root.go | 3 +- internal/app/wwctl/configure/nfs/root.go | 3 +- internal/app/wwctl/configure/root.go | 3 +- internal/app/wwctl/configure/ssh/root.go | 3 +- internal/app/wwctl/configure/tftp/root.go | 3 +- internal/app/wwctl/container/build/root.go | 5 +-- internal/app/wwctl/container/delete/root.go | 5 +-- .../app/wwctl/container/exec/child/root.go | 1 + internal/app/wwctl/container/exec/root.go | 7 ++-- internal/app/wwctl/container/imprt/root.go | 10 ++++-- internal/app/wwctl/container/list/root.go | 3 +- internal/app/wwctl/container/root.go | 7 ++-- internal/app/wwctl/kernel/delete/root.go | 7 ++-- internal/app/wwctl/kernel/imprt/root.go | 6 ++-- internal/app/wwctl/kernel/list/root.go | 3 +- internal/app/wwctl/kernel/root.go | 6 ++-- internal/app/wwctl/node/add/root.go | 5 +-- internal/app/wwctl/node/console/root.go | 5 +-- internal/app/wwctl/node/delete/root.go | 5 +-- internal/app/wwctl/node/list/root.go | 8 +++-- internal/app/wwctl/node/ready/root.go | 6 ++-- internal/app/wwctl/node/root.go | 3 +- internal/app/wwctl/node/sensors/root.go | 7 ++-- internal/app/wwctl/node/set/root.go | 5 +-- internal/app/wwctl/overlay/build/root.go | 5 +-- internal/app/wwctl/overlay/chmod/root.go | 20 +++++++---- internal/app/wwctl/overlay/chown/root.go | 6 ++-- internal/app/wwctl/overlay/create/root.go | 5 +-- internal/app/wwctl/overlay/delete/root.go | 7 ++-- internal/app/wwctl/overlay/edit/root.go | 11 +++--- internal/app/wwctl/overlay/imprt/root.go | 6 ++-- internal/app/wwctl/overlay/list/root.go | 7 ++-- internal/app/wwctl/overlay/mkdir/root.go | 5 +-- internal/app/wwctl/overlay/root.go | 3 +- internal/app/wwctl/overlay/show/root.go | 5 ++- internal/app/wwctl/power/cycle/root.go | 5 +-- internal/app/wwctl/power/off/root.go | 5 +-- internal/app/wwctl/power/on/root.go | 4 +-- internal/app/wwctl/power/reset/root.go | 7 ++-- internal/app/wwctl/power/root.go | 5 +-- internal/app/wwctl/power/soft/root.go | 3 +- internal/app/wwctl/power/status/root.go | 5 +-- internal/app/wwctl/profile/add/root.go | 5 +-- internal/app/wwctl/profile/delete/root.go | 5 +-- internal/app/wwctl/profile/list/root.go | 5 +-- internal/app/wwctl/profile/root.go | 3 +- internal/app/wwctl/profile/set/root.go | 4 +-- internal/app/wwctl/root.go | 16 ++++++--- internal/app/wwctl/server/reload/root.go | 3 +- internal/app/wwctl/server/restart/root.go | 3 +- internal/app/wwctl/server/root.go | 3 +- internal/app/wwctl/server/start/root.go | 3 +- internal/app/wwctl/server/status/root.go | 3 +- internal/app/wwctl/server/stop/root.go | 3 +- internal/pkg/help/help.go | 35 +++++++++++++++++++ 57 files changed, 216 insertions(+), 114 deletions(-) create mode 100644 internal/pkg/help/help.go diff --git a/cmd/man_page/man_page.go b/cmd/man_page/man_page.go index 369026fa..8a35a3be 100644 --- a/cmd/man_page/man_page.go +++ b/cmd/man_page/man_page.go @@ -1,4 +1,5 @@ -// usage: ./bash_completion +// Generate man pages for wwctl command. +// usage: ./man_page package main import ( diff --git a/internal/app/wwctl/configure/dhcp/root.go b/internal/app/wwctl/configure/dhcp/root.go index 76ec9e97..d27f8ad3 100644 --- a/internal/app/wwctl/configure/dhcp/root.go +++ b/internal/app/wwctl/configure/dhcp/root.go @@ -6,7 +6,8 @@ import ( var ( baseCmd = &cobra.Command{ - Use: "dhcp", + DisableFlagsInUseLine: true, + Use: "dhcp [OPTIONS]", Short: "Manage and initialize DHCP", Long: "DHCP is a dependent service to Warewulf. This command will configure DHCP as defined\n" + "in the warewulf.conf file.", diff --git a/internal/app/wwctl/configure/hosts/root.go b/internal/app/wwctl/configure/hosts/root.go index a8294453..84877a40 100644 --- a/internal/app/wwctl/configure/hosts/root.go +++ b/internal/app/wwctl/configure/hosts/root.go @@ -4,7 +4,8 @@ import "github.com/spf13/cobra" var ( baseCmd = &cobra.Command{ - Use: "hosts", + DisableFlagsInUseLine: true, + Use: "hosts [OPTIONS]", Short: "Update the /etc/hosts file", Long: "Write out the /etc/hosts file based on the Warewulf template (hosts.tmpl) in the\n" + "Warewulf configuration directory.", diff --git a/internal/app/wwctl/configure/nfs/root.go b/internal/app/wwctl/configure/nfs/root.go index 4121efa9..4e074021 100644 --- a/internal/app/wwctl/configure/nfs/root.go +++ b/internal/app/wwctl/configure/nfs/root.go @@ -4,7 +4,8 @@ import "github.com/spf13/cobra" var ( baseCmd = &cobra.Command{ - Use: "nfs", + DisableFlagsInUseLine: true, + Use: "nfs [OPTIONS]", Short: "Manage and initialize NFS", Long: "NFS is an optional dependent service of Warewulf, this tool will automatically\n" + "configure NFS as per the configuration in the warewulf.conf file.", diff --git a/internal/app/wwctl/configure/root.go b/internal/app/wwctl/configure/root.go index aece4bfa..6d8a2c41 100644 --- a/internal/app/wwctl/configure/root.go +++ b/internal/app/wwctl/configure/root.go @@ -15,7 +15,8 @@ import ( var ( baseCmd = &cobra.Command{ - Use: "configure", + DisableFlagsInUseLine: true, + Use: "configure [OPTIONS]", Short: "Manage system services", Long: "This application allows you to manage and initialize Warewulf dependent system\n" + "services based on the configuration in the warewulf.conf file.", diff --git a/internal/app/wwctl/configure/ssh/root.go b/internal/app/wwctl/configure/ssh/root.go index 8f7ba046..2246c0db 100644 --- a/internal/app/wwctl/configure/ssh/root.go +++ b/internal/app/wwctl/configure/ssh/root.go @@ -4,7 +4,8 @@ import "github.com/spf13/cobra" var ( baseCmd = &cobra.Command{ - Use: "ssh", + DisableFlagsInUseLine: true, + Use: "ssh [OPTIONS]", Short: "Manage and initialize SSH", Long: "SSH is an optionally dependent service for Warewulf, this tool will automatically\n" + "setup the ssh keys nodes using the 'default' system overlay as well as user owned\n" + diff --git a/internal/app/wwctl/configure/tftp/root.go b/internal/app/wwctl/configure/tftp/root.go index 9b5edb2e..7629fa2c 100644 --- a/internal/app/wwctl/configure/tftp/root.go +++ b/internal/app/wwctl/configure/tftp/root.go @@ -4,7 +4,8 @@ import "github.com/spf13/cobra" var ( baseCmd = &cobra.Command{ - Use: "tftp", + DisableFlagsInUseLine: true, + Use: "tftp [OPTIONS]", Short: "Manage and initialize TFTP", Long: "TFTP is a dependent service of Warewulf, this tool will enable the tftp services\n" + "on your Warewulf master.", diff --git a/internal/app/wwctl/container/build/root.go b/internal/app/wwctl/container/build/root.go index d02e651d..93ff98cd 100644 --- a/internal/app/wwctl/container/build/root.go +++ b/internal/app/wwctl/container/build/root.go @@ -7,9 +7,10 @@ import ( var ( baseCmd = &cobra.Command{ - Use: "build [flags] [container name]...", + DisableFlagsInUseLine: true, + Use: "build [OPTIONS] CONTAINER [...]", Short: "(Re)build a bootable VNFS image", - Long: "This command will build a bootable VNFS image from an imported container image.", + Long: "This command will build a bootable VNFS image from imported CONTAINER image(s).", RunE: CobraRunE, Args: cobra.MinimumNArgs(1), ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { diff --git a/internal/app/wwctl/container/delete/root.go b/internal/app/wwctl/container/delete/root.go index fe0e5d23..64e909ba 100644 --- a/internal/app/wwctl/container/delete/root.go +++ b/internal/app/wwctl/container/delete/root.go @@ -7,9 +7,10 @@ import ( var ( baseCmd = &cobra.Command{ - Use: "delete [flags] [container name]...", + DisableFlagsInUseLine: true, + Use: "delete [OPTIONS] CONTAINER [...]", Short: "Delete an imported container", - Long: "This command will delete a container that has been imported into Warewulf.", + Long: "This command will delete CONTAINERs that have been imported into Warewulf.", RunE: CobraRunE, ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { if len(args) != 0 { diff --git a/internal/app/wwctl/container/exec/child/root.go b/internal/app/wwctl/container/exec/child/root.go index 8a9d422b..0b7dde7c 100644 --- a/internal/app/wwctl/container/exec/child/root.go +++ b/internal/app/wwctl/container/exec/child/root.go @@ -4,6 +4,7 @@ import "github.com/spf13/cobra" var ( baseCmd = &cobra.Command{ + DisableFlagsInUseLine: true, Use: "__child", Hidden: true, RunE: CobraRunE, diff --git a/internal/app/wwctl/container/exec/root.go b/internal/app/wwctl/container/exec/root.go index 8e418541..a3022599 100644 --- a/internal/app/wwctl/container/exec/root.go +++ b/internal/app/wwctl/container/exec/root.go @@ -8,10 +8,11 @@ import ( var ( baseCmd = &cobra.Command{ - Use: "exec [flags] [container name] [command]", + DisableFlagsInUseLine: true, + Use: "exec [OPTIONS] CONTAINER COMMAND", Short: "Run a command inside of a Warewulf container", - Long: "This command will allow you to run any command inside of a given\n" + - "warewulf container. This is commonly used with an interactive shell such as /bin/bash\n" + + Long: "Run a COMMAND inside of a warewulf CONTAINER.\n" + + "This is commonly used with an interactive shell such as /bin/bash\n" + "to run a virtual environment within the container.", RunE: CobraRunE, Args: cobra.MinimumNArgs(2), diff --git a/internal/app/wwctl/container/imprt/root.go b/internal/app/wwctl/container/imprt/root.go index 1725d06a..94772821 100644 --- a/internal/app/wwctl/container/imprt/root.go +++ b/internal/app/wwctl/container/imprt/root.go @@ -4,10 +4,14 @@ import "github.com/spf13/cobra" var ( baseCmd = &cobra.Command{ - Use: "import [flags] [container source URI]", + DisableFlagsInUseLine: true, + Use: "imprt [OPTIONS] SOURCE [NAME]", Short: "Import a container into Warewulf", - Long: "This command will pull and import a container into Warewulf so it can be used\n" + - "as a source to create a bootable VNFS image.", + Long: +`This command will pull and import a container into Warewulf from SOURCE, +optionally renaming it to NAME. The SOURCE must be in a supported URI format. +Imported containers are used to create bootable VNFS images.`, + Example: "wwctl container import docker://warewulf/centos-8 my_container", RunE: CobraRunE, Args: cobra.MinimumNArgs(1), } diff --git a/internal/app/wwctl/container/list/root.go b/internal/app/wwctl/container/list/root.go index 273eb371..908aae77 100644 --- a/internal/app/wwctl/container/list/root.go +++ b/internal/app/wwctl/container/list/root.go @@ -4,7 +4,8 @@ import "github.com/spf13/cobra" var ( baseCmd = &cobra.Command{ - Use: "list [flags]", + DisableFlagsInUseLine: true, + Use: "list [OPTIONS]", Short: "List imported Warewulf containers", Long: "This command will show you the containers that are imported into Warewulf.", RunE: CobraRunE, diff --git a/internal/app/wwctl/container/root.go b/internal/app/wwctl/container/root.go index 79bc0a5f..02efc3b0 100644 --- a/internal/app/wwctl/container/root.go +++ b/internal/app/wwctl/container/root.go @@ -11,11 +11,12 @@ import ( var ( baseCmd = &cobra.Command{ - Use: "container", + 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" + - "images for nodes to boot. These commands will help you import, management, and\n" + - "transform containers into bootable Warewulf VNFS images.", + "node images. These commands will help you import, manage, and transform\n" + + "containers into bootable Warewulf VNFS images.", Aliases: []string{"vnfs"}, } ) diff --git a/internal/app/wwctl/kernel/delete/root.go b/internal/app/wwctl/kernel/delete/root.go index 4e714b46..5fc68bea 100644 --- a/internal/app/wwctl/kernel/delete/root.go +++ b/internal/app/wwctl/kernel/delete/root.go @@ -7,9 +7,10 @@ import ( var ( baseCmd = &cobra.Command{ - Use: "delete [flags] [kernel version]...", - Short: "Delete an imported kernel", - Long: "This command will delete a kernel that has been imported into Warewulf.", + DisableFlagsInUseLine: true, + Use: "delete [OPTIONS] KERNEL [...]", + Short: "Delete imported kernels", + Long: "This command will delete KERNEL versions that have been imported into Warewulf.", RunE: CobraRunE, Args: cobra.MinimumNArgs(1), ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { diff --git a/internal/app/wwctl/kernel/imprt/root.go b/internal/app/wwctl/kernel/imprt/root.go index cc6e2539..7d398264 100644 --- a/internal/app/wwctl/kernel/imprt/root.go +++ b/internal/app/wwctl/kernel/imprt/root.go @@ -9,10 +9,10 @@ import ( var ( baseCmd = &cobra.Command{ - Use: "import [flags] [kernel version]", + DisableFlagsInUseLine: true, + Use: "import [OPTIONS] KERNEL", Short: "Import Kernel version into Warewulf", - Long: "This will import a Kernel version from the control node into Warewulf for nodes\n" + - "to be configured to boot on.", + Long: "This will import a boot KERNEL version from the control node into Warewulf", RunE: CobraRunE, Args: cobra.MinimumNArgs(1), } diff --git a/internal/app/wwctl/kernel/list/root.go b/internal/app/wwctl/kernel/list/root.go index 2fcceb4b..fba84101 100644 --- a/internal/app/wwctl/kernel/list/root.go +++ b/internal/app/wwctl/kernel/list/root.go @@ -4,7 +4,8 @@ import "github.com/spf13/cobra" var ( baseCmd = &cobra.Command{ - Use: "list [flags]", + DisableFlagsInUseLine: true, + Use: "list [OPTIONS]", Short: "List imported Kernel images", Long: "This command will list the kernels that have been imported into Warewulf.", RunE: CobraRunE, diff --git a/internal/app/wwctl/kernel/root.go b/internal/app/wwctl/kernel/root.go index 33d74b0a..bb0cdb8d 100644 --- a/internal/app/wwctl/kernel/root.go +++ b/internal/app/wwctl/kernel/root.go @@ -9,10 +9,10 @@ import ( var ( baseCmd = &cobra.Command{ - Use: "kernel", + DisableFlagsInUseLine: true, + Use: "kernel COMMAND [OPTIONS]", Short: "Kernel Image Management", - Long: "This command is for management of Warewulf Kernels to be used for\n" + - "bootstrapping nodes", + Long: "This command manages Warewulf Kernels used for bootstrapping nodes", } ) diff --git a/internal/app/wwctl/node/add/root.go b/internal/app/wwctl/node/add/root.go index c4c716b3..2df38971 100644 --- a/internal/app/wwctl/node/add/root.go +++ b/internal/app/wwctl/node/add/root.go @@ -4,9 +4,10 @@ import "github.com/spf13/cobra" var ( baseCmd = &cobra.Command{ - Use: "add [flags] [node pattern]", + DisableFlagsInUseLine: true, + Use: "add [OPTIONS] NODENAME", Short: "Add new node to Warewulf", - Long: "This command will add a new node to Warewulf.", + Long: "This command will add a new node named NODENAME to Warewulf.", RunE: CobraRunE, Args: cobra.MinimumNArgs(1), } diff --git a/internal/app/wwctl/node/console/root.go b/internal/app/wwctl/node/console/root.go index 6a4e1b9f..a0d05f4e 100644 --- a/internal/app/wwctl/node/console/root.go +++ b/internal/app/wwctl/node/console/root.go @@ -6,9 +6,10 @@ import ( var ( powerCmd = &cobra.Command{ - Use: "console [flags] [node pattern]", + DisableFlagsInUseLine: true, + Use: "console [OPTIONS] NODENAME", Short: "Connect to IPMI console", - Long: "Start IPMI console for a singe node.", + Long: "Start a new IPMI console for NODENAME.", Args: cobra.MinimumNArgs(1), RunE: CobraRunE, } diff --git a/internal/app/wwctl/node/delete/root.go b/internal/app/wwctl/node/delete/root.go index b62664f2..95a96f8f 100644 --- a/internal/app/wwctl/node/delete/root.go +++ b/internal/app/wwctl/node/delete/root.go @@ -7,9 +7,10 @@ import ( var ( baseCmd = &cobra.Command{ - Use: "delete [flags] [exact node name]...", + DisableFlagsInUseLine: true, + Use: "delete [OPTIONS] NODE [NODE ...]", Short: "Delete a node from Warewulf", - Long: "This command will remove a node from the Warewulf node configuration.", + Long: "This command will remove NODE(s) from the Warewulf node configuration.", Args: cobra.MinimumNArgs(1), RunE: CobraRunE, Aliases: []string{"rm", "del"}, diff --git a/internal/app/wwctl/node/list/root.go b/internal/app/wwctl/node/list/root.go index b72903ed..e9c78d6c 100644 --- a/internal/app/wwctl/node/list/root.go +++ b/internal/app/wwctl/node/list/root.go @@ -4,9 +4,11 @@ import "github.com/spf13/cobra" var ( baseCmd = &cobra.Command{ - Use: "list [flags] (node pattern)", - Short: "List nodes matching pattern", - Long: "This command will show you configured nodes.", + DisableFlagsInUseLine: true, + Use: "list [OPTIONS] [PATTERN]", + Short: "List nodes", + Long: "This command lists all configured nodes. Optionally, it will list only\n" + + "nodes matching a glob PATTERN.", RunE: CobraRunE, Aliases: []string{"ls"}, } diff --git a/internal/app/wwctl/node/ready/root.go b/internal/app/wwctl/node/ready/root.go index abcba8b8..fb129a22 100644 --- a/internal/app/wwctl/node/ready/root.go +++ b/internal/app/wwctl/node/ready/root.go @@ -7,8 +7,10 @@ import ( var ( baseCmd = &cobra.Command{ - Use: "ready", - Short: "Warewulf Status Check", + DisableFlagsInUseLine: true, + Use: "ready [OPTIONS]", + Short: "Warewulf status check", + Long: "Provides the current status of all Warewulf nodes.", RunE: CobraRunE, ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { if len(args) != 0 { diff --git a/internal/app/wwctl/node/root.go b/internal/app/wwctl/node/root.go index 7a37b726..a8b10061 100644 --- a/internal/app/wwctl/node/root.go +++ b/internal/app/wwctl/node/root.go @@ -13,7 +13,8 @@ import ( var ( baseCmd = &cobra.Command{ - Use: "node", + DisableFlagsInUseLine: true, + Use: "node COMMAND [OPTONS]", Short: "Node management", Long: "Management of node settings. All node ranges can use brackets to identify\n" + "node ranges. For example: n00[00-4].cluster[0-1] will identify the first 5 nodes\n" + diff --git a/internal/app/wwctl/node/sensors/root.go b/internal/app/wwctl/node/sensors/root.go index ea95dd4f..07405812 100644 --- a/internal/app/wwctl/node/sensors/root.go +++ b/internal/app/wwctl/node/sensors/root.go @@ -7,9 +7,10 @@ import ( var ( powerCmd = &cobra.Command{ - Use: "sensors [flags] [node pattern]", - Short: "Show node's IPMI sensor information", - Long: "Show IPMI sensors for a single node.", + DisableFlagsInUseLine: true, + Use: "sensors [OPTIONS] PATTERN", + Short: "Show node IPMI sensor information", + Long: "Show IPMI sensor information for nodes matching PATTERN.", Args: cobra.MinimumNArgs(1), RunE: CobraRunE, ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { diff --git a/internal/app/wwctl/node/set/root.go b/internal/app/wwctl/node/set/root.go index 767bb94c..19fca758 100644 --- a/internal/app/wwctl/node/set/root.go +++ b/internal/app/wwctl/node/set/root.go @@ -12,9 +12,10 @@ import ( var ( baseCmd = &cobra.Command{ - Use: "set [flags] [node pattern]...", + DisableFlagsInUseLine: true, + Use: "set [OPTIONS] PATTERN [PATTERN ...]", Short: "Configure node properties", - Long: "This command will allow you to set configuration properties for nodes.\n\n" + + Long: "This command sets configuration properties for nodes matching PATTERN.\n\n" + "Note: use the string 'UNSET' to remove a configuration", Args: cobra.MinimumNArgs(1), RunE: CobraRunE, diff --git a/internal/app/wwctl/overlay/build/root.go b/internal/app/wwctl/overlay/build/root.go index 197c9f5e..5b5bb45d 100644 --- a/internal/app/wwctl/overlay/build/root.go +++ b/internal/app/wwctl/overlay/build/root.go @@ -4,9 +4,10 @@ import "github.com/spf13/cobra" var ( baseCmd = &cobra.Command{ - Use: "build [flags] (overlay kind) (overlay name)", + DisableFlagsInUseLine: true, + Use: "build [OPTIONS] {system|runtime} OVERLAY_NAME", Short: "(Re)build an overlay", - Long: "This command will build a system or runtime overlay.", + Long: "This command builds a new system or runtime overlay named OVERLAY_NAME.", RunE: CobraRunE, Args: cobra.RangeArgs(0, 2), } diff --git a/internal/app/wwctl/overlay/chmod/root.go b/internal/app/wwctl/overlay/chmod/root.go index d9755157..7790c5df 100644 --- a/internal/app/wwctl/overlay/chmod/root.go +++ b/internal/app/wwctl/overlay/chmod/root.go @@ -1,15 +1,21 @@ package chmod -import "github.com/spf13/cobra" +import ( + "github.com/spf13/cobra" +) var ( baseCmd = &cobra.Command{ - Use: "chmod [flags] (overlay kind) (overlay name) (path) (mode)", - Short: "Change file permissions within an overlay", - Long: "This command will allow you to change the permissions of a file within an\n" + - "overlay.", - RunE: CobraRunE, - Args: cobra.ExactArgs(4), + DisableFlagsInUseLine: true, + Use: "chmod [OPTIONS] {runtime|system} OVERLAY_NAME FILENAME MODE", + Short: "Change file permissions in an overlay", + Long: `Changes the permissions of a single FILENAME within an overlay specified by +overlay type (system or runtime) and its OVERLAY_NAME. + +You can use any MODE format supported by the chmod command.`, + Example: "wwctl overlay chmod system default /etc/hostname.ww 0660", + RunE: CobraRunE, + Args: cobra.ExactArgs(4), } ) diff --git a/internal/app/wwctl/overlay/chown/root.go b/internal/app/wwctl/overlay/chown/root.go index 970434dd..8d45823e 100644 --- a/internal/app/wwctl/overlay/chown/root.go +++ b/internal/app/wwctl/overlay/chown/root.go @@ -4,10 +4,10 @@ import "github.com/spf13/cobra" var ( baseCmd = &cobra.Command{ - Use: "chown [flags] (overlay kind) (overlay name) (path) (UID) [(GID)]", + Use: "chown [OPTIONS] {system|runtime} OVERLAY_NAME FILE UID [GID]", Short: "Change file ownership within an overlay", - Long: "This command will allow you to change the ownership of a file within an\n" + - "overlay.", + Long: "This command changes the ownership of a FILE within the system or runtime OVERLAY_NAME\n" + + "to the user specified by UID. Optionally, it will also change group ownership to GID.", RunE: CobraRunE, Args: cobra.RangeArgs(4, 5), } diff --git a/internal/app/wwctl/overlay/create/root.go b/internal/app/wwctl/overlay/create/root.go index 9b671b3b..b09b249e 100644 --- a/internal/app/wwctl/overlay/create/root.go +++ b/internal/app/wwctl/overlay/create/root.go @@ -6,9 +6,10 @@ import ( var ( baseCmd = &cobra.Command{ - Use: "create [flags] (overlay kind) (overlay name)", + DisableFlagsInUseLine: true, + Use: "create [OPTIONS] {system|runtime} OVERLAY_NAME", Short: "Initialize a new Overlay", - Long: "This command will create a new empty overlay.", + Long: "This command creates a new empty system or runtime overlay named OVERLAY_NAME.", RunE: CobraRunE, Args: cobra.ExactArgs(2), } diff --git a/internal/app/wwctl/overlay/delete/root.go b/internal/app/wwctl/overlay/delete/root.go index da636e8d..875909b3 100644 --- a/internal/app/wwctl/overlay/delete/root.go +++ b/internal/app/wwctl/overlay/delete/root.go @@ -6,10 +6,11 @@ import ( var ( baseCmd = &cobra.Command{ - Use: "delete [flags] (overlay kind) (overlay name) [overlay file]", + DisableFlagsInUseLine: true, + Use: "delete [OPTIONS] {runtime|system} OVERLAY_NAME [FILE [FILE ...]]", Short: "Delete Warewulf Overlay or files", - Long: "This command will delete files within an overlay or an entire overlay if no\n" + - "files are given to remove (use with caution).", + Long: "This command will delete FILEs within OVERLAY_NAME or the entire OVERLAY_NAME if no\n" + + "files are listed. Use with caution!", RunE: CobraRunE, Args: cobra.RangeArgs(2, 3), Aliases: []string{"rm", "del"}, diff --git a/internal/app/wwctl/overlay/edit/root.go b/internal/app/wwctl/overlay/edit/root.go index e1b5c2cf..7f981614 100644 --- a/internal/app/wwctl/overlay/edit/root.go +++ b/internal/app/wwctl/overlay/edit/root.go @@ -6,11 +6,12 @@ import ( var ( baseCmd = &cobra.Command{ - Use: "edit [flags] (overlay kind) (overlay name) (file path)", - Short: "Edit/Create a file within a Warewulf Overlay", - Long: "This command will allow you to edit or create a new file within a given\n" + - "overlay. Note: when creating files ending in a '.ww' suffix this will always be\n" + - "parsed as a Warewulf template file, and the suffix will be removed automatically.", + DisableFlagsInUseLine: true, + Use: "edit [OPTIONS] {system|runtime} OVERLAY_NAME FILE", + Short: "Edit or create a file within a Warewulf Overlay", + Long: "This command will open the FILE for editing or create a new file within the\n" + + "OVERLAY_NAME. Note: files created with a '.ww' suffix will always be\n" + + "parsed as Warewulf template files, and the suffix will be removed automatically.", RunE: CobraRunE, Args: cobra.ExactArgs(3), } diff --git a/internal/app/wwctl/overlay/imprt/root.go b/internal/app/wwctl/overlay/imprt/root.go index c0fcbad9..0e4c2146 100644 --- a/internal/app/wwctl/overlay/imprt/root.go +++ b/internal/app/wwctl/overlay/imprt/root.go @@ -4,9 +4,11 @@ import "github.com/spf13/cobra" var ( baseCmd = &cobra.Command{ - Use: "import [flags] (overlay kind) (overlay name) (host source) [overlay target]", + DisableFlagsInUseLine: true, + Use: "import [OPTIONS] {system|runtime} OVERLAY_NAME FILE [NEW_NAME]", Short: "Import a file into a Warewulf Overlay", - Long: "This command will import a file into a given Warewulf overlay.", + Long: "This command imports the FILE into the Warewulf OVERLAY_NAME.\n" + + "Optionally, the file can be renamed to NEW_NAME", RunE: CobraRunE, Args: cobra.RangeArgs(3, 4), Aliases: []string{"cp"}, diff --git a/internal/app/wwctl/overlay/list/root.go b/internal/app/wwctl/overlay/list/root.go index ea2310e9..c7b33ce4 100644 --- a/internal/app/wwctl/overlay/list/root.go +++ b/internal/app/wwctl/overlay/list/root.go @@ -6,10 +6,11 @@ import ( var ( baseCmd = &cobra.Command{ - Use: "list [flags] (overlay kind) [overlay name]", + DisableFlagsInUseLine: true, + Use: "list [OPTIONS] {system|runtime} [OVERLAY_NAME]", Short: "List Warewulf Overlays and files", - Long: "This command will show you information about Warewulf overlays and the\n" + - "files contained within.", + Long: "This command displays information about all Warewulf overlays or the specified\n" + + "OVERLAY_NAME. It also supports listing overlay content information.", RunE: CobraRunE, Args: cobra.MinimumNArgs(1), Aliases: []string{"ls"}, diff --git a/internal/app/wwctl/overlay/mkdir/root.go b/internal/app/wwctl/overlay/mkdir/root.go index 148d0514..e95cba0a 100644 --- a/internal/app/wwctl/overlay/mkdir/root.go +++ b/internal/app/wwctl/overlay/mkdir/root.go @@ -6,9 +6,10 @@ import ( var ( baseCmd = &cobra.Command{ - Use: "mkdir [flags] (overlay kind) (overlay name) (directory path)", + DisableFlagsInUseLine: true, + Use: "mkdir [OPTIONS] {system|runtime} OVERLAY_NAME DIRECTORY", Short: "Create a new directory within an Overlay", - Long: "This command will allow you to create a new file within a given Warewulf overlay.", + Long: "This command creates a new directory within the Warewulf OVERLAY_NAME.", RunE: CobraRunE, Args: cobra.MinimumNArgs(3), } diff --git a/internal/app/wwctl/overlay/root.go b/internal/app/wwctl/overlay/root.go index 616a99c0..4bb1cd95 100644 --- a/internal/app/wwctl/overlay/root.go +++ b/internal/app/wwctl/overlay/root.go @@ -16,7 +16,8 @@ import ( var ( baseCmd = &cobra.Command{ - Use: "overlay", + DisableFlagsInUseLine: true, + Use: "overlay COMMAND [OPTIONS]", Short: "Warewulf Overlay Management", Long: "Management interface for Warewulf overlays", } diff --git a/internal/app/wwctl/overlay/show/root.go b/internal/app/wwctl/overlay/show/root.go index fe58f714..43c491ce 100644 --- a/internal/app/wwctl/overlay/show/root.go +++ b/internal/app/wwctl/overlay/show/root.go @@ -6,10 +6,9 @@ import ( var ( baseCmd = &cobra.Command{ - Use: "show [flags] (overlay kind) (overlay name) (overlay file)", + Use: "show [OPTIONS] {system|runtime} OVERLAY_NAME FILE", Short: "Show (cat) a file within a Warewulf Overlay", - Long: "This command will output the contents of a file within a given\n" + - "Warewulf overlay.", + Long: "This command displays the contents of FILE within OVERLAY_NAME.", RunE: CobraRunE, Aliases: []string{"cat"}, Args: cobra.ExactArgs(3), diff --git a/internal/app/wwctl/power/cycle/root.go b/internal/app/wwctl/power/cycle/root.go index fcd9093d..18f0fc51 100644 --- a/internal/app/wwctl/power/cycle/root.go +++ b/internal/app/wwctl/power/cycle/root.go @@ -6,9 +6,10 @@ import ( var ( powerCmd = &cobra.Command{ - Use: "cycle [flags] (node pattern)...", + DisableFlagsInUseLine: true, + Use: "cycle [OPTIONS] [PATTERN ...]", Short: "Power cycle the given node(s)", - Long: "This command will cycle the power for a given set of nodes.", + Long: "This command cycles power for a set of nodes specified by PATTERN.", RunE: CobraRunE, } ) diff --git a/internal/app/wwctl/power/off/root.go b/internal/app/wwctl/power/off/root.go index 0b98bed1..cb659dda 100644 --- a/internal/app/wwctl/power/off/root.go +++ b/internal/app/wwctl/power/off/root.go @@ -7,9 +7,10 @@ import ( var ( powerCmd = &cobra.Command{ - Use: "off", + DisableFlagsInUseLine: true, + Use: "off [OPTIONS] [PATTERN ...]", Short: "Power off the given node(s)", - Long: "This command will shutdown the power to a given set of nodes.", + Long: "This command will shutdown power to a set of nodes specified by PATTERN.", RunE: CobraRunE, ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { if len(args) != 0 { diff --git a/internal/app/wwctl/power/on/root.go b/internal/app/wwctl/power/on/root.go index 7918299a..8e195e18 100644 --- a/internal/app/wwctl/power/on/root.go +++ b/internal/app/wwctl/power/on/root.go @@ -7,9 +7,9 @@ import ( var ( powerCmd = &cobra.Command{ - Use: "on", + Use: "on [OPTIONS] [PATTERN ...]", Short: "Power on the given node(s)", - Long: "This command will power on a given set of nodes.", + Long: "This command will power on a set of nodes specified by PATTERN.", RunE: CobraRunE, ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { if len(args) != 0 { diff --git a/internal/app/wwctl/power/reset/root.go b/internal/app/wwctl/power/reset/root.go index 6622de8e..02d79c3a 100644 --- a/internal/app/wwctl/power/reset/root.go +++ b/internal/app/wwctl/power/reset/root.go @@ -7,9 +7,10 @@ import ( var ( powerCmd = &cobra.Command{ - Use: "reset", - Short: "Issue a reset to the given node(s)", - Long: "This command will issue a reset to the given set of nodes.", + DisableFlagsInUseLine: true, + Use: "reset [OPTIONS] [PATTERN ...]", + Short: "Issue a reset to node(s)", + Long: "This command will issue a reset to a set of nodes specified by PATTERN.", RunE: CobraRunE, ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { if len(args) != 0 { diff --git a/internal/app/wwctl/power/root.go b/internal/app/wwctl/power/root.go index e2222e29..135139b2 100644 --- a/internal/app/wwctl/power/root.go +++ b/internal/app/wwctl/power/root.go @@ -12,9 +12,10 @@ import ( var ( baseCmd = &cobra.Command{ - Use: "power", + DisableFlagsInUseLine: true, + Use: "power COMMAND [OPTIONS]", Short: "Warewulf node power management", - Long: "This command can control the power state of nodes.", + Long: "This command controls the power state of nodes.", } ) diff --git a/internal/app/wwctl/power/soft/root.go b/internal/app/wwctl/power/soft/root.go index af13114c..77100254 100644 --- a/internal/app/wwctl/power/soft/root.go +++ b/internal/app/wwctl/power/soft/root.go @@ -7,9 +7,10 @@ import ( var ( powerCmd = &cobra.Command{ + DisableFlagsInUseLine: true, Use: "soft", Short: "Gracefully shuts down the given node(s)", - Long: "This command will gracefully shutdown the given set of nodes.", + Long: "This command uses the operationg system to shut down the set of nodes specified by PATTERN.", RunE: CobraRunE, ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { if len(args) != 0 { diff --git a/internal/app/wwctl/power/status/root.go b/internal/app/wwctl/power/status/root.go index 454165e5..40c6fc64 100644 --- a/internal/app/wwctl/power/status/root.go +++ b/internal/app/wwctl/power/status/root.go @@ -7,9 +7,10 @@ import ( var ( powerCmd = &cobra.Command{ - Use: "status", + DisableFlagsInUseLine: true, + Use: "status [OPTIONS] [PATTERN ...]", Short: "Show power status for the given node(s)", - Long: "This command will show the power status of a given set of nodes.", + Long: "This command displays the power status of a set of nodes specified by PATTERN.", RunE: CobraRunE, ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { if len(args) != 0 { diff --git a/internal/app/wwctl/profile/add/root.go b/internal/app/wwctl/profile/add/root.go index f560128c..9e95d8d2 100644 --- a/internal/app/wwctl/profile/add/root.go +++ b/internal/app/wwctl/profile/add/root.go @@ -4,9 +4,10 @@ import "github.com/spf13/cobra" var ( baseCmd = &cobra.Command{ - Use: "add (profile name)", + DisableFlagsInUseLine: true, + Use: "add PROFILE", Short: "Add a new node profile", - Long: "This command will add a new node profile.", + Long: "This command adds a new named PROFILE.", RunE: CobraRunE, Args: cobra.MinimumNArgs(1), } diff --git a/internal/app/wwctl/profile/delete/root.go b/internal/app/wwctl/profile/delete/root.go index aaf92662..a5cea9e1 100644 --- a/internal/app/wwctl/profile/delete/root.go +++ b/internal/app/wwctl/profile/delete/root.go @@ -4,9 +4,10 @@ import "github.com/spf13/cobra" var ( baseCmd = &cobra.Command{ - Use: "delete [flags] (profile pattern)", + DisableFlagsInUseLine: true, + Use: "delete [OPTIONS] PROFILE", Short: "Delete a node profile", - Long: "This command will delete a node profile.", + Long: "This command deletes the node PROFILE. You may use a pattern for PROFILE.", RunE: CobraRunE, Args: cobra.MinimumNArgs(1), } diff --git a/internal/app/wwctl/profile/list/root.go b/internal/app/wwctl/profile/list/root.go index 6c795ebb..1144d5c2 100644 --- a/internal/app/wwctl/profile/list/root.go +++ b/internal/app/wwctl/profile/list/root.go @@ -4,9 +4,10 @@ import "github.com/spf13/cobra" var ( baseCmd = &cobra.Command{ - Use: "list [flags] [profile pattern]...", + DisableFlagsInUseLine: true, + Use: "list [OPTIONS] [PROFILE ...]", Short: "List profiles and configurations", - Long: "This command will list and show the profile configurations.", + Long: "This command will display configurations for PROFILE.", RunE: CobraRunE, Aliases: []string{"ls"}, } diff --git a/internal/app/wwctl/profile/root.go b/internal/app/wwctl/profile/root.go index faa89044..2945d04e 100644 --- a/internal/app/wwctl/profile/root.go +++ b/internal/app/wwctl/profile/root.go @@ -10,7 +10,8 @@ import ( var ( baseCmd = &cobra.Command{ - Use: "profile", + DisableFlagsInUseLine: true, + Use: "profile COMMAND [OPTIONS]", Short: "Node configuration profile management", Long: "Management of node profile settings", } diff --git a/internal/app/wwctl/profile/set/root.go b/internal/app/wwctl/profile/set/root.go index 6e533b5f..3bbccf73 100644 --- a/internal/app/wwctl/profile/set/root.go +++ b/internal/app/wwctl/profile/set/root.go @@ -12,9 +12,9 @@ import ( var ( baseCmd = &cobra.Command{ - Use: "set [flags] (profile pattern)...", + Use: "set [OPTIONS] [PROFILE ...]", Short: "Configure node profile properties", - Long: "This command will allow you to set configuration properties for node profiles.\n\n" + + Long: "This command sets configuration properties for the node PROFILE(s).\n\n" + "Note: use the string 'UNSET' to remove a configuration", Args: cobra.MinimumNArgs(1), RunE: CobraRunE, diff --git a/internal/app/wwctl/root.go b/internal/app/wwctl/root.go index 840fbb6e..10437f80 100644 --- a/internal/app/wwctl/root.go +++ b/internal/app/wwctl/root.go @@ -10,6 +10,7 @@ import ( "github.com/hpcng/warewulf/internal/app/wwctl/profile" "github.com/hpcng/warewulf/internal/app/wwctl/server" "github.com/hpcng/warewulf/internal/pkg/wwlog" + "github.com/hpcng/warewulf/internal/pkg/help" "github.com/spf13/cobra" "github.com/spf13/cobra/doc" @@ -18,9 +19,10 @@ import ( var ( rootCmd = &cobra.Command{ - Use: "wwctl", + DisableFlagsInUseLine: true, + Use: "wwctl COMMAND [OPTIONS]", Short: "Warewulf Control", - Long: "Control interface to the Cluster Warewulf Provisioning System.", + Long: "Control interface to the Warewulf Cluster Provisioning System.", PersistentPreRunE: rootPersistentPreRunE, SilenceUsage: true, SilenceErrors: true, @@ -33,6 +35,9 @@ func init() { rootCmd.PersistentFlags().BoolVarP(&verboseArg, "verbose", "v", false, "Run with increased verbosity.") rootCmd.PersistentFlags().BoolVarP(&DebugFlag, "debug", "d", false, "Run with debugging messages enabled.") + rootCmd.SetUsageTemplate(help.UsageTemplate) + rootCmd.SetHelpTemplate(help.HelpTemplate) + rootCmd.AddCommand(overlay.GetCommand()) rootCmd.AddCommand(container.GetCommand()) rootCmd.AddCommand(node.GetCommand()) @@ -60,14 +65,17 @@ func rootPersistentPreRunE(cmd *cobra.Command, args []string) error { return nil } -// GenBashCompletionFile +// External functions not used by the wwctl command line + +// Generate Bash completion file func GenBashCompletion(w io.Writer) error { return rootCmd.GenBashCompletion(w) } +// Generate man pages func GenManTree(fileName string) error { header := &doc.GenManHeader{ - Title: "MINE", + Title: "WWCTL", Section: "1", } return doc.GenManTree(rootCmd, header, fileName) diff --git a/internal/app/wwctl/server/reload/root.go b/internal/app/wwctl/server/reload/root.go index b503b746..9a880b7a 100644 --- a/internal/app/wwctl/server/reload/root.go +++ b/internal/app/wwctl/server/reload/root.go @@ -4,7 +4,8 @@ import "github.com/spf13/cobra" var ( baseCmd = &cobra.Command{ - Use: "reload", + DisableFlagsInUseLine: true, + Use: "reload [OPTIONS]", Short: "Reload the Warewulf server configuration", RunE: CobraRunE, } diff --git a/internal/app/wwctl/server/restart/root.go b/internal/app/wwctl/server/restart/root.go index c1538dcd..84224ed6 100644 --- a/internal/app/wwctl/server/restart/root.go +++ b/internal/app/wwctl/server/restart/root.go @@ -4,7 +4,8 @@ import "github.com/spf13/cobra" var ( baseCmd = &cobra.Command{ - Use: "restart", + DisableFlagsInUseLine: true, + Use: "restart [OPTIONS]", Short: "Restart the Warewulf server", RunE: CobraRunE, } diff --git a/internal/app/wwctl/server/root.go b/internal/app/wwctl/server/root.go index de865f63..22b1bce3 100644 --- a/internal/app/wwctl/server/root.go +++ b/internal/app/wwctl/server/root.go @@ -11,7 +11,8 @@ import ( var ( baseCmd = &cobra.Command{ - Use: "server", + DisableFlagsInUseLine: true, + Use: "server COMMAND [OPTIONS]", Short: "Warewulf server process commands", Long: "This command will allow you to control the Warewulf daemon process.", } diff --git a/internal/app/wwctl/server/start/root.go b/internal/app/wwctl/server/start/root.go index 2d4ca442..be4e0621 100644 --- a/internal/app/wwctl/server/start/root.go +++ b/internal/app/wwctl/server/start/root.go @@ -4,7 +4,8 @@ import "github.com/spf13/cobra" var ( baseCmd = &cobra.Command{ - Use: "start", + DisableFlagsInUseLine: true, + Use: "start [OPTIONS]", Short: "Start Warewulf server", RunE: CobraRunE, } diff --git a/internal/app/wwctl/server/status/root.go b/internal/app/wwctl/server/status/root.go index d7e6270a..83a07b8c 100644 --- a/internal/app/wwctl/server/status/root.go +++ b/internal/app/wwctl/server/status/root.go @@ -4,7 +4,8 @@ import "github.com/spf13/cobra" var ( baseCmd = &cobra.Command{ - Use: "status", + DisableFlagsInUseLine: true, + Use: "status [OPTIONS]", Short: "Warewulf server status", RunE: CobraRunE, } diff --git a/internal/app/wwctl/server/stop/root.go b/internal/app/wwctl/server/stop/root.go index 23549d95..94df3acc 100644 --- a/internal/app/wwctl/server/stop/root.go +++ b/internal/app/wwctl/server/stop/root.go @@ -4,7 +4,8 @@ import "github.com/spf13/cobra" var ( baseCmd = &cobra.Command{ - Use: "stop", + DisableFlagsInUseLine: true, + Use: "stop [OPTIONS]", Short: "Stop Warewulf server", RunE: CobraRunE, } diff --git a/internal/pkg/help/help.go b/internal/pkg/help/help.go new file mode 100644 index 00000000..93726f76 --- /dev/null +++ b/internal/pkg/help/help.go @@ -0,0 +1,35 @@ +package help + +// UsageTemplate replaces the default usage template from cobra +const UsageTemplate string = `Usage: +{{if .Runnable}} {{.UseLine}} +{{end}}{{if .HasAvailableSubCommands}} {{.CommandPath}} COMMAND [OPTIONS] +{{end}}{{if gt (len .Aliases) 0}} +Aliases: + {{.NameAndAliases}} +{{end}}{{if .HasExample}} +Examples: + {{.Example}} +{{end}}{{if .HasAvailableSubCommands}} +Available Commands:{{range .Commands}}{{if (or .IsAvailableCommand (eq .Name "help"))}} + {{rpad .Name .NamePadding }} {{.Short}}{{end}}{{end}} +{{end}}{{if .HasAvailableLocalFlags}} +Options: +{{.LocalFlags.FlagUsages | trimTrailingWhitespaces}} +{{end}}{{if .HasAvailableInheritedFlags}} +Global Options: +{{.InheritedFlags.FlagUsages | trimTrailingWhitespaces}} +{{end}}{{if .HasHelpSubCommands}} +Additional help topics:{{range .Commands}}{{if .IsAdditionalHelpTopicCommand}} + {{rpad .CommandPath .CommandPathPadding}} {{.Short}}{{end}}{{end}} +{{end}}{{if .HasAvailableSubCommands}} +Use "{{.CommandPath}} COMMAND --help" for more information about a COMMAND. +{{end}} +` +// End UsageTemplate + +// HelpTemplate replaces the default help template from cobra +const HelpTemplate string = ` +{{with (or .Long .Short)}}{{. | trimTrailingWhitespaces}} +{{end}} +{{if or .Runnable .HasSubCommands}}{{.UsageString}}{{end}}` From 6bf8695951ec40eeafd59882c57ec07446d4275f Mon Sep 17 00:00:00 2001 From: Christian Goll Date: Tue, 9 Nov 2021 13:51:57 +0100 Subject: [PATCH 11/25] Adding '^' and '$' to serach string to avoid greedy regexp --- internal/pkg/node/methods.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/pkg/node/methods.go b/internal/pkg/node/methods.go index b2179a1d..bc5de819 100644 --- a/internal/pkg/node/methods.go +++ b/internal/pkg/node/methods.go @@ -14,7 +14,7 @@ func FilterByName(set []NodeInfo, searchList []string) []NodeInfo { if len(searchList) > 0 { for _, search := range searchList { for _, entry := range set { - b, _ := regexp.MatchString(search, entry.Id.Get()) + b, _ := regexp.MatchString("^"+search+"$", entry.Id.Get()) if b { ret = append(ret, entry) } From 5d729f5cc475225d8db9aaab177b3e2355f3a089 Mon Sep 17 00:00:00 2001 From: Christian Goll Date: Mon, 15 Nov 2021 10:03:27 +0100 Subject: [PATCH 12/25] updated .gitignore to ignore man pages --- .gitignore | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.gitignore b/.gitignore index 9bfa6313..e1845cba 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,7 @@ /wwctl /bash_completion /man_page + +# other created files +/usr/share/man/man1/ +/etc/bash_completion.d/ From 74da63d079810296d2b1389204c07a5d27f461c8 Mon Sep 17 00:00:00 2001 From: Christian Goll Date: Thu, 18 Nov 2021 16:27:57 +0100 Subject: [PATCH 13/25] set .conf files for man_page and bash_completion --- Makefile | 9 +++++++-- internal/pkg/node/constructors.go | 7 ++++--- internal/pkg/warewulfconf/datastructure.go | 2 +- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/Makefile b/Makefile index 66ff0636..d04f9d26 100644 --- a/Makefile +++ b/Makefile @@ -5,6 +5,7 @@ VERSION := 4.2.0 # auto installed tooling TOOLS_DIR := .tools TOOLS_BIN := $(TOOLS_DIR)/bin +CONFIG := $(shell pwd) # tools GO_TOOLS_BIN := $(addprefix $(TOOLS_BIN)/, $(notdir $(GO_TOOLS))) @@ -115,12 +116,16 @@ wwclient: cd cmd/wwclient; CGO_ENABLED=0 GOOS=linux go build -mod vendor -a -ldflags '-extldflags -static' -o ../../wwclient bash_completion: - cd cmd/bash_completion && go build -mod vendor -tags "$(WW_BUILD_GO_BUILD_TAGS)" -o ../../bash_completion + cd cmd/bash_completion && go build -ldflags="-X 'github.com/hpcng/warewulf/internal/pkg/warewulfconf.ConfigFile=$(CONFIG)/etc/warewulf.conf'\ + -X 'github.com/hpcng/warewulf/internal/pkg/node.ConfigFile=$(CONFIG)/etc/nodes.conf'"\ + -mod vendor -tags "$(WW_BUILD_GO_BUILD_TAGS)" -o ../../bash_completion install -d -m 0755 ./etc/bash_completion.d/ ./bash_completion ./etc/bash_completion.d/warewulf man_page: - cd cmd/man_page && go build -mod vendor -tags "$(WW_BUILD_GO_BUILD_TAGS)" -o ../../man_page + cd cmd/man_page && go build -ldflags="-X 'github.com/hpcng/warewulf/internal/pkg/warewulfconf.ConfigFile=$(CONFIG)/etc/warewulf.conf'\ + -X 'github.com/hpcng/warewulf/internal/pkg/node.ConfigFile=$(CONFIG)/etc/nodes.conf'"\ + -mod vendor -tags "$(WW_BUILD_GO_BUILD_TAGS)" -o ../../man_page install -d -m 0755 ./usr/share/man/man1 ./man_page ./usr/share/man/man1 gzip --force ./usr/share/man/man1/wwctl*1 diff --git a/internal/pkg/node/constructors.go b/internal/pkg/node/constructors.go index 27007dec..92c18107 100644 --- a/internal/pkg/node/constructors.go +++ b/internal/pkg/node/constructors.go @@ -3,14 +3,15 @@ package node import ( "errors" "fmt" - "github.com/hpcng/warewulf/internal/pkg/wwlog" - "gopkg.in/yaml.v2" "io/ioutil" "sort" "strings" + + "github.com/hpcng/warewulf/internal/pkg/wwlog" + "gopkg.in/yaml.v2" ) -const ConfigFile = "/etc/warewulf/nodes.conf" +var ConfigFile = "/etc/warewulf/nodes.conf" func New() (nodeYaml, error) { var ret nodeYaml diff --git a/internal/pkg/warewulfconf/datastructure.go b/internal/pkg/warewulfconf/datastructure.go index 8315ddd6..d47670ec 100644 --- a/internal/pkg/warewulfconf/datastructure.go +++ b/internal/pkg/warewulfconf/datastructure.go @@ -5,7 +5,7 @@ import ( "github.com/hpcng/warewulf/internal/pkg/wwlog" ) -const ConfigFile = "/etc/warewulf/warewulf.conf" +var ConfigFile = "/etc/warewulf/warewulf.conf" type ControllerConf struct { Comment string `yaml:"comment"` From bd5218a7c75e41ffe5d19a8216dd64bf1425b8cf Mon Sep 17 00:00:00 2001 From: griznog Date: Tue, 23 Nov 2021 10:44:35 -0600 Subject: [PATCH 14/25] Add Id and Cluster to the available variables for template substitution. --- internal/pkg/warewulfd/ipxe.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/internal/pkg/warewulfd/ipxe.go b/internal/pkg/warewulfd/ipxe.go index f8a57dc9..e6626370 100644 --- a/internal/pkg/warewulfd/ipxe.go +++ b/internal/pkg/warewulfd/ipxe.go @@ -18,6 +18,8 @@ type iPxeTemplate struct { WaitTime string Hostname string Fqdn string + Id string + Cluster string ContainerName string Hwaddr string Ipaddr string @@ -129,6 +131,8 @@ func IpxeSend(w http.ResponseWriter, req *http.Request) { var replace iPxeTemplate + replace.Id = nodeobj.Id.Get() + replace.Cluster = nodeobj.Cluster.Get() replace.Fqdn = nodeobj.Id.Get() replace.Ipaddr = conf.Ipaddr replace.Port = strconv.Itoa(conf.Warewulf.Port) From 7f56463c633ca36697db476f7f2a333c6df2daca Mon Sep 17 00:00:00 2001 From: griznog Date: Tue, 23 Nov 2021 12:59:36 -0600 Subject: [PATCH 15/25] Had the wrong name for Cluster. --- internal/pkg/warewulfd/ipxe.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/pkg/warewulfd/ipxe.go b/internal/pkg/warewulfd/ipxe.go index e6626370..2eec83ec 100644 --- a/internal/pkg/warewulfd/ipxe.go +++ b/internal/pkg/warewulfd/ipxe.go @@ -132,7 +132,7 @@ func IpxeSend(w http.ResponseWriter, req *http.Request) { var replace iPxeTemplate replace.Id = nodeobj.Id.Get() - replace.Cluster = nodeobj.Cluster.Get() + replace.Cluster = nodeobj.ClusterName.Get() replace.Fqdn = nodeobj.Id.Get() replace.Ipaddr = conf.Ipaddr replace.Port = strconv.Itoa(conf.Warewulf.Port) From 300070c3bcba22449a02f2c3000358e631f1a7b3 Mon Sep 17 00:00:00 2001 From: Niko Kivel Date: Thu, 25 Nov 2021 22:49:19 +0100 Subject: [PATCH 16/25] install `wwclient` for all system overlays --- Makefile | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 66ff0636..f88cc2db 100644 --- a/Makefile +++ b/Makefile @@ -19,6 +19,10 @@ export GOPROXY # built tags needed for wwbuild binary WW_BUILD_GO_BUILD_TAGS := containers_image_openpgp containers_image_ostree +# system-overlay directories for install_wwclient +OVERLAY_DIR ?= $(DESTDIR)/var/warewulf/overlays/system/ +overlays = ${dir ${wildcard ${OVERLAY_DIR}*/}} + all: vendor wwctl wwclient bash_completion man_page build: lint test-it vet all @@ -87,7 +91,6 @@ files: all chmod 600 $(DESTDIR)/var/warewulf/overlays/system/default/etc/ssh/ssh* chmod 644 $(DESTDIR)/var/warewulf/overlays/system/default/etc/ssh/ssh*.pub.ww mkdir -p $(DESTDIR)/var/warewulf/overlays/system/default/warewulf/bin/ - cp wwclient $(DESTDIR)/var/warewulf/overlays/system/default/warewulf/bin/ cp wwctl $(DESTDIR)/usr/bin/ mkdir -p $(DESTDIR)/usr/lib/firewalld/services install -c -m 0644 include/firewalld/warewulf.xml $(DESTDIR)/usr/lib/firewalld/services @@ -114,6 +117,9 @@ wwctl: wwclient: cd cmd/wwclient; CGO_ENABLED=0 GOOS=linux go build -mod vendor -a -ldflags '-extldflags -static' -o ../../wwclient +install_wwclient: wwclient + $(foreach overlay, ${overlays}, install -D -m 0755 wwclient ${overlay}warewulf/bin/wwclient;) + bash_completion: cd cmd/bash_completion && go build -mod vendor -tags "$(WW_BUILD_GO_BUILD_TAGS)" -o ../../bash_completion install -d -m 0755 ./etc/bash_completion.d/ @@ -141,7 +147,7 @@ clean: rm -f bash_completion rm -f man_page -install: files +install: files install_wwclient debinstall: files debfiles From 32e0de5a0f731aa31742c8e00f110952cadaacea Mon Sep 17 00:00:00 2001 From: Christian Goll Date: Mon, 4 Oct 2021 17:10:33 +0200 Subject: [PATCH 17/25] added version information --- Makefile | 2 +- internal/app/wwctl/root.go | 2 ++ internal/app/wwctl/version/main.go | 16 ++++++++++++++++ internal/app/wwctl/version/root.go | 22 ++++++++++++++++++++++ 4 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 internal/app/wwctl/version/main.go create mode 100644 internal/app/wwctl/version/root.go diff --git a/Makefile b/Makefile index 3903dab4..fc5c6c7c 100644 --- a/Makefile +++ b/Makefile @@ -115,7 +115,7 @@ debfiles: debian cp wwclient $(DESTDIR)/var/warewulf/overlays/system/debian/warewulf/bin/ wwctl: - cd cmd/wwctl; GOOS=linux go build -mod vendor -tags "$(WW_BUILD_GO_BUILD_TAGS)" -o ../../wwctl + cd cmd/wwctl; GOOS=linux go build -ldflags="-X 'github.com/hpcng/warewulf/internal/app/wwctl/version/version.Version=$(VERSION)'" -mod vendor -tags "$(WW_BUILD_GO_BUILD_TAGS)" -o ../../wwctl wwclient: cd cmd/wwclient; CGO_ENABLED=0 GOOS=linux go build -mod vendor -a -ldflags '-extldflags -static' -o ../../wwclient diff --git a/internal/app/wwctl/root.go b/internal/app/wwctl/root.go index 10437f80..059b38db 100644 --- a/internal/app/wwctl/root.go +++ b/internal/app/wwctl/root.go @@ -9,6 +9,7 @@ import ( "github.com/hpcng/warewulf/internal/app/wwctl/power" "github.com/hpcng/warewulf/internal/app/wwctl/profile" "github.com/hpcng/warewulf/internal/app/wwctl/server" + "github.com/hpcng/warewulf/internal/app/wwctl/version" "github.com/hpcng/warewulf/internal/pkg/wwlog" "github.com/hpcng/warewulf/internal/pkg/help" "github.com/spf13/cobra" @@ -46,6 +47,7 @@ func init() { rootCmd.AddCommand(profile.GetCommand()) rootCmd.AddCommand(configure.GetCommand()) rootCmd.AddCommand(server.GetCommand()) + rootCmd.AddCommand(version.GetCommand()) } diff --git a/internal/app/wwctl/version/main.go b/internal/app/wwctl/version/main.go new file mode 100644 index 00000000..0658e986 --- /dev/null +++ b/internal/app/wwctl/version/main.go @@ -0,0 +1,16 @@ +package version + +import ( + "fmt" + + "github.com/spf13/cobra" +) + +var Version = "development" + +func CobraRunE(cmd *cobra.Command, args []string) error { + + fmt.Println("Version foo:\t", Version) + + return nil +} diff --git a/internal/app/wwctl/version/root.go b/internal/app/wwctl/version/root.go new file mode 100644 index 00000000..766d3b8f --- /dev/null +++ b/internal/app/wwctl/version/root.go @@ -0,0 +1,22 @@ +package version + +import "github.com/spf13/cobra" + +var ( + baseCmd = &cobra.Command{ + Use: "version", + Short: "Version information", + Long: "This command will print the Warewulf version.", + RunE: CobraRunE, + Args: cobra.ExactArgs(0), + Aliases: []string{"vers"}, + } +) + +func init() { +} + +// GetRootCommand returns the root cobra.Command for the application. +func GetCommand() *cobra.Command { + return baseCmd +} From 58c6adaff46ddc10935fddc646fe4a85cc3838d5 Mon Sep 17 00:00:00 2001 From: Christian Goll Date: Mon, 4 Oct 2021 19:23:11 +0200 Subject: [PATCH 18/25] using right syntax in Makefile --- Makefile | 8 +++++++- internal/app/wwctl/version/main.go | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index fc5c6c7c..f772eec3 100644 --- a/Makefile +++ b/Makefile @@ -5,6 +5,12 @@ RELEASE ?= 1 SRC ?= main +VERSION_FULL ?= $(shell test -e .git && git describe --tags --long) +ifeq ($(VERSION_FULL),) +VERSION_FULL := $(VERSION) +endif + + # auto installed tooling TOOLS_DIR := .tools TOOLS_BIN := $(TOOLS_DIR)/bin @@ -115,7 +121,7 @@ debfiles: debian cp wwclient $(DESTDIR)/var/warewulf/overlays/system/debian/warewulf/bin/ wwctl: - cd cmd/wwctl; GOOS=linux go build -ldflags="-X 'github.com/hpcng/warewulf/internal/app/wwctl/version/version.Version=$(VERSION)'" -mod vendor -tags "$(WW_BUILD_GO_BUILD_TAGS)" -o ../../wwctl + cd cmd/wwctl; GOOS=linux go build -ldflags="-X 'github.com/hpcng/warewulf/internal/app/wwctl/version.Version=$(VERSION_FULL)'" -mod vendor -tags "$(WW_BUILD_GO_BUILD_TAGS)" -o ../../wwctl wwclient: cd cmd/wwclient; CGO_ENABLED=0 GOOS=linux go build -mod vendor -a -ldflags '-extldflags -static' -o ../../wwclient diff --git a/internal/app/wwctl/version/main.go b/internal/app/wwctl/version/main.go index 0658e986..f977b662 100644 --- a/internal/app/wwctl/version/main.go +++ b/internal/app/wwctl/version/main.go @@ -10,7 +10,7 @@ var Version = "development" func CobraRunE(cmd *cobra.Command, args []string) error { - fmt.Println("Version foo:\t", Version) + fmt.Println("Version:\t", Version) return nil } From 0a6d8b39a6151310efdf98fc684396aa47bd6692 Mon Sep 17 00:00:00 2001 From: Christian Goll Date: Thu, 7 Oct 2021 11:01:59 +0200 Subject: [PATCH 19/25] on server start print version info --- Makefile | 2 +- internal/app/wwctl/version/main.go | 5 ++--- internal/pkg/version/version.go | 7 +++++++ internal/pkg/warewulfd/daemon.go | 3 ++- 4 files changed, 12 insertions(+), 5 deletions(-) create mode 100644 internal/pkg/version/version.go diff --git a/Makefile b/Makefile index f772eec3..d431dbeb 100644 --- a/Makefile +++ b/Makefile @@ -121,7 +121,7 @@ debfiles: debian cp wwclient $(DESTDIR)/var/warewulf/overlays/system/debian/warewulf/bin/ wwctl: - cd cmd/wwctl; GOOS=linux go build -ldflags="-X 'github.com/hpcng/warewulf/internal/app/wwctl/version.Version=$(VERSION_FULL)'" -mod vendor -tags "$(WW_BUILD_GO_BUILD_TAGS)" -o ../../wwctl + cd cmd/wwctl; GOOS=linux go build -ldflags="-X 'github.com/hpcng/warewulf/internal/pkg/version.Version=$(VERSION_FULL)'" -mod vendor -tags "$(WW_BUILD_GO_BUILD_TAGS)" -o ../../wwctl wwclient: cd cmd/wwclient; CGO_ENABLED=0 GOOS=linux go build -mod vendor -a -ldflags '-extldflags -static' -o ../../wwclient diff --git a/internal/app/wwctl/version/main.go b/internal/app/wwctl/version/main.go index f977b662..08e48d09 100644 --- a/internal/app/wwctl/version/main.go +++ b/internal/app/wwctl/version/main.go @@ -3,14 +3,13 @@ package version import ( "fmt" + "github.com/hpcng/warewulf/internal/pkg/version" "github.com/spf13/cobra" ) -var Version = "development" - func CobraRunE(cmd *cobra.Command, args []string) error { - fmt.Println("Version:\t", Version) + fmt.Println("Version:\t", version.GetVersion()) return nil } diff --git a/internal/pkg/version/version.go b/internal/pkg/version/version.go new file mode 100644 index 00000000..0e8e1a5a --- /dev/null +++ b/internal/pkg/version/version.go @@ -0,0 +1,7 @@ +package version + +var Version string = "development" + +func GetVersion() string { + return Version +} diff --git a/internal/pkg/warewulfd/daemon.go b/internal/pkg/warewulfd/daemon.go index 042808d0..acb04ac8 100644 --- a/internal/pkg/warewulfd/daemon.go +++ b/internal/pkg/warewulfd/daemon.go @@ -9,6 +9,7 @@ import ( "syscall" "github.com/hpcng/warewulf/internal/pkg/util" + "github.com/hpcng/warewulf/internal/pkg/version" "github.com/pkg/errors" ) @@ -53,7 +54,7 @@ func DaemonStart() error { fmt.Fprintf(p, "%d", pid) - fmt.Printf("Started Warewulf server at PID: %d\n", pid) + fmt.Printf("Started Warewulf (%s) server at PID: %d\n", version.GetVersion(), pid) } From 2a6ba9799244cf00a6c7269f5ca81e57d55117eb Mon Sep 17 00:00:00 2001 From: Christian Goll Date: Mon, 8 Nov 2021 09:30:08 +0100 Subject: [PATCH 20/25] using --first-parent option to describe git version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index d431dbeb..a8c28836 100644 --- a/Makefile +++ b/Makefile @@ -5,7 +5,7 @@ RELEASE ?= 1 SRC ?= main -VERSION_FULL ?= $(shell test -e .git && git describe --tags --long) +VERSION_FULL ?= $(shell test -e .git && git describe --tags --long --first-parent) ifeq ($(VERSION_FULL),) VERSION_FULL := $(VERSION) endif From a1619e2d0345d07f83e82291bd0a4edb734df5bc Mon Sep 17 00:00:00 2001 From: jcsiadal Date: Sat, 4 Dec 2021 01:47:14 +0000 Subject: [PATCH 21/25] Fix misspelled command Signed-off-by: jcsiadal --- internal/app/wwctl/container/imprt/root.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/app/wwctl/container/imprt/root.go b/internal/app/wwctl/container/imprt/root.go index 94772821..061c0efe 100644 --- a/internal/app/wwctl/container/imprt/root.go +++ b/internal/app/wwctl/container/imprt/root.go @@ -5,7 +5,7 @@ import "github.com/spf13/cobra" var ( baseCmd = &cobra.Command{ DisableFlagsInUseLine: true, - Use: "imprt [OPTIONS] SOURCE [NAME]", + Use: "import [OPTIONS] SOURCE [NAME]", Short: "Import a container into Warewulf", Long: `This command will pull and import a container into Warewulf from SOURCE, From f47d2cedb9c55187e1515417da230df85241b415 Mon Sep 17 00:00:00 2001 From: Christian Goll Date: Mon, 6 Dec 2021 09:54:02 +0100 Subject: [PATCH 22/25] add bash completion for node list --- internal/app/wwctl/node/list/root.go | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/internal/app/wwctl/node/list/root.go b/internal/app/wwctl/node/list/root.go index e9c78d6c..b354c881 100644 --- a/internal/app/wwctl/node/list/root.go +++ b/internal/app/wwctl/node/list/root.go @@ -1,16 +1,32 @@ package list -import "github.com/spf13/cobra" +import ( + "github.com/hpcng/warewulf/internal/pkg/node" + "github.com/spf13/cobra" +) var ( baseCmd = &cobra.Command{ DisableFlagsInUseLine: true, - Use: "list [OPTIONS] [PATTERN]", - Short: "List nodes", - Long: "This command lists all configured nodes. Optionally, it will list only\n" + - "nodes matching a glob PATTERN.", + Use: "list [OPTIONS] [PATTERN]", + Short: "List nodes", + Long: "This command lists all configured nodes. Optionally, it will list only\n" + + "nodes matching a glob PATTERN.", RunE: CobraRunE, Aliases: []string{"ls"}, + ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) != 0 { + return nil, cobra.ShellCompDirectiveNoFileComp + } + + nodeDB, _ := node.New() + nodes, _ := nodeDB.FindAllNodes() + var node_names []string + for _, node := range nodes { + node_names = append(node_names, node.Id.Get()) + } + return node_names, cobra.ShellCompDirectiveNoFileComp + }, } ShowNet bool ShowIpmi bool From 3957ffb2c9e685708e478660d7d07f144b02afeb Mon Sep 17 00:00:00 2001 From: "Michael L. Young" Date: Mon, 6 Dec 2021 14:25:45 -0500 Subject: [PATCH 23/25] ipmi: Fix log output, set IMPI port on profile and settings for console - Fix the logs to reference the correct IPMI setting that is being set. - Add setting the IPMI port at a profile level. - Apply all IPMI settings when preparing to us the console. Closes #225 --- internal/app/wwctl/node/console/power.go | 12 +++++++----- internal/app/wwctl/profile/set/main.go | 13 +++++++++---- internal/app/wwctl/profile/set/root.go | 4 +++- 3 files changed, 19 insertions(+), 10 deletions(-) diff --git a/internal/app/wwctl/node/console/power.go b/internal/app/wwctl/node/console/power.go index 9332edb7..aa9fcfa7 100644 --- a/internal/app/wwctl/node/console/power.go +++ b/internal/app/wwctl/node/console/power.go @@ -49,11 +49,13 @@ func CobraRunE(cmd *cobra.Command, args []string) error { } ipmiCmd := power.IPMI{ - NodeName: node.Id.Get(), - HostName: node.IpmiIpaddr.Get(), - User: node.IpmiUserName.Get(), - Password: node.IpmiPassword.Get(), - AuthType: "MD5", + NodeName: node.Id.Get(), + HostName: node.IpmiIpaddr.Get(), + Port: node.IpmiPort.Get(), + User: node.IpmiUserName.Get(), + Password: node.IpmiPassword.Get(), + AuthType: "MD5", + Interface: node.IpmiInterface.Get(), } err := ipmiCmd.Console() diff --git a/internal/app/wwctl/profile/set/main.go b/internal/app/wwctl/profile/set/main.go index 667111f7..74d128bd 100644 --- a/internal/app/wwctl/profile/set/main.go +++ b/internal/app/wwctl/profile/set/main.go @@ -96,12 +96,17 @@ func CobraRunE(cmd *cobra.Command, args []string) error { } if SetIpmiNetmask != "" { - wwlog.Printf(wwlog.VERBOSE, "Profile: %s, Setting IPMI username to: %s\n", p.Id.Get(), SetIpmiNetmask) + wwlog.Printf(wwlog.VERBOSE, "Profile: %s, Setting IPMI netmask to: %s\n", p.Id.Get(), SetIpmiNetmask) p.IpmiNetmask.Set(SetIpmiNetmask) } + if SetIpmiPort != "" { + wwlog.Printf(wwlog.VERBOSE, "Profile: %s, Setting IPMI port to: %s\n", p.Id.Get(), SetIpmiPort) + p.IpmiPort.Set(SetIpmiPort) + } + if SetIpmiGateway != "" { - wwlog.Printf(wwlog.VERBOSE, "Profile: %s, Setting IPMI username to: %s\n", p.Id.Get(), SetIpmiGateway) + wwlog.Printf(wwlog.VERBOSE, "Profile: %s, Setting IPMI gateway to: %s\n", p.Id.Get(), SetIpmiGateway) p.IpmiGateway.Set(SetIpmiGateway) } @@ -111,12 +116,12 @@ func CobraRunE(cmd *cobra.Command, args []string) error { } if SetIpmiPassword != "" { - wwlog.Printf(wwlog.VERBOSE, "Profile: %s, Setting IPMI username to: %s\n", p.Id.Get(), SetIpmiPassword) + wwlog.Printf(wwlog.VERBOSE, "Profile: %s, Setting IPMI password to: %s\n", p.Id.Get(), SetIpmiPassword) p.IpmiPassword.Set(SetIpmiPassword) } if SetIpmiInterface != "" { - wwlog.Printf(wwlog.VERBOSE, "Profile: %s, Setting IPMI username to: %s\n", p.Id.Get(), SetIpmiInterface) + wwlog.Printf(wwlog.VERBOSE, "Profile: %s, Setting IPMI interface to: %s\n", p.Id.Get(), SetIpmiInterface) p.IpmiInterface.Set(SetIpmiInterface) } diff --git a/internal/app/wwctl/profile/set/root.go b/internal/app/wwctl/profile/set/root.go index 3bbccf73..392c1476 100644 --- a/internal/app/wwctl/profile/set/root.go +++ b/internal/app/wwctl/profile/set/root.go @@ -44,6 +44,7 @@ var ( SetRuntimeOverlay string SetSystemOverlay string SetIpmiNetmask string + SetIpmiPort string SetIpmiGateway string SetIpmiUsername string SetIpmiPassword string @@ -103,10 +104,11 @@ func init() { log.Println(err) } baseCmd.PersistentFlags().StringVar(&SetIpmiNetmask, "ipminetmask", "", "Set the node's IPMI netmask") + baseCmd.PersistentFlags().StringVar(&SetIpmiPort, "ipmiport", "", "Set the node's IPMI port") baseCmd.PersistentFlags().StringVar(&SetIpmiGateway, "ipmigateway", "", "Set the node's IPMI gateway") baseCmd.PersistentFlags().StringVar(&SetIpmiUsername, "ipmiuser", "", "Set the node's IPMI username") baseCmd.PersistentFlags().StringVar(&SetIpmiPassword, "ipmipass", "", "Set the node's IPMI password") - baseCmd.PersistentFlags().StringVar(&SetIpmiInterface, "ipmiinterface", "", "Set the node's IPMI interface (defaults to 'lan' if empty)") + baseCmd.PersistentFlags().StringVar(&SetIpmiInterface, "ipmiinterface", "", "Set the node's IPMI interface (defaults to 'lan')") baseCmd.PersistentFlags().StringVarP(&SetNetDev, "netdev", "N", "", "Define the network device to configure") baseCmd.PersistentFlags().StringVarP(&SetIpaddr, "ipaddr", "I", "", "Set the node's network device IP address") From 23fb20637fb74b3b7dd8bc5096accbe583ee93c8 Mon Sep 17 00:00:00 2001 From: "Michael L. Young" Date: Tue, 7 Dec 2021 09:56:35 -0500 Subject: [PATCH 24/25] Fix displaying IPMI settings when listing profiles Remove displaying the IPMI ip address field when looking at all the settings in a profile since this is not set in the profile, only on the node level. --- internal/app/wwctl/profile/list/main.go | 1 - 1 file changed, 1 deletion(-) diff --git a/internal/app/wwctl/profile/list/main.go b/internal/app/wwctl/profile/list/main.go index f43a2046..a549abd7 100644 --- a/internal/app/wwctl/profile/list/main.go +++ b/internal/app/wwctl/profile/list/main.go @@ -41,7 +41,6 @@ func CobraRunE(cmd *cobra.Command, args []string) error { fmt.Printf("%-20s %-18s %s\n", profile.Id.Get(), "RuntimeOverlay", profile.RuntimeOverlay.Print()) fmt.Printf("%-20s %-18s %s\n", profile.Id.Get(), "SystemOverlay", profile.SystemOverlay.Print()) fmt.Printf("%-20s %-18s %s\n", profile.Id.Get(), "Ipxe", profile.Ipxe.Print()) - fmt.Printf("%-20s %-18s %s\n", profile.Id.Get(), "IpmiIpaddr", profile.IpmiIpaddr.Print()) fmt.Printf("%-20s %-18s %s\n", profile.Id.Get(), "IpmiNetmask", profile.IpmiNetmask.Print()) fmt.Printf("%-20s %-18s %s\n", profile.Id.Get(), "IpmiPort", profile.IpmiPort.Print()) fmt.Printf("%-20s %-18s %s\n", profile.Id.Get(), "IpmiGateway", profile.IpmiGateway.Print()) From 12ee1061cfd778a5950408fa0316bd6af8ed1ae2 Mon Sep 17 00:00:00 2001 From: "Michael L. Young" Date: Tue, 7 Dec 2021 10:35:22 -0500 Subject: [PATCH 25/25] Add some spacing around the IPMI port column --- internal/app/wwctl/node/list/main.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/internal/app/wwctl/node/list/main.go b/internal/app/wwctl/node/list/main.go index 31b81eba..0a392862 100644 --- a/internal/app/wwctl/node/list/main.go +++ b/internal/app/wwctl/node/list/main.go @@ -84,11 +84,11 @@ func CobraRunE(cmd *cobra.Command, args []string) error { } } else if ShowIpmi { - fmt.Printf("%-22s %-16s %-5s %-20s %-20s %-20s\n", "NODE NAME", "IPMI IPADDR", "IPMI PORT", "IPMI USERNAME", "IPMI PASSWORD", "IPMI INTERFACE") - fmt.Println(strings.Repeat("=", 80)) + fmt.Printf("%-22s %-16s %-10s %-20s %-20s %-14s\n", "NODE NAME", "IPMI IPADDR", "IPMI PORT", "IPMI USERNAME", "IPMI PASSWORD", "IPMI INTERFACE") + fmt.Println(strings.Repeat("=", 108)) for _, node := range node.FilterByName(nodes, args) { - fmt.Printf("%-22s %-16s %-5s %-20s %-20s %-20s\n", node.Id.Get(), node.IpmiIpaddr.Print(), node.IpmiPort.Print(), node.IpmiUserName.Print(), node.IpmiPassword.Print(), node.IpmiInterface.Print()) + fmt.Printf("%-22s %-16s %-10s %-20s %-20s %-14s\n", node.Id.Get(), node.IpmiIpaddr.Print(), node.IpmiPort.Print(), node.IpmiUserName.Print(), node.IpmiPassword.Print(), node.IpmiInterface.Print()) } } else if ShowLong {