diff --git a/LICENSE_DEPENDENCIES.md b/LICENSE_DEPENDENCIES.md index 95c87be40..0eae13e46 100644 --- a/LICENSE_DEPENDENCIES.md +++ b/LICENSE_DEPENDENCIES.md @@ -11,35 +11,35 @@ project then you may use a subset of them. The dependencies and their licenses are as follows: -## github.com/containerd/containerd/errdefs +## github.com/Masterminds/goutils **License:** Apache-2.0 -**License URL:** +**License URL:** ## github.com/containers/image/v5 **License:** Apache-2.0 -**License URL:** +**License URL:** ## github.com/containers/libtrust **License:** Apache-2.0 -**License URL:** +**License URL:** ## github.com/containers/ocicrypt **License:** Apache-2.0 -**License URL:** +**License URL:** ## github.com/containers/storage **License:** Apache-2.0 -**License URL:** +**License URL:** ## github.com/coreos/go-semver/semver @@ -63,7 +63,7 @@ The dependencies and their licenses are as follows: **License:** Apache-2.0 -**License URL:** +**License URL:** ## github.com/coreos/vcontext @@ -71,59 +71,173 @@ The dependencies and their licenses are as follows: **License URL:** +## github.com/cyberphone/json-canonicalization/go/src/webpki.org/jsoncanonicalizer + +**License:** Apache-2.0 + +**License URL:** + ## github.com/digitalocean/go-smbios/smbios **License:** Apache-2.0 **License URL:** -## github.com/docker/distribution +## github.com/distribution/reference + +**License:** Apache-2.0 + +**License URL:** + +## github.com/docker/distribution/registry **License:** Apache-2.0 -**License URL:** +**License URL:** ## github.com/docker/docker **License:** Apache-2.0 -**License URL:** +**License URL:** ## github.com/docker/go-connections **License:** Apache-2.0 -**License URL:** +**License URL:** -## github.com/docker/go-metrics +## github.com/docker/go-units **License:** Apache-2.0 -**License URL:** +**License URL:** -## github.com/docker/go-units +## github.com/go-jose/go-jose/v3 + +**License:** Apache-2.0 + +**License URL:** + +## github.com/go-logr/logr + +**License:** Apache-2.0 + +**License URL:** + +## github.com/go-logr/stdr + +**License:** Apache-2.0 + +**License URL:** + +## github.com/go-openapi/analysis + +**License:** Apache-2.0 + +**License URL:** + +## github.com/go-openapi/errors + +**License:** Apache-2.0 + +**License URL:** + +## github.com/go-openapi/jsonpointer + +**License:** Apache-2.0 + +**License URL:** + +## github.com/go-openapi/jsonreference + +**License:** Apache-2.0 + +**License URL:** + +## github.com/go-openapi/loads + +**License:** Apache-2.0 + +**License URL:** + +## github.com/go-openapi/runtime **License:** Apache-2.0 -**License URL:** +**License URL:** + +## github.com/go-openapi/spec + +**License:** Apache-2.0 + +**License URL:** + +## github.com/go-openapi/strfmt + +**License:** Apache-2.0 + +**License URL:** + +## github.com/go-openapi/swag + +**License:** Apache-2.0 + +**License URL:** + +## github.com/go-openapi/validate + +**License:** Apache-2.0 + +**License URL:** ## github.com/golang/glog **License:** Apache-2.0 -**License URL:** +**License URL:** -## github.com/matttproud/golang_protobuf_extensions/pbutil +## github.com/google/go-containerregistry/pkg/name + +**License:** Apache-2.0 + +**License URL:** + +## github.com/klauspost/compress **License:** Apache-2.0 -**License URL:** +**License URL:** ## github.com/moby/sys/mountinfo **License:** Apache-2.0 -**License URL:** +**License URL:** + +## github.com/moby/sys/user + +**License:** Apache-2.0 + +**License URL:** + +## github.com/modern-go/concurrent + +**License:** Apache-2.0 + +**License URL:** + +## github.com/modern-go/reflect2 + +**License:** Apache-2.0 + +**License URL:** + +## github.com/oklog/ulid + +**License:** Apache-2.0 + +**License URL:** ## github.com/opencontainers/go-digest @@ -135,73 +249,67 @@ The dependencies and their licenses are as follows: **License:** Apache-2.0 -**License URL:** +**License URL:** -## github.com/opencontainers/runc/libcontainer +## github.com/opencontainers/runc/libcontainer/user **License:** Apache-2.0 -**License URL:** +**License URL:** ## github.com/opencontainers/runtime-spec/specs-go **License:** Apache-2.0 -**License URL:** +**License URL:** ## github.com/opencontainers/umoci **License:** Apache-2.0 -**License URL:** +**License URL:** ## github.com/opencontainers/umoci/third_party/shared **License:** Apache-2.0 -**License URL:** +**License URL:** -## github.com/opencontainers/umoci/third_party/user - -**License:** Apache-2.0 - -**License URL:** - -## github.com/prometheus/client_golang/prometheus +## github.com/rootless-containers/proto/go-proto **License:** Apache-2.0 -**License URL:** +**License URL:** -## github.com/prometheus/client_model/go +## github.com/sassoftware/go-rpmutils **License:** Apache-2.0 -**License URL:** +**License URL:** -## github.com/prometheus/common +## github.com/sigstore/fulcio/pkg/certificate **License:** Apache-2.0 -**License URL:** +**License URL:** -## github.com/prometheus/procfs +## github.com/sigstore/rekor/pkg/generated/models **License:** Apache-2.0 -**License URL:** +**License URL:** -## github.com/rootless-containers/proto/go-proto +## github.com/sigstore/sigstore/pkg **License:** Apache-2.0 -**License URL:** +**License URL:** ## github.com/spf13/cobra **License:** Apache-2.0 -**License URL:** +**License URL:** ## github.com/stefanberger/go-pkcs11uri @@ -215,25 +323,61 @@ The dependencies and their licenses are as follows: **License URL:** -## google.golang.org/genproto +## go.mongodb.org/mongo-driver + +**License:** Apache-2.0 + +**License URL:** + +## go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp + +**License:** Apache-2.0 + +**License URL:** + +## go.opentelemetry.io/otel + +**License:** Apache-2.0 + +**License URL:** + +## go.opentelemetry.io/otel/metric + +**License:** Apache-2.0 + +**License URL:** + +## go.opentelemetry.io/otel/trace + +**License:** Apache-2.0 + +**License URL:** + +## google.golang.org/genproto/googleapis/api + +**License:** Apache-2.0 + +**License URL:** + +## google.golang.org/genproto/googleapis/rpc/status **License:** Apache-2.0 -**License URL:** +**License URL:** ## google.golang.org/grpc **License:** Apache-2.0 -**License URL:** +**License URL:** -## gopkg.in/square/go-jose.v2 +## gopkg.in/go-jose/go-jose.v2 **License:** Apache-2.0 -**License URL:** +**License URL:** -## gopkg.in/yaml.v3 +## gopkg.in/yaml.v2 **License:** Apache-2.0 @@ -257,53 +401,65 @@ The dependencies and their licenses are as follows: **License URL:** +## dario.cat/mergo + +**License:** BSD-3-Clause + +**License URL:** + ## github.com/cyphar/filepath-securejoin **License:** BSD-3-Clause -**License URL:** +**License URL:** -## github.com/gogo/protobuf/proto +## github.com/go-jose/go-jose/v3/json **License:** BSD-3-Clause -**License URL:** +**License URL:** -## github.com/golang/protobuf +## github.com/gogo/protobuf/proto **License:** BSD-3-Clause -**License URL:** +**License URL:** -## github.com/golang/snappy +## github.com/golang/protobuf/proto **License:** BSD-3-Clause -**License URL:** +**License URL:** ## github.com/google/uuid **License:** BSD-3-Clause -**License URL:** +**License URL:** ## github.com/gorilla/mux **License:** BSD-3-Clause -**License URL:** +**License URL:** ## github.com/grpc-ecosystem/grpc-gateway/v2 **License:** BSD-3-Clause -**License URL:** +**License URL:** -## github.com/klauspost/compress +## github.com/imdario/mergo + +**License:** BSD-3-Clause + +**License URL:** + +## github.com/klauspost/compress/internal/snapref **License:** BSD-3-Clause -**License URL:** +**License URL:** ## github.com/manifoldco/promptui @@ -315,19 +471,19 @@ The dependencies and their licenses are as follows: **License:** BSD-3-Clause -**License URL:** +**License URL:** -## github.com/mtrmac/gpgme +## github.com/pmezard/go-difflib/difflib **License:** BSD-3-Clause -**License URL:** +**License URL:** -## github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg +## github.com/proglottis/gpgme **License:** BSD-3-Clause -**License URL:** +**License URL:** ## github.com/spf13/pflag @@ -339,7 +495,7 @@ The dependencies and their licenses are as follows: **License:** BSD-3-Clause -**License URL:** +**License URL:** ## github.com/vbatts/go-mtree @@ -347,65 +503,95 @@ The dependencies and their licenses are as follows: **License URL:** +## github.com/vbatts/tar-split + +**License:** BSD-3-Clause + +**License URL:** + ## golang.org/x/crypto **License:** BSD-3-Clause -**License URL:** +**License URL:** + +## golang.org/x/exp + +**License:** BSD-3-Clause + +**License URL:** ## golang.org/x/net **License:** BSD-3-Clause -**License URL:** +**License URL:** ## golang.org/x/sync/semaphore **License:** BSD-3-Clause -**License URL:** +**License URL:** ## golang.org/x/sys/unix **License:** BSD-3-Clause -**License URL:** +**License URL:** ## golang.org/x/term **License:** BSD-3-Clause -**License URL:** +**License URL:** ## golang.org/x/text **License:** BSD-3-Clause -**License URL:** +**License URL:** ## google.golang.org/protobuf **License:** BSD-3-Clause -**License URL:** +**License URL:** -## gopkg.in/square/go-jose.v2/json +## gopkg.in/go-jose/go-jose.v2/json **License:** BSD-3-Clause -**License URL:** +**License URL:** + +## github.com/davecgh/go-spew/spew + +**License:** ISC + +**License URL:** ## github.com/BurntSushi/toml **License:** MIT -**License URL:** +**License URL:** + +## github.com/Masterminds/semver/v3 + +**License:** MIT + +**License URL:** + +## github.com/Masterminds/sprig/v3 + +**License:** MIT + +**License URL:** ## github.com/VividCortex/ewma **License:** MIT -**License URL:** +**License URL:** ## github.com/acarl005/stripansi @@ -419,29 +605,23 @@ The dependencies and their licenses are as follows: **License URL:** -## github.com/beorn7/perks/quantile - -**License:** MIT - -**License URL:** - -## github.com/cespare/xxhash/v2 +## github.com/asaskevich/govalidator **License:** MIT -**License URL:** +**License URL:** ## github.com/chzyer/readline **License:** MIT -**License URL:** +**License URL:** ## github.com/cpuguy83/go-md2man/v2/md2man **License:** MIT -**License URL:** +**License URL:** ## github.com/creasty/defaults @@ -453,31 +633,55 @@ The dependencies and their licenses are as follows: **License:** MIT -**License URL:** +**License URL:** ## github.com/fatih/color **License:** MIT -**License URL:** +**License URL:** + +## github.com/felixge/httpsnoop + +**License:** MIT + +**License URL:** + +## github.com/huandu/xstrings + +**License:** MIT + +**License URL:** + +## github.com/josharian/intern + +**License:** MIT + +**License URL:** -## github.com/ghodss/yaml +## github.com/json-iterator/go **License:** MIT -**License URL:** +**License URL:** ## github.com/klauspost/compress/zstd/internal/xxhash **License:** MIT -**License URL:** +**License URL:** ## github.com/klauspost/pgzip **License:** MIT -**License URL:** +**License URL:** + +## github.com/mailru/easyjson + +**License:** MIT + +**License URL:** ## github.com/mattn/go-colorable @@ -489,13 +693,37 @@ The dependencies and their licenses are as follows: **License:** MIT -**License URL:** +**License URL:** ## github.com/mattn/go-runewidth **License:** MIT -**License URL:** +**License URL:** + +## github.com/mattn/go-sqlite3 + +**License:** MIT + +**License URL:** + +## github.com/mitchellh/copystructure + +**License:** MIT + +**License URL:** + +## github.com/mitchellh/mapstructure + +**License:** MIT + +**License URL:** + +## github.com/mitchellh/reflectwalk + +**License:** MIT + +**License URL:** ## github.com/olekukonko/tablewriter @@ -503,35 +731,65 @@ The dependencies and their licenses are as follows: **License URL:** +## github.com/rivo/uniseg + +**License:** MIT + +**License URL:** + +## github.com/secure-systems-lab/go-securesystemslib/encrypted + +**License:** MIT + +**License URL:** + +## github.com/shopspring/decimal + +**License:** MIT + +**License URL:** + ## github.com/sirupsen/logrus **License:** MIT -**License URL:** +**License URL:** -## github.com/urfave/cli +## github.com/spf13/cast **License:** MIT -**License URL:** +**License URL:** -## github.com/vincent-petithory/dataurl +## github.com/stretchr/testify/assert **License:** MIT -**License URL:** +**License URL:** -## go.etcd.io/bbolt +## github.com/titanous/rocacheck **License:** MIT -**License URL:** +**License URL:** + +## github.com/urfave/cli + +**License:** MIT + +**License URL:** + +## github.com/vincent-petithory/dataurl + +**License:** MIT + +**License URL:** ## go.mozilla.org/pkcs7 **License:** MIT -**License URL:** +**License URL:** ## gopkg.in/yaml.v3 @@ -539,15 +797,39 @@ The dependencies and their licenses are as follows: **License URL:** +## github.com/hashicorp/errwrap + +**License:** MPL-2.0 + +**License URL:** + +## github.com/hashicorp/go-multierror + +**License:** MPL-2.0 + +**License URL:** + +## github.com/hashicorp/go-version + +**License:** MPL-2.0 + +**License URL:** + +## github.com/letsencrypt/boulder + +**License:** MPL-2.0 + +**License URL:** + ## github.com/talos-systems/go-smbios/smbios **License:** MPL-2.0 **License URL:** -## github.com/vbauerster/mpb/v5 +## github.com/vbauerster/mpb/v8 **License:** Unlicense -**License URL:** +**License URL:** diff --git a/Makefile b/Makefile index 4c3cc10c5..0f970b57f 100644 --- a/Makefile +++ b/Makefile @@ -73,6 +73,10 @@ etc/bash_completion.d/wwctl: wwctl lint: $(config) $(GOLANGCI_LINT) run --build-tags "$(WW_GO_BUILD_TAGS)" --timeout=5m ./... +.PHONY: deadcode +deadcode: $(config) + $(GOLANG_DEADCODE) -test ./... + .PHONY: vet vet: $(config) go vet ./... @@ -221,6 +225,7 @@ wwapird: vendor dist: vendor lint: $(GOLANGCI_LINT) +deadcode: $(GOLANG_DEADCODE) protofiles = internal/pkg/api/routes/wwapiv1/routes.pb.go \ internal/pkg/api/routes/wwapiv1/routes.pb.gw.go \ diff --git a/Tools.mk b/Tools.mk index a8d3808ef..aa5e49f50 100644 --- a/Tools.mk +++ b/Tools.mk @@ -7,6 +7,8 @@ GO_TOOLS_VENDOR := $(addprefix vendor/, $(GO_TOOLS)) GOLANGCI_LINT := $(TOOLS_BIN)/golangci-lint GOLANGCI_LINT_VERSION := v1.56.2 +GOLANG_DEADCODE := $(TOOLS_BIN)/deadcode + PROTOC := $(TOOLS_BIN)/protoc PROTOC_GEN_GO := $(TOOLS_BIN)/protoc-gen-go PROTOC_GEN_GO_GRPC := $(TOOLS_BIN)/protoc-gen-go-grpc @@ -32,6 +34,9 @@ $(GO_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) +$(GOLANG_DEADCODE): + GOBIN="$(PWD)/$(TOOLS_BIN)" go install golang.org/x/tools/cmd/deadcode@v0.24.0 + $(PROTOC): $(TOOLS_DIR) cd $(TOOLS_DIR) && curl -LO $(PROTOC_URL) && unzip -o $(notdir $(PROTOC_URL)) touch --no-create $(PROTOC) # by default the timestamp is preserved from the archive diff --git a/API.md b/internal/app/api/API.md similarity index 100% rename from API.md rename to internal/app/api/API.md diff --git a/internal/pkg/api/apiconfig/container/container.go b/internal/pkg/api/apiconfig/container/container.go deleted file mode 100644 index 0c21f3bfe..000000000 --- a/internal/pkg/api/apiconfig/container/container.go +++ /dev/null @@ -1,369 +0,0 @@ -package container - -import ( - "fmt" - "os" - "path" - "strconv" - "strings" - - "github.com/containers/image/v5/types" - "github.com/pkg/errors" - "github.com/warewulf/warewulf/internal/pkg/api/routes/wwapiv1" - "github.com/warewulf/warewulf/internal/pkg/container" - "github.com/warewulf/warewulf/internal/pkg/kernel" - "github.com/warewulf/warewulf/internal/pkg/node" - "github.com/warewulf/warewulf/internal/pkg/util" - "github.com/warewulf/warewulf/internal/pkg/warewulfd" - "github.com/warewulf/warewulf/internal/pkg/wwlog" -) - -// TODO: SynchUser is not NYI in the API: See https://github.com/warewulf/warewulf/blob/main/internal/app/wwctl/container/syncuser/main.go - -func ContainerBuild(cbp *wwapiv1.ContainerBuildParameter) (err error) { - - if cbp == nil { - return fmt.Errorf("ContainerBuildParameter is nil") - } - - var containers []string - - if cbp.All { - containers, err = container.ListSources() - } else { - containers = cbp.ContainerNames - } - - if len(containers) == 0 { - return - } - - for _, c := range containers { - if !container.ValidSource(c) { - err = fmt.Errorf("VNFS name does not exist: %s", c) - wwlog.Error("%s", err) - return - } - - err = container.Build(c, cbp.Force) - if err != nil { - wwlog.Error("Could not build container %s: %s", c, err) - return - } - } - - if cbp.Default { - if len(containers) != 1 { - wwlog.Error("Can only set default for one container") - } else { - var nodeDB node.NodeYaml - nodeDB, err = node.New() - if err != nil { - wwlog.Error("Could not open node configuration: %s", err) - return - } - - //TODO: Don't loop through profiles, instead have a nodeDB function that goes directly to the map - profiles, _ := nodeDB.FindAllProfiles() - for _, profile := range profiles { - wwlog.Debug("Looking for profile default: %s", profile.Id()) - if profile.Id() == "default" { - wwlog.Debug("Found profile default, setting container name to: %s", containers[0]) - profile.ContainerName = containers[0] - } - } - // TODO: Need a wrapper and flock around this. Sometimes we restart warewulfd and sometimes we don't. - err = nodeDB.Persist() - if err != nil { - return errors.Wrap(err, "failed to persist nodedb") - } - err = warewulfd.DaemonReload() - if err != nil { - return errors.Wrap(err, "failed to reload warewulfd") - } - wwlog.Info("Set default profile to container: %s", containers[0]) - } - } - return -} - -func ContainerDelete(cdp *wwapiv1.ContainerDeleteParameter) (err error) { - - if cdp == nil { - return fmt.Errorf("ContainerDeleteParameter is nil") - } - - nodeDB, err := node.New() - if err != nil { - wwlog.Error("Could not open nodeDB: %s", err) - return - } - - nodes, err := nodeDB.FindAllNodes() - if err != nil { - return - } - -ARG_LOOP: - for i := 0; i < len(cdp.ContainerNames); i++ { - //_, arg := range args { - containerName := cdp.ContainerNames[i] - for _, n := range nodes { - if n.ContainerName == containerName { - wwlog.Error("Container is configured for nodes, skipping: %s", containerName) - continue ARG_LOOP - } - } - - if !container.ValidSource(containerName) { - wwlog.Error("Container name is not a valid source: %s", containerName) - continue - } - err := container.DeleteSource(containerName) - if err != nil { - wwlog.Error("Could not remove source: %s", containerName) - } else { - fmt.Printf("Container has been deleted: %s\n", containerName) - } - } - - return -} - -func ContainerImport(cip *wwapiv1.ContainerImportParameter) (containerName string, err error) { - - if cip == nil { - err = fmt.Errorf("NodeAddParameter is nil") - return - } - - if cip.Name == "" { - name := path.Base(cip.Source) - fmt.Printf("Setting VNFS name: %s\n", name) - cip.Name = name - } - if !container.ValidName(cip.Name) { - err = fmt.Errorf("VNFS name contains illegal characters: %s", cip.Name) - wwlog.Error("%s", err) - return - } - - containerName = cip.Name - fullPath := container.SourceDir(cip.Name) - - if util.IsDir(fullPath) { - if cip.Force { - fmt.Printf("Overwriting existing VNFS\n") - err = os.RemoveAll(fullPath) - if err != nil { - wwlog.Error("%s", err) - return - } - } else if cip.Update { - fmt.Printf("Updating existing VNFS\n") - } else { - err = fmt.Errorf("VNFS Name exists, specify --force, --update, or choose a different name: %s", cip.Name) - wwlog.Error("%s", err) - return - } - } else if strings.HasPrefix(cip.Source, "docker://") || strings.HasPrefix(cip.Source, "docker-daemon://") { - var sCtx *types.SystemContext - sCtx, err = getSystemContext() - if err != nil { - wwlog.Error("%s", err) - // return was missing here. Was that deliberate? - } - - err = container.ImportDocker(cip.Source, cip.Name, sCtx) - if err != nil { - wwlog.Error("Could not import image: %s", err) - _ = container.DeleteSource(cip.Name) - return - } - } else if util.IsDir(cip.Source) { - err = container.ImportDirectory(cip.Source, cip.Name) - if err != nil { - wwlog.Error("Could not import image: %s", err) - _ = container.DeleteSource(cip.Name) - return - } - } else { - err = fmt.Errorf("Invalid dir or uri: %s", cip.Source) - wwlog.Error("%s", err) - return - } - - fmt.Printf("Building container: %s\n", cip.Name) - err = container.Build(cip.Name, true) - if err != nil { - wwlog.Error("Could not build container %s: %s", cip.Name, err) - return - } - - if cip.Default { - var nodeDB node.NodeYaml - nodeDB, err = node.New() - if err != nil { - wwlog.Error("Could not open node configuration: %s", err) - return - } - - //TODO: Don't loop through profiles, instead have a nodeDB function that goes directly to the map - profiles, _ := nodeDB.FindAllProfiles() - for _, profile := range profiles { - wwlog.Debug("Looking for profile default: %s", profile.Id()) - if profile.Id() == "default" { - wwlog.Debug("Found profile default, setting container name to: %s", cip.Name) - profile.ContainerName = cip.Name - } - } - // TODO: We need this in a function with a flock around it. - // Also need to understand if the daemon restart is only to - // reload the config or if there is something more. - err = nodeDB.Persist() - if err != nil { - err = errors.Wrap(err, "failed to persist nodedb") - return - } - - fmt.Printf("Set default profile to container: %s\n", cip.Name) - err = warewulfd.DaemonReload() - if err != nil { - err = errors.Wrap(err, "failed to reload warewulf daemon") - return - } - } - return -} - -func ContainerList() (containerInfo []*wwapiv1.ContainerInfo, err error) { - var sources []string - - sources, err = container.ListSources() - if err != nil { - wwlog.Error("%s", err) - return - } - - nodeDB, err := node.New() - if err != nil { - wwlog.Error("%s", err) - return - } - - nodes, err := nodeDB.FindAllNodes() - if err != nil { - wwlog.Error("%s", err) - return - } - - nodemap := make(map[string]int) - for _, n := range nodes { - nodemap[n.ContainerName]++ - } - - for _, source := range sources { - if nodemap[source] == 0 { - nodemap[source] = 0 - } - - wwlog.Debug("Finding kernel version for: %s", source) - _, kernelVersion, _ := kernel.FindKernel(container.RootFsDir(source)) - - containerInfo = append(containerInfo, &wwapiv1.ContainerInfo{ - Name: source, - NodeCount: uint32(nodemap[source]), - KernelVersion: kernelVersion, - }) - } - return -} - -func ContainerShow(csp *wwapiv1.ContainerShowParameter) (response *wwapiv1.ContainerShowResponse, err error) { - - containerName := csp.ContainerName - - if !container.ValidName(containerName) { - err = fmt.Errorf("%s is not a valid container", containerName) - return - } - - rootFsDir := container.RootFsDir(containerName) - - nodeDB, err := node.New() - if err != nil { - return - } - - nodes, err := nodeDB.FindAllNodes() - if err != nil { - return - } - - var nodeList []string - for _, n := range nodes { - if n.ContainerName == containerName { - - nodeList = append(nodeList, n.Id()) - } - } - - response = &wwapiv1.ContainerShowResponse{ - Name: containerName, - Rootfs: rootFsDir, - Nodes: nodeList, - } - return -} - -// Private helpers - -func setOCICredentials(sCtx *types.SystemContext) error { - username, userSet := os.LookupEnv("WAREWULF_OCI_USERNAME") - password, passSet := os.LookupEnv("WAREWULF_OCI_PASSWORD") - if userSet || passSet { - if userSet && passSet { - sCtx.DockerAuthConfig = &types.DockerAuthConfig{ - Username: username, - Password: password, - } - } else { - return fmt.Errorf("oci username and password env vars must be specified together") - } - } - return nil -} - -func setNoHTTPSOpts(sCtx *types.SystemContext) error { - val, ok := os.LookupEnv("WAREWULF_OCI_NOHTTPS") - if !ok { - return nil - } - - noHTTPS, err := strconv.ParseBool(val) - if err != nil { - return fmt.Errorf("while parsing insecure http option: %v", err) - } - - // only set this if we want to disable, otherwise leave as undefined - if noHTTPS { - sCtx.DockerInsecureSkipTLSVerify = types.NewOptionalBool(true) - } - sCtx.OCIInsecureSkipTLSVerify = noHTTPS - - return nil -} - -func getSystemContext() (sCtx *types.SystemContext, err error) { - sCtx = &types.SystemContext{} - - if err := setOCICredentials(sCtx); err != nil { - return nil, err - } - - if err := setNoHTTPSOpts(sCtx); err != nil { - return nil, err - } - - return sCtx, nil -} diff --git a/internal/pkg/api/node/edit.go b/internal/pkg/api/node/edit.go index b28ead94e..e980098da 100644 --- a/internal/pkg/api/node/edit.go +++ b/internal/pkg/api/node/edit.go @@ -10,25 +10,6 @@ import ( "gopkg.in/yaml.v3" ) -/* -Returns the nodes as a yaml string -*/ -func FindAllNodeConfs() *wwapiv1.NodeYaml { - nodeDB, err := node.New() - if err != nil { - wwlog.Error("Could not open nodeDB: %s\n", err) - os.Exit(1) - } - nodeMap, _ := nodeDB.FindAllNodes() - // ignore err as nodeDB should always be correct - buffer, _ := yaml.Marshal(nodeMap) - retVal := wwapiv1.NodeYaml{ - NodeConfMapYaml: string(buffer), - Hash: nodeDB.StringHash(), - } - return &retVal -} - /* Returns filtered list of nodes */ diff --git a/internal/pkg/api/node/utils.go b/internal/pkg/api/node/utils.go deleted file mode 100644 index d6a159ece..000000000 --- a/internal/pkg/api/node/utils.go +++ /dev/null @@ -1,61 +0,0 @@ -package apinode - -import ( - "strings" - - "github.com/pkg/errors" - "github.com/warewulf/warewulf/internal/pkg/node" - "github.com/warewulf/warewulf/internal/pkg/warewulfd" -) - -// nodeDbSave persists the nodeDB to disk and restarts warewulfd. -// TODO: We will likely need locking around anything changing nodeDB -// or restarting warewulfd. Determine if the reason for restart is -// just to reinitialize warewulfd with the new nodeDB or if there is -// something more to it. -func DbSave(nodeDB *node.NodeYaml) (err error) { - err = nodeDB.Persist() - if err != nil { - return errors.Wrap(err, "failed to persist nodedb") - } - - err = warewulfd.DaemonReload() - if err != nil { - return errors.Wrap(err, "failed to reload warewulf daemon") - } - return -} - -/* -Add the netname to the options map, as its only known after the -command line options have been read out, but its needing for setting -the values. Returns the manipulated map and a bool which is true if -networks specific values were set, but no netname was given. -*/ -func AddNetname(theMap map[string]*string) (map[string]*string, bool) { - netname := "" - netvalues := false - retMap := make(map[string]*string) - for key, val := range theMap { - if key == "NetDevs" && *val != "" { - netname = *val - } - } - for key, val := range theMap { - keys := strings.Split(key, ".") - myVal := *val - if len(keys) >= 2 && keys[0] == "NetDevs" { - if *val != "" { - netvalues = true - } - if netname != "" { - retMap[keys[0]+"."+netname+"."+strings.Join(keys[1:], ".")] = &myVal - } - } else { - retMap[key] = &myVal - } - - } - - return retMap, netvalues && netname == "" -} diff --git a/internal/pkg/api/profile/edit.go b/internal/pkg/api/profile/edit.go index cbd06d0af..4a85ef50e 100644 --- a/internal/pkg/api/profile/edit.go +++ b/internal/pkg/api/profile/edit.go @@ -11,24 +11,6 @@ import ( "gopkg.in/yaml.v3" ) -/* -Returns the nodes as a yaml string -*/ -func FindAllProfileConfs() *wwapiv1.NodeYaml { - nodeDB, err := node.New() - if err != nil { - wwlog.Error("Could not open nodeDB: %s\n", err) - os.Exit(1) - } - profileMap, _ := nodeDB.FindAllProfiles() - // ignore err as nodeDB should always be correct - buffer, _ := yaml.Marshal(profileMap) - retVal := wwapiv1.NodeYaml{ - NodeConfMapYaml: string(buffer), - } - return &retVal -} - /* Returns filtered list of nodes */ diff --git a/internal/pkg/container/util.go b/internal/pkg/container/util.go index 1089a2c0e..b2e54057a 100644 --- a/internal/pkg/container/util.go +++ b/internal/pkg/container/util.go @@ -48,11 +48,6 @@ func ListSources() ([]string, error) { return ret, nil } -func DoesContainerExists(name string) bool { - fullPath := ImageFile(name) - return util.IsFile(fullPath) -} - func DoesSourceExist(name string) bool { fullPath := RootFsDir(name) return util.IsDir(fullPath) diff --git a/internal/pkg/node/helper.go b/internal/pkg/node/helper.go deleted file mode 100644 index 9598c21d9..000000000 --- a/internal/pkg/node/helper.go +++ /dev/null @@ -1,16 +0,0 @@ -package node - -/* -helper functions -*/ - -// string which is printed if no value is set -const NoValue = "--" - -// print NoValue if string is empty -func PrintVal(in string) (out string) { - if in != "" { - return in - } - return NoValue -} diff --git a/internal/pkg/node/methods.go b/internal/pkg/node/methods.go index ad7e4b227..0c37d2a92 100644 --- a/internal/pkg/node/methods.go +++ b/internal/pkg/node/methods.go @@ -82,40 +82,6 @@ func FilterProfileListByName(set []ProfileConf, searchList []string) []ProfileCo return ret } -/* -Filter a given map of NodeConf against given regular expression. -*/ -func FilterNodeMapByName(inputMap map[string]*NodeConf, searchList []string) (retMap map[string]*NodeConf) { - retMap = map[string]*NodeConf{} - if len(searchList) > 0 { - for _, search := range searchList { - for name, nConf := range inputMap { - if match, _ := regexp.MatchString("^"+search+"$", name); match { - retMap[name] = nConf - } - } - } - } - return retMap -} - -/* -Filter a given map of ProfileConf against given regular expression. -*/ -func FilterProfileMapByName(inputMap map[string]*ProfileConf, searchList []string) (retMap map[string]*ProfileConf) { - retMap = map[string]*ProfileConf{} - if len(searchList) > 0 { - for _, search := range searchList { - for name, nConf := range inputMap { - if match, _ := regexp.MatchString("^"+search+"$", name); match { - retMap[name] = nConf - } - } - } - } - return retMap -} - /* Creates an NodeConf with the given id. Doesn't add it to the database */ diff --git a/internal/pkg/oci/cache.go b/internal/pkg/oci/cache.go deleted file mode 100644 index 7cf2ac688..000000000 --- a/internal/pkg/oci/cache.go +++ /dev/null @@ -1,111 +0,0 @@ -package oci - -import ( - "context" - "fmt" - "os" - "path/filepath" - - "github.com/containers/image/v5/types" -) - -type CacheOpt func(*Cache) error - -func OptSetCachePath(path string) CacheOpt { - return func(s *Cache) error { - s.path = path - return nil - } -} - -type Cache struct { - path string -} - -func (c *Cache) rootfsDir() string { - return filepath.Join(c.path, rootfsPrefix) -} - -func (c *Cache) blobDir() string { - return filepath.Join(c.path, blobPrefix) -} - -// checkEntry maps the given id a path within the cache. It will return an os.ErrNotExist if the entry path is empty. -func (c *Cache) checkEntry(id string) (string, error) { - path := filepath.Join(c.rootfsDir(), id) - fi, err := os.Stat(path) - if err != nil { - return "", err - } - - if !fi.IsDir() { - return "", fmt.Errorf("invalid entry %q is not a directory", path) - } - - return path, nil -} - -func (c *Cache) createEntry(id string) (string, error) { - path := filepath.Join(c.rootfsDir(), id) - if err := os.MkdirAll(path, 0755); err != nil { - return "", err - } - - return path, nil -} - -func NewCache(opts ...CacheOpt) (*Cache, error) { - s := &Cache{ - path: filepath.Join(defaultCachePath), - } - - for _, o := range opts { - if err := o(s); err != nil { - return nil, err - } - } - - if err := os.MkdirAll(s.path, 0755); err != nil { - return nil, err - } - - return s, nil -} - -func (c *Cache) Pull(ctx context.Context, uri string, sysCtx *types.SystemContext) (string, error) { - p, err := NewPuller( - OptSetBlobCachePath(c.blobDir()), - OptSetSystemContext(sysCtx), - ) - if err != nil { - return "", err - } - - id, err := p.GenerateID(ctx, uri) - if err != nil { - return "", err - } - - // look up cache entry and return if it exists - path, err := c.checkEntry(id) - if err == nil { - return path, nil - } else if !os.IsNotExist(err) { - return "", err - } - - // cache entry does not exist so we must create it - path, err = c.createEntry(id) - if err != nil { - return "", err - } - - // populate entry - if err := p.Pull(ctx, uri, path); err != nil { - // clean up entry on error - os.RemoveAll(path) - return "", err - } - - return path, nil -} diff --git a/internal/pkg/oci/puller.go b/internal/pkg/oci/puller.go index e7b194b3e..b73883706 100644 --- a/internal/pkg/oci/puller.go +++ b/internal/pkg/oci/puller.go @@ -31,13 +31,6 @@ func OptSetBlobCachePath(path string) pullerOpt { } } -func OptSetTmpDirPath(path string) pullerOpt { - return func(p *puller) error { - p.tmpDirPath = path - return nil - } -} - func OptSetSystemContext(s *types.SystemContext) pullerOpt { return func(p *puller) error { p.sysCtx = s diff --git a/internal/pkg/util/copyfile.go b/internal/pkg/util/copyfile.go index 797a4d6a1..ccaabbda6 100644 --- a/internal/pkg/util/copyfile.go +++ b/internal/pkg/util/copyfile.go @@ -3,8 +3,6 @@ package util import ( "io" "os" - "path" - "path/filepath" "github.com/warewulf/warewulf/internal/pkg/wwlog" ) @@ -60,47 +58,3 @@ func SafeCopyFile(src string, dst string) error { } return err } - -func CopyFiles(source string, dest string) error { - err := filepath.Walk(source, func(location string, info os.FileInfo, err error) error { - if err != nil { - return err - } - - if info.IsDir() { - wwlog.Debug("Creating directory: %s", location) - info, err := os.Stat(source) - if err != nil { - return err - } - - err = os.MkdirAll(path.Join(dest, location), info.Mode()) - if err != nil { - return err - } - err = CopyUIDGID(source, dest) - if err != nil { - return err - } - - } else { - wwlog.Debug("Writing file: %s", location) - - err := CopyFile(location, path.Join(dest, location)) - if err != nil { - return err - } - - } - - return nil - }) - - if err != nil { - return err - } - - return nil -} - -//TODO: func CopyRecursive ... diff --git a/internal/pkg/util/util.go b/internal/pkg/util/util.go index 5b21426b9..c293296cd 100644 --- a/internal/pkg/util/util.go +++ b/internal/pkg/util/util.go @@ -2,20 +2,16 @@ package util import ( "bufio" - "crypto/sha256" "fmt" "io" "io/fs" - "math/rand" "net" "os" "os/exec" "path" "path/filepath" "regexp" - "runtime" "strings" - "sync/atomic" "syscall" "time" @@ -23,49 +19,6 @@ import ( "github.com/warewulf/warewulf/internal/pkg/wwlog" ) -// reserve some number of cpus for system/warwulfd usage -var processLimitedReserve int = 4 - -// maximum number of concurrent spawned processes -var processLimitedMax = MaxInt(1, runtime.NumCPU()-processLimitedReserve) - -// Channel used as semaphore to specififed processLimitedMax -var processLimitedChan = make(chan int, processLimitedMax) - -// Current number of processes started + queued -var processLimitedNum int32 = 0 - -// Counter over total history of started processes -var processLimitedCounter uint32 = 0 - -func ProcessLimitedEnter() (index uint32) { - atomic.AddInt32(&processLimitedNum, 1) - index = atomic.AddUint32(&processLimitedCounter, 1) - // NOTE: blocks when channel is full (i.e. processLimitedMax) - // until a process exists and takes one out of channel - processLimitedChan <- 1 - return -} - -func ProcessLimitedExit() { - <-processLimitedChan - atomic.AddInt32(&processLimitedNum, -1) -} - -func ProcessLimitedStatus() (running int32, queued int32) { - running = int32(len(processLimitedChan)) - queued = processLimitedNum - running - return -} - -func MaxInt(a int, b int) int { - if a > b { - return a - } - - return b -} - func FirstError(errs ...error) (err error) { for _, e := range errs { if err == nil { @@ -122,16 +75,6 @@ func PathIsNewer(source string, compare string) bool { return time1.Before(time2) } -func RandomString(n int) string { - var letter = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789") - - b := make([]rune, n) - for i := range b { - b[i] = letter[rand.Intn(len(letter))] - } - return string(b) -} - /* Checks if given string is in slice. I yes returns true, false otherwise. */ @@ -144,21 +87,6 @@ func InSlice(slice []string, match string) bool { return false } -/* -Checks if one or more elements of a slice A are a part of slice B. Returns true -as soon as one element matches.\ -*/ -func SliceInSlice(A []string, B []string) bool { - for _, a := range A { - for _, b := range B { - if a == b { - return true - } - } - } - return false -} - func IsDir(path string) bool { wwlog.Debug("Checking if path exists as a directory: %s", path) @@ -205,13 +133,6 @@ func ValidString(pattern string, expr string) bool { return false } -func ValidateOrDie(message string, pattern string, expr string) { - if ValidString(pattern, expr) { - wwlog.Error("%s does not validate: '%s'", message, pattern) - os.Exit(1) - } -} - // ****************************************************************************** func FindFiles(path string) []string { var ret []string @@ -349,71 +270,6 @@ func ExecInteractive(command string, a ...string) error { return err } -func ShaSumFile(file string) (string, error) { - var ret string - - f, err := os.Open(file) - if err != nil { - return ret, nil - } - defer f.Close() - - h := sha256.New() - if _, err := io.Copy(h, f); err != nil { - return ret, err - } - - return fmt.Sprintf("%x", h.Sum(nil)), nil -} - -func SliceRemoveElement(array []string, remove string) []string { - var ret []string - - // Linear time, maintains order - for _, r := range array { - if r != remove { - ret = append(ret, r) - } else { - wwlog.Debug("Removing slice from array: %s", remove) - } - } - - return ret -} - -/* -Adds a string, to string slice if the given string is not present in the slice. -*/ -func SliceAddUniqueElement(array []string, add string) []string { - var ret []string - var found bool - - //Linear time, appends - for _, r := range array { - ret = append(ret, r) - if r == add { - found = true - } - } - - if !found { - ret = append(ret, add) - } - - return ret -} - -/* -Appends a string slice to another slice. Guarantees that the elements are uniq. -*/ -func SliceAppendUniq(array []string, add []string) []string { - ret := array - for _, r := range add { - ret = SliceAddUniqueElement(ret, r) - } - return ret -} - func SystemdStart(systemdName string) error { startCmd := fmt.Sprintf("systemctl restart %s", systemdName) enableCmd := fmt.Sprintf("systemctl enable %s", systemdName) @@ -449,48 +305,6 @@ func CopyUIDGID(source string, dest string) error { return err } -func SplitEscaped(input, delim, escape string) []string { - var ret []string - str := "" - for i := 1; i < len(input); i++ { - str += string(input[i-1]) - if string(input[i]) == delim && string(input[i-1]) != escape { - i++ - ret = append(ret, str) - str = "" - } - if string(input[i]) == escape { - i++ - } - - } - str += string(input[len(input)-1]) - ret = append(ret, str) - - return (ret) -} - -func SplitValidPaths(input, delim string) []string { - var ret []string - str := "" - for i := 1; i < len(input); i++ { - str += string(input[i-1]) - if (string(input[i]) == delim && string(input[i-1]) != "\\") && (IsDir(str) || IsFile(str)) { - i++ - ret = append(ret, str) - str = "" - } - if string(input[i]) == "\\" { - i++ - } - - } - str += string(input[len(input)-1]) - ret = append(ret, str) - - return (ret) -} - func IncrementIPv4(start net.IP, inc uint) net.IP { ipv4 := start.To4() v4_int := uint(ipv4[0])<<24 + uint(ipv4[1])<<16 + uint(ipv4[2])<<8 + uint(ipv4[3]) @@ -716,28 +530,6 @@ func BuildFsImage( return nil } -/* -****************************************************************************** - - Runs wwctl command -*/ -func RunWWCTL(args ...string) (out []byte, err error) { - index := ProcessLimitedEnter() - defer ProcessLimitedExit() - running, queued := ProcessLimitedStatus() - - wwlog.Verbose("Starting wwctl process %d (%d running, %d queued): %v", - index, running, queued, args) - - proc := exec.Command("wwctl", args...) - - out, err = proc.CombinedOutput() - - wwlog.Verbose("Finished wwctl process %d", index) - - return out, err -} - /* Get size of given directory in bytes */ diff --git a/internal/pkg/warewulfd/daemon.go b/internal/pkg/warewulfd/daemon.go index 53c819b1a..816c958bf 100644 --- a/internal/pkg/warewulfd/daemon.go +++ b/internal/pkg/warewulfd/daemon.go @@ -35,11 +35,6 @@ func SetNoDaemon() { nodaemon = true } -// run with daemon -func SetDaemon() { - nodaemon = false -} - func DaemonFormatter(logLevel int, rec *wwlog.LogRecord) string { return "[" + rec.Time.Format(time.UnixDate) + "] " + wwlog.DefaultFormatter(logLevel, rec) } diff --git a/internal/pkg/wwlog/wwlog.go b/internal/pkg/wwlog/wwlog.go index 5f71f1700..bd8b61797 100644 --- a/internal/pkg/wwlog/wwlog.go +++ b/internal/pkg/wwlog/wwlog.go @@ -175,14 +175,6 @@ func SetLogWriterErr(newOut io.Writer) { logOut = newOut } -func GetLogWriterInfo() io.Writer { - return logOut -} - -func GetLogWriterErr() io.Writer { - return logErr -} - /* Set the log record formatter By default this is set to DefaultFormatter @@ -192,10 +184,6 @@ func SetLogFormatter(formatter LogFormatter) { Debug("Set log formatter: %s", runtime.FuncForPC(reflect.ValueOf(formatter).Pointer()).Name()) } -func GetLogFormatter() LogFormatter { - return logFormatter -} - /* Internal method to create a log record */ @@ -227,14 +215,6 @@ func LogCaller(level int, skip int, err error, message string, a ...interface{}) } } -func Println(level int, message string) { - LogCaller(level, 1, nil, message) -} - -func Printf(level int, message string, a ...interface{}) { - LogCaller(level, 1, nil, message, a...) -} - /* ****************************************************************************** Named log level functions @@ -311,10 +291,6 @@ func SecWarn(message string, a ...interface{}) { LogCaller(SECWARN, 1, nil, message, a...) } -func ErrOut(message string, a ...interface{}) { - LogCaller(ERROUT, 1, nil, message, a...) -} - func Error(message string, a ...interface{}) { LogCaller(ERROR, 1, nil, message, a...) } diff --git a/scripts/update-license-dependencies.sh b/scripts/update-license-dependencies.sh old mode 100644 new mode 100755 diff --git a/ssh_config b/ssh_config deleted file mode 100644 index 377c91f4d..000000000 --- a/ssh_config +++ /dev/null @@ -1,4 +0,0 @@ -Host * - StrictHostKeyChecking no - UserKnownHostsFile /dev/null - LogLevel QUIET diff --git a/tools.go b/tools.go deleted file mode 100644 index 709bd3782..000000000 --- a/tools.go +++ /dev/null @@ -1,11 +0,0 @@ -//go:build tools -// +build tools - -package tools - -import ( - _ "github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-grpc-gateway" - _ "github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2" - _ "google.golang.org/grpc/cmd/protoc-gen-go-grpc" - _ "google.golang.org/protobuf/cmd/protoc-gen-go" -)