Files
warewulf/Makefile
MatthewHink d8cd6049ac Initial cut of wwapi.
We need an API for Warewulf in order to automate around it. The initial version of the API will look a lot like wwctl. wwctl will call the API so that we do not need to maintain separate code paths. In this preview wwctl calls the API via direct function call, but we can change that to a gprc or REST call to a Warewulf server in the future.

This commit contains:
wwapid WareWulf API Daemon. A grpc server with mTLS auth.
wwapic WareWulf API Client. A grpc client with mTLS auth. It's just a sample that reads the version from the server.
wwapird WareWulf API Rest Daemon. A http REST reverse proxy to wwapid.
There are also sample insecure and secure curls to test with.

Implemented Functionality:
wwctl node add
wwctl node delete
wwctl node list
wwctl node set
wwctl node status
wwctl container build
wwctl container delete
wwctl container import
wwctl container list
wwctl container show

Some notes on the files:

    Logic that was in wwctl has moved to warewulf/internal/pkg/api. wwctl just calls the API. wwctl functionality is unchanged.
    Everything under the /google directory is copied google proto code to stand up wwapird. It's a bit strange to copy in the code, but that is currently how it's done.
    Everything in warewulf/internal/pkg/api/routes/wwapiv1 is generated code.

There are some loose ends here, such as no service installers. I just ran off the command line for development.
The Makefile could use improvement. I'm building by make clean setup proto all build wwapid wwapic wwapird ; echo $?
I copied the configs from warewulf/etc to /usr/local/etc/warewulf manually.
2022-06-24 08:39:30 -07:00

299 lines
10 KiB
Makefile

.PHONY: all
-include Defaults.mk
# Linux distro (try and set to /etc/os-release ID)
OS_REL := $(shell sed -n "s/^ID\s*=\s*['"\""]\(.*\)['"\""]/\1/p" /etc/os-release)
OS ?= $(OS_REL)
# List of variables to save and replace in files
VARLIST := OS
# Project Information
VARLIST += WAREWULF VERSION RELEASE
WAREWULF ?= warewulf
VERSION ?= 4.3.0
GIT_TAG := $(shell test -e .git && git log -1 --format="%h")
ifdef GIT_TAG
ifdef $(filter $(OS),ubuntu debian)
RELEASE ?= 1.git_$(subst -,+,$(GIT_TAG))
else
RELEASE ?= 1.git_$(subst -,_,$(GIT_TAG))
endif
else
RELEASE ?= 1
endif
# Use LSB-compliant paths if OS is known
ifneq ($(OS),)
USE_LSB_PATHS := true
endif
# Always default to GNU autotools default paths if PREFIX has been redefined
ifdef PREFIX
USE_LSB_PATHS := false
endif
# System directory paths
VARLIST += PREFIX BINDIR SYSCONFDIR SRVDIR DATADIR MANDIR DOCDIR LOCALSTATEDIR
PREFIX ?= /usr/local
BINDIR ?= $(PREFIX)/bin
SYSCONFDIR ?= $(PREFIX)/etc
DATADIR ?= $(PREFIX)/share
MANDIR ?= $(DATADIR)/man
DOCDIR ?= $(DATADIR)/doc
ifeq ($(USE_LSB_PATHS),true)
SRVDIR ?= /srv
LOCALSTATEDIR ?= /var/local
else
SRVDIR ?= $(PREFIX)/srv
LOCALSTATEDIR ?= $(PREFIX)/var
endif
# OS-Specific Service Locations
VARLIST += TFTPDIR FIREWALLDDIR SYSTEMDDIR
SYSTEMDDIR ?= /usr/lib/systemd/system
BASHCOMPDIR ?= /etc/bash_completion.d
FIREWALLDDIR ?= /usr/lib/firewalld/services
ifeq ($(OS),suse)
TFTPDIR ?= /srv/tftpboot
endif
ifeq ($(OS),ubuntu)
TFTPDIR ?= /srv/tftp
endif
# Default to Red Hat / Rocky Linux
TFTPDIR ?= /var/lib/tftpboot
# Warewulf directory paths
VARLIST += WWCLIENTDIR WWCONFIGDIR WWPROVISIONDIR WWOVERLAYDIR WWCHROOTDIR WWTFTPDIR WWDOCDIR WWDATADIR
WWCONFIGDIR := $(SYSCONFDIR)/$(WAREWULF)
WWPROVISIONDIR := $(SRVDIR)/$(WAREWULF)
WWOVERLAYDIR := $(LOCALSTATEDIR)/$(WAREWULF)/overlays
WWCHROOTDIR := $(LOCALSTATEDIR)/$(WAREWULF)/chroots
WWTFTPDIR := $(TFTPDIR)/$(WAREWULF)
WWDOCDIR := $(DOCDIR)/$(WAREWULF)
WWDATADIR := $(DATADIR)/$(WAREWULF)
WWCLIENTDIR ?= /warewulf
# auto installed tooling
TOOLS_DIR := .tools
TOOLS_BIN := $(TOOLS_DIR)/bin
CONFIG := $(shell pwd)
# tools
GO_TOOLS_BIN := $(addprefix $(TOOLS_BIN)/, $(notdir $(GO_TOOLS)))
GO_TOOLS_VENDOR := $(addprefix vendor/, $(GO_TOOLS))
GOLANGCI_LINT := $(TOOLS_BIN)/golangci-lint
GOLANGCI_LINT_VERSION := v1.45.2
# use GOPROXY for older git clients and speed up downloads
GOPROXY ?= https://proxy.golang.org
export GOPROXY
# built tags needed for wwbuild binary
WW_GO_BUILD_TAGS := containers_image_openpgp containers_image_ostree
all: config vendor wwctl wwclient bash_completion.d man_pages config_defaults wwapid wwapic wwapird
build: lint test-it vet all
# set the go tools into the tools bin.
setup_tools: $(GO_TOOLS_BIN) $(GOLANGCI_LINT)
# install go tools into TOOLS_BIN
$(GO_TOOLS_BIN):
@GOBIN="$(PWD)/$(TOOLS_BIN)" go install -mod=vendor $(GO_TOOLS)
# install golangci-lint into TOOLS_BIN
$(GOLANGCI_LINT):
@curl -qq -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(TOOLS_BIN) $(GOLANGCI_LINT_VERSION)
setup: vendor $(TOOLS_DIR) setup_tools
vendor:
go mod tidy -v
go mod vendor
$(TOOLS_DIR):
@mkdir -p $@
# Pre-build steps for source, such as "go generate"
config:
# Store configuration for subsequent runs
printf " $(foreach V,$(VARLIST),$V := $(strip $($V))\n)" > Defaults.mk
# Global variable search and replace for all *.in files
find . -type f -name "*.in" -not -path "./vendor/*" \
-exec sh -c 'sed -ne "$(foreach V,$(VARLIST),s,@$V@,$(strip $($V)),g;)p" $${0} > $${0%.in}' {} \;
touch config
rm_config:
rm -f config
genconfig: rm_config config
# Lint
lint: setup_tools
@echo Running golangci-lint...
@$(GOLANGCI_LINT) run --build-tags "$(WW_GO_BUILD_TAGS)" --skip-dirs internal/pkg/staticfiles ./...
vet:
go vet ./...
test-it:
go test -v ./... -ldflags="-X 'github.com/hpcng/warewulf/internal/pkg/warewulfconf.ConfigFile=$(shell pwd)/etc/warewulf.conf'"
# 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
install -d -m 0755 $(DESTDIR)$(BINDIR)
install -d -m 0755 $(DESTDIR)$(WWCHROOTDIR)
install -d -m 0755 $(DESTDIR)$(WWPROVISIONDIR)
install -d -m 0755 $(DESTDIR)$(WWOVERLAYDIR)/wwinit/$(WWCLIENTDIR)
install -d -m 0755 $(DESTDIR)$(WWCONFIGDIR)/ipxe
install -d -m 0755 $(DESTDIR)$(BASHCOMPDIR)
install -d -m 0755 $(DESTDIR)$(MANDIR)/man1
install -d -m 0755 $(DESTDIR)$(WWDOCDIR)
install -d -m 0755 $(DESTDIR)$(FIREWALLDDIR)
install -d -m 0755 $(DESTDIR)$(SYSTEMDDIR)
install -d -m 0755 $(DESTDIR)$(WWDATADIR)/ipxe
test -f $(DESTDIR)$(WWCONFIGDIR)/warewulf.conf || install -m 644 etc/warewulf.conf $(DESTDIR)$(WWCONFIGDIR)
test -f $(DESTDIR)$(WWCONFIGDIR)/nodes.conf || install -m 644 etc/nodes.conf $(DESTDIR)$(WWCONFIGDIR)
test -f $(DESTDIR)$(SYSCONFDIR)/warewulf/wwapic.conf || install -m 644 etc/wwapic.conf $(DESTDIR)$(SYSCONFDIR)/warewulf/
test -f $(DESTDIR)$(SYSCONFDIR)/warewulf/wwapid.conf || install -m 644 etc/wwapid.conf $(DESTDIR)$(SYSCONFDIR)/warewulf/
test -f $(DESTDIR)$(SYSCONFDIR)/warewulf/wwapird.conf || install -m 644 etc/wwapird.conf $(DESTDIR)$(SYSCONFDIR)/warewulf/
cp -r etc/examples $(DESTDIR)$(WWCONFIGDIR)/
cp -r etc/ipxe $(DESTDIR)$(WWCONFIGDIR)/
cp -r overlays/* $(DESTDIR)$(WWOVERLAYDIR)/
chmod 755 $(DESTDIR)$(WWOVERLAYDIR)/wwinit/init
find $(DESTDIR)$(WWOVERLAYDIR) -type f -name "*.in" -exec rm -f {} \;
chmod 755 $(DESTDIR)$(WWOVERLAYDIR)/wwinit/$(WWCLIENTDIR)/wwinit
chmod 600 $(DESTDIR)$(WWOVERLAYDIR)/wwinit/etc/ssh/ssh*
chmod 644 $(DESTDIR)$(WWOVERLAYDIR)/wwinit/etc/ssh/ssh*.pub.ww
chmod 750 $(DESTDIR)$(WWOVERLAYDIR)/host
install -m 0755 wwctl $(DESTDIR)$(BINDIR)
install -m 0755 wwapic $(DESTDIR)$(BINDIR)
install -m 0755 wwapid $(DESTDIR)$(BINDIR)
install -m 0755 wwapird $(DESTDIR)$(BINDIR)
install -m 0644 include/firewalld/warewulf.xml $(DESTDIR)$(FIREWALLDDIR)
install -m 0644 include/systemd/warewulfd.service $(DESTDIR)$(SYSTEMDDIR)
install -m 0644 LICENSE.md $(DESTDIR)$(WWDOCDIR)
cp bash_completion.d/warewulf $(DESTDIR)$(BASHCOMPDIR)
cp man_pages/* $(DESTDIR)$(MANDIR)/man1/
install -m 0644 staticfiles/arm64.efi $(DESTDIR)$(WWDATADIR)/ipxe
install -m 0644 staticfiles/x86_64.efi $(DESTDIR)$(WWDATADIR)/ipxe
install -m 0644 staticfiles/x86_64.kpxe $(DESTDIR)$(WWDATADIR)/ipxe
init:
systemctl daemon-reload
cp -r tftpboot/* $(WWTFTPDIR)/ipxe/
restorecon -r $(WWTFTPDIR)
wwctl:
cd cmd/wwctl; GOOS=linux go build -mod vendor -tags "$(WW_GO_BUILD_TAGS)" -o ../../wwctl
wwclient:
cd cmd/wwclient; CGO_ENABLED=0 GOOS=linux go build -mod vendor -a -ldflags "-extldflags -static \
-X 'github.com/hpcng/warewulf/internal/pkg/warewulfconf.ConfigFile=/etc/warewulf/warewulf.conf'" -o ../../wwclient
install_wwclient: wwclient
install -m 0755 wwclient $(DESTDIR)$(WWOVERLAYDIR)/wwinit/$(WWCLIENTDIR)/wwclient
bash_completion:
cd cmd/bash_completion && go build -ldflags="-X 'github.com/hpcng/warewulf/internal/pkg/warewulfconf.ConfigFile=./etc/warewulf.conf'\
-X 'github.com/hpcng/warewulf/internal/pkg/node.ConfigFile=./etc/nodes.conf'"\
-mod vendor -tags "$(WW_GO_BUILD_TAGS)" -o ../../bash_completion
bash_completion.d: bash_completion
install -d -m 0755 bash_completion.d
./bash_completion bash_completion.d/warewulf
man_page:
cd cmd/man_page && go build -ldflags="-X 'github.com/hpcng/warewulf/internal/pkg/warewulfconf.ConfigFile=./etc/warewulf.conf'\
-X 'github.com/hpcng/warewulf/internal/pkg/node.ConfigFile=./etc/nodes.conf'"\
-mod vendor -tags "$(WW_GO_BUILD_TAGS)" -o ../../man_page
man_pages: man_page
install -d man_pages
./man_page ./man_pages
cd man_pages; for i in wwctl*1; do echo "Compressing manpage: $$i"; gzip --force $$i; done
config_defaults: vendor cmd/config_defaults/config_defaults.go
cd cmd/config_defaults && go build -ldflags="-X 'github.com/hpcng/warewulf/internal/pkg/warewulfconf.ConfigFile=./etc/warewulf.conf'\
-X 'github.com/hpcng/warewulf/internal/pkg/node.ConfigFile=./etc/nodes.conf'"\
-mod vendor -tags "$(WW_GO_BUILD_TAGS)" -o ../../config_defaults
update_configuration: vendor cmd/update_configuration/update_configuration.go
cd cmd/update_configuration && go build -ldflags="-X 'github.com/hpcng/warewulf/internal/pkg/warewulfconf.ConfigFile=./etc/warewulf.conf'\
-X 'github.com/hpcng/warewulf/internal/pkg/node.ConfigFile=./etc/nodes.conf'"\
-mod vendor -tags "$(WW_GO_BUILD_TAGS)" -o ../../update_configuration
warewulfconf: config_defaults
./config_defaults
dist: vendor config
rm -rf .dist/$(WAREWULF)-$(VERSION)
mkdir -p .dist/$(WAREWULF)-$(VERSION)
cp -rap * .dist/$(WAREWULF)-$(VERSION)/
cd .dist; tar -czf ../$(WAREWULF)-$(VERSION).tar.gz $(WAREWULF)-$(VERSION)
rm -rf .dist
## wwapi generate code from protobuf. Requires protoc and protoc-grpc-gen-gateway to generate code.
## To setup latest protoc:
## Download the protobuf-all-[VERSION].tar.gz from https://github.com/protocolbuffers/protobuf/releases
## Extract the contents and change in the directory
## ./configure
## make
## make check
## sudo make install
## sudo ldconfig # refresh shared library cache.
## To setup protoc-gen-grpc-gateway, see https://github.com/grpc-ecosystem/grpc-gateway
proto:
protoc -I internal/pkg/api/routes/v1 -I=. \
--grpc-gateway_out=. \
--grpc-gateway_opt logtostderr=true \
--go_out=. \
--go-grpc_out=. \
routes.proto
wwapid: ## Build the grpc api server.
go build -o ./wwapid internal/app/api/wwapid/wwapid.go
wwapic: ## Build the sample wwapi client.
go build -o ./wwapic internal/app/api/wwapic/wwapic.go
wwapird: ## Build the rest api server (revese proxy to the grpc api server).
go build -o ./wwapird internal/app/api/wwapird/wwapird.go
clean:
rm -f wwclient
rm -f wwctl
rm -rf .dist
rm -f $(WAREWULF)-$(VERSION).tar.gz
rm -f bash_completion
rm -rf bash_completion.d
rm -f man_page
rm -rf man_pages
rm -rf vendor
rm -f warewulf.spec
rm -f config
rm -f Defaults.mk
rm -rf $(TOOLS_DIR)
rm -f config_defaults
rm -f update_configuration
install: files install_wwclient
debinstall: files debfiles