Skip to content

Commit

Permalink
Refactor project structure
Browse files Browse the repository at this point in the history
Refactore the current project structure to reflect the current
conventions in Go. Create top-level packages for `api`, `cmd` and keep
the implementation details in the `internal` package.

Also bump golang version to 1.22 and update the `golangci-lint` to
v1.57.0.
  • Loading branch information
afritzler committed Mar 20, 2024
1 parent 3066391 commit 58e2dd6
Show file tree
Hide file tree
Showing 65 changed files with 314 additions and 342 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/golangci-lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,5 @@ jobs:
- name: golangci-lint
uses: golangci/golangci-lint-action@v4
with:
version: v1.54.2
version: v1.57.0
skip-pkg-cache: true
2 changes: 1 addition & 1 deletion .reuse/dep5
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ Files:
CONTRIBUTING.md
Dockerfile
Makefile
pkg/ceph/test.key
internal/ceph/test.key
mkdocs.yml
hack/*.sh
Copyright: 2023 SAP SE or an SAP affiliate company and IronCore contributors
Expand Down
11 changes: 6 additions & 5 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@ RUN --mount=type=cache,target=/root/.cache/go-build \
go mod download

# Copy the go source
COPY pkg/ pkg/
COPY iri/ iri/
COPY api/ api/
COPY internal/ internal/
COPY cmd/ cmd/
COPY hack/ hack/

ARG TARGETOS
Expand All @@ -22,7 +23,7 @@ ARG TARGETARCH
FROM builder as ceph-bucket-provider-builder
RUN --mount=type=cache,target=/root/.cache/go-build \
--mount=type=cache,target=/go/pkg \
CGO_ENABLED=0 GOOS=$TARGETOS GOARCH=$TARGETARCH GO111MODULE=on go build -ldflags="-s -w" -a -o bin/ceph-bucket-provider ./iri/bucket/cmd/bucket/main.go
CGO_ENABLED=0 GOOS=$TARGETOS GOARCH=$TARGETARCH GO111MODULE=on go build -ldflags="-s -w" -a -o bin/ceph-bucket-provider ./cmd/bucketprovider/main.go


# Start from Kubernetes Debian base.
Expand All @@ -34,7 +35,7 @@ RUN apt update && apt install -y libcephfs-dev librbd-dev librados-dev libc-bin
# Build
RUN --mount=type=cache,target=/root/.cache/go-build \
--mount=type=cache,target=/go/pkg \
CGO_ENABLED=1 GOOS=$TARGETOS GOARCH=$TARGETARCH GO111MODULE=on go build -ldflags="-s -w" -a -o bin/ceph-volume-provider ./iri/volume/cmd/volume/main.go
CGO_ENABLED=1 GOOS=$TARGETOS GOARCH=$TARGETARCH GO111MODULE=on go build -ldflags="-s -w" -a -o bin/ceph-volume-provider ./cmd/volumeprovider/main.go


# Use distroless as minimal base image to package the manager binary
Expand Down Expand Up @@ -125,4 +126,4 @@ ENTRYPOINT ["/ceph-volume-provider"]
FROM distroless-base as ceph-bucket-provider
COPY --from=ceph-bucket-provider-builder /workspace/bin/ceph-bucket-provider /ceph-bucket-provider
USER 65532:65532
ENTRYPOINT ["/ceph-bucket-provider"]
ENTRYPOINT ["/ceph-bucket-provider"]
24 changes: 16 additions & 8 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ help: ## Display this help.
.PHONY: manifests
manifests: controller-gen ## Generate WebhookConfiguration, ClusterRole and CustomResourceDefinition objects.
# bucket
$(CONTROLLER_GEN) rbac:roleName=broker-role paths="./iri/bucket/..." output:rbac:artifacts:config=config/ceph-bucket-provider/ceph-provider-rbac
$(CONTROLLER_GEN) rbac:roleName=broker-role paths="./internal/bucketserver/..." output:rbac:artifacts:config=config/ceph-bucket-provider/ceph-provider-rbac

.PHONY: generate
generate: controller-gen ## Generate code containing DeepCopy, DeepCopyInto, and DeepCopyObject method implementations.
Expand Down Expand Up @@ -76,8 +76,9 @@ add-license: addlicense ## Add license headers to all go files.
check-license: addlicense ## Check that every file has a license header present.
find . -name '*.go' -exec $(ADDLICENSE) -check -c 'IronCore authors' {} +

lint: ## Run golangci-lint against code.
golangci-lint run ./...
.PHONY: lint
lint: golangci-lint ## Run golangci-lint on the code.
$(GOLANGCI_LINT) run ./...

check: manifests generate check-license lint test

Expand All @@ -96,19 +97,19 @@ clean-docs: ## Remove all local mkdocs Docker images (cleanup).

.PHONY: build-volume
build-volume: generate fmt vet ## Build manager binary.
CGO_ENABLED=1 GO111MODULE=on go build -ldflags="-s -w" -a -o bin/ceph-volume-provider ./iri/volume/cmd/volume/main.go
CGO_ENABLED=1 GO111MODULE=on go build -ldflags="-s -w" -a -o bin/ceph-volume-provider ./cmd/volumeprovider/main.go

.PHONY: build-bucket
build-bucket: generate fmt vet ## Build manager binary.
CGO_ENABLED=0 GO111MODULE=on go build -ldflags="-s -w" -a -o bin/ceph-bucket-provider ./iri/bucket/cmd/bucket/main.go
CGO_ENABLED=0 GO111MODULE=on go build -ldflags="-s -w" -a -o bin/ceph-bucket-provider ./cmd/bucketprovider/main.go

.PHONY: run-volume
run-volume: manifests generate fmt vet ## Run a controller from your host.
go run ./iri/bucket/cmd/volume/main.go
go run ./cmd/volumeprovider/main.go

.PHONY: run-bucket
run-bucket: manifests generate fmt vet ## Run a controller from your host.
go run ./iri/bucket/cmd/bucket/main.go
go run ./cmd/bucketprovider/main.go

.PHONY: docker-build
docker-build: test ## Build docker image with the manager.
Expand Down Expand Up @@ -139,11 +140,13 @@ KUSTOMIZE ?= $(LOCALBIN)/kustomize
CONTROLLER_GEN ?= $(LOCALBIN)/controller-gen
ENVTEST ?= $(LOCALBIN)/setup-envtest
ADDLICENSE ?= $(LOCALBIN)/addlicense
GOLANGCI_LINT ?= $(LOCALBIN)/golangci-lint

## Tool Versions
KUSTOMIZE_VERSION ?= v3.8.7
CONTROLLER_TOOLS_VERSION ?= v0.13.0
CONTROLLER_TOOLS_VERSION ?= v0.14.0
ADDLICENSE_VERSION ?= v1.1.1
GOLANGCI_LINT_VERSION ?= v1.57.0

KUSTOMIZE_INSTALL_SCRIPT ?= "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh"
.PHONY: kustomize
Expand All @@ -165,3 +168,8 @@ $(ENVTEST): $(LOCALBIN)
addlicense: $(ADDLICENSE) ## Download addlicense locally if necessary.
$(ADDLICENSE): $(LOCALBIN)
test -s $(LOCALBIN)/addlicense || GOBIN=$(LOCALBIN) go install github.com/google/addlicense@$(ADDLICENSE_VERSION)

.PHONY: golangci-lint
golangci-lint: $(GOLANGCI_LINT) ## Download golangci-lint locally if necessary.
$(GOLANGCI_LINT): $(LOCALBIN)
test -s $(LOCALBIN)/golangci-lint || GOBIN=$(LOCALBIN) go install github.com/golangci/golangci-lint/cmd/golangci-lint@$(GOLANGCI_LINT_VERSION)
File renamed without changes.
5 changes: 3 additions & 2 deletions iri/volume/apiutils/constants.go → api/constants.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
// SPDX-FileCopyrightText: 2022 SAP SE or an SAP affiliate company and IronCore contributors
// SPDX-License-Identifier: Apache-2.0

package apiutils
package api

const (
LabelsAnnotation = "ceph-provider.ironcore.dev/labels"
AnnotationsAnnotation = "ceph-provider.ironcore.dev/annotations"
ManagerLabel = "ceph-provider.ironcore.dev/manager"
ClassLabel = "ceph-provider.ironcore.dev/class"
ManagerLabel = "ceph-provider.ironcore.dev/manager"
BucketManager = "ceph-bucket-provider"
VolumeManager = "ceph-volume-provider"
)
File renamed without changes.
File renamed without changes.
103 changes: 102 additions & 1 deletion iri/bucket/apiutils/apiutils.go → api/utils.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: 2022 SAP SE or an SAP affiliate company and IronCore contributors
// SPDX-License-Identifier: Apache-2.0

package apiutils
package api

import (
"encoding/json"
Expand Down Expand Up @@ -112,3 +112,104 @@ func IsManagedBy(o metav1.Object, manager string) bool {
actual, ok := o.GetLabels()[ManagerLabel]
return ok && actual == manager
}

func GetObjectMetadataFromObjectID(o Metadata) (*irimeta.ObjectMetadata, error) {
annotations, err := GetAnnotationsAnnotationForMetadata(o)
if err != nil {
return nil, err
}

labels, err := GetLabelsAnnotationForMetadata(o)
if err != nil {
return nil, err
}

var deletedAt int64
if o.DeletedAt != nil && !o.DeletedAt.IsZero() {
deletedAt = o.DeletedAt.UnixNano()
}

return &irimeta.ObjectMetadata{
Id: o.ID,
Annotations: annotations,
Labels: labels,
Generation: o.GetGeneration(),
CreatedAt: o.CreatedAt.UnixNano(),
DeletedAt: deletedAt,
}, nil
}

func GetAnnotationsAnnotationForMetadata(o Metadata) (map[string]string, error) {
data, ok := o.GetAnnotations()[AnnotationsAnnotation]
if !ok {
return nil, fmt.Errorf("object has no annotations at %s", AnnotationsAnnotation)
}

var annotations map[string]string
if err := json.Unmarshal([]byte(data), &annotations); err != nil {
return nil, err
}

return annotations, nil
}

func GetLabelsAnnotationForMetadata(o Metadata) (map[string]string, error) {
data, ok := o.GetAnnotations()[LabelsAnnotation]
if !ok {
return nil, fmt.Errorf("object has no labels at %s", LabelsAnnotation)
}

var labels map[string]string
if err := json.Unmarshal([]byte(data), &labels); err != nil {
return nil, err
}

return labels, nil
}

func GetClassLabelFromObject(o Object) (string, bool) {
class, found := o.GetLabels()[ClassLabel]
return class, found
}

func SetObjectMetadataFromMetadata(o Object, metadata *irimeta.ObjectMetadata) error {
if err := SetAnnotationsAnnotationForObject(o, metadata.Annotations); err != nil {
return err
}
if err := SetLabelsAnnotationForOject(o, metadata.Labels); err != nil {
return err
}
return nil
}

func SetLabelsAnnotationForOject(o Object, labels map[string]string) error {
data, err := json.Marshal(labels)
if err != nil {
return fmt.Errorf("error marshalling labels: %w", err)
}
metautils.SetAnnotation(o, LabelsAnnotation, string(data))
return nil
}

func SetAnnotationsAnnotationForObject(o Object, annotations map[string]string) error {
data, err := json.Marshal(annotations)
if err != nil {
return fmt.Errorf("error marshalling annotations: %w", err)
}
metautils.SetAnnotation(o, AnnotationsAnnotation, string(data))

return nil
}

func SetClassLabelForObject(o Object, class string) {
metautils.SetLabel(o, ClassLabel, class)
}

func IsObjectManagedBy(o Object, manager string) bool {
actual, ok := o.GetLabels()[ManagerLabel]
return ok && actual == manager
}

func SetManagerLabel(o Object, manager string) {
metautils.SetLabel(o, ManagerLabel, manager)
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,16 @@ import (
"fmt"
"net"

"github.com/ironcore-dev/ceph-provider/internal/bcr"
"github.com/ironcore-dev/ceph-provider/internal/bucketserver"
"github.com/ironcore-dev/controller-utils/configutils"
"github.com/ironcore-dev/ironcore/broker/common"
iriv1alpha1 "github.com/ironcore-dev/ironcore/iri/apis/bucket/v1alpha1"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
"google.golang.org/grpc"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/log/zap"

"github.com/ironcore-dev/ceph-provider/pkg/bcr"

"github.com/ironcore-dev/ceph-provider/iri/bucket/server"
"github.com/ironcore-dev/controller-utils/configutils"
"github.com/ironcore-dev/ironcore/broker/common"
iri "github.com/ironcore-dev/ironcore/iri/apis/bucket/v1alpha1"
)

type Options struct {
Expand Down Expand Up @@ -99,7 +97,7 @@ func Run(ctx context.Context, opts Options) error {
return fmt.Errorf("failed to initialize bucket class registry: %w", err)
}

srv, err := server.New(cfg, classRegistry, server.Options{
srv, err := bucketserver.New(cfg, classRegistry, bucketserver.Options{
Namespace: opts.Namespace,
BucketPoolStorageClassName: opts.BucketPoolStorageClassName,
BucketClassSelector: opts.BucketClassSelector,
Expand Down Expand Up @@ -137,7 +135,7 @@ func Run(ctx context.Context, opts Options) error {
return resp, err
}),
)
iri.RegisterBucketRuntimeServer(grpcSrv, srv)
iriv1alpha1.RegisterBucketRuntimeServer(grpcSrv, srv)

setupLog.Info("Starting server", "Address", l.Addr().String())
go func() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (
"fmt"
"os"

"github.com/ironcore-dev/ceph-provider/iri/volume/cmd/volume/app"
"github.com/ironcore-dev/ceph-provider/cmd/bucketprovider/app"
ctrl "sigs.k8s.io/controller-runtime"
)

Expand Down
42 changes: 21 additions & 21 deletions iri/volume/cmd/volume/app/app.go → cmd/volumeprovider/app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,18 @@ import (
"sync"
"time"

"github.com/ironcore-dev/ceph-provider/iri/volume/server"
"github.com/ironcore-dev/ceph-provider/pkg/api"
"github.com/ironcore-dev/ceph-provider/pkg/ceph"
"github.com/ironcore-dev/ceph-provider/pkg/controllers"
"github.com/ironcore-dev/ceph-provider/pkg/encryption"
"github.com/ironcore-dev/ceph-provider/pkg/event"
"github.com/ironcore-dev/ceph-provider/pkg/omap"
"github.com/ironcore-dev/ceph-provider/pkg/utils"
"github.com/ironcore-dev/ceph-provider/pkg/vcr"
providerapi "github.com/ironcore-dev/ceph-provider/api"
"github.com/ironcore-dev/ceph-provider/internal/ceph"
"github.com/ironcore-dev/ceph-provider/internal/controllers"
"github.com/ironcore-dev/ceph-provider/internal/encryption"
"github.com/ironcore-dev/ceph-provider/internal/event"
"github.com/ironcore-dev/ceph-provider/internal/omap"
"github.com/ironcore-dev/ceph-provider/internal/snapshotstrategy"
"github.com/ironcore-dev/ceph-provider/internal/vcr"
"github.com/ironcore-dev/ceph-provider/internal/volumeserver"
"github.com/ironcore-dev/ironcore-image/oci/remote"
"github.com/ironcore-dev/ironcore/broker/common"
iri "github.com/ironcore-dev/ironcore/iri/apis/volume/v1alpha1"
iriv1alpha1 "github.com/ironcore-dev/ironcore/iri/apis/volume/v1alpha1"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
"google.golang.org/grpc"
Expand Down Expand Up @@ -192,16 +192,16 @@ func Run(ctx context.Context, opts Options) error {
}

setupLog.Info("Configuring image store", "OmapName", omap.OmapNameVolumes)
imageStore, err := omap.New(conn, opts.Ceph.Pool, omap.Options[*api.Image]{
imageStore, err := omap.New(conn, opts.Ceph.Pool, omap.Options[*providerapi.Image]{
OmapName: omap.OmapNameVolumes,
NewFunc: func() *api.Image { return &api.Image{} },
CreateStrategy: utils.ImageStrategy,
NewFunc: func() *providerapi.Image { return &providerapi.Image{} },
CreateStrategy: snapshotstrategy.ImageStrategy,
})
if err != nil {
return fmt.Errorf("failed to initialize image store: %w", err)
}

imageEvents, err := event.NewListWatchSource[*api.Image](
imageEvents, err := event.NewListWatchSource[*providerapi.Image](
imageStore.List,
imageStore.Watch,
event.ListWatchSourceOptions{},
Expand All @@ -211,16 +211,16 @@ func Run(ctx context.Context, opts Options) error {
}

setupLog.Info("Configuring snapshot store", "OmapName", omap.OmapNameOsImages)
snapshotStore, err := omap.New(conn, opts.Ceph.Pool, omap.Options[*api.Snapshot]{
snapshotStore, err := omap.New(conn, opts.Ceph.Pool, omap.Options[*providerapi.Snapshot]{
OmapName: omap.OmapNameOsImages,
NewFunc: func() *api.Snapshot { return &api.Snapshot{} },
CreateStrategy: utils.SnapshotStrategy,
NewFunc: func() *providerapi.Snapshot { return &providerapi.Snapshot{} },
CreateStrategy: snapshotstrategy.SnapshotStrategy,
})
if err != nil {
return fmt.Errorf("failed to initialize snapshot store: %w", err)
}

snapshotEvents, err := event.NewListWatchSource[*api.Snapshot](
snapshotEvents, err := event.NewListWatchSource[*providerapi.Snapshot](
snapshotStore.List,
snapshotStore.Watch,
event.ListWatchSourceOptions{},
Expand Down Expand Up @@ -319,13 +319,13 @@ func Run(ctx context.Context, opts Options) error {
return fmt.Errorf("failed to initialize ceph command client: %w", err)
}

srv, err := server.New(
srv, err := volumeserver.New(
imageStore,
snapshotStore,
classRegistry,
encryptor,
cephCommandClient,
server.Options{
volumeserver.Options{
BurstFactor: opts.Ceph.BurstFactor,
BurstDurationInSeconds: opts.Ceph.BurstDurationInSeconds,
},
Expand Down Expand Up @@ -362,7 +362,7 @@ func Run(ctx context.Context, opts Options) error {
return resp, err
}),
)
iri.RegisterVolumeRuntimeServer(grpcSrv, srv)
iriv1alpha1.RegisterVolumeRuntimeServer(grpcSrv, srv)

setupLog.Info("Starting server", "Address", l.Addr().String())
go func() {
Expand Down
Loading

0 comments on commit 58e2dd6

Please sign in to comment.