Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
The diff you're trying to view is too large. We only load the first 3000 changed files.
19 changes: 17 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Build topolvm
FROM --platform=$BUILDPLATFORM golang:1.24-bookworm AS build-topolvm
FROM --platform=$BUILDPLATFORM golang:1.25-bookworm AS build-topolvm

# Get argument
ARG TOPOLVM_VERSION
Expand Down Expand Up @@ -27,7 +27,8 @@ COPY --from=build-topolvm /workdir/build/hypertopolvm /hypertopolvm
RUN ln -s hypertopolvm /lvmd \
&& ln -s hypertopolvm /topolvm-scheduler \
&& ln -s hypertopolvm /topolvm-node \
&& ln -s hypertopolvm /topolvm-controller
&& ln -s hypertopolvm /topolvm-controller \
&& ln -s hypertopolvm /topolvm-snapshotter

COPY --from=build-topolvm /workdir/LICENSE /LICENSE

Expand All @@ -49,6 +50,20 @@ RUN make csi-sidecars GOARCH=${TARGETARCH}
# TopoLVM container with sidecar
FROM topolvm AS topolvm-with-sidecar

# Install curl and bzip2
RUN set -x \
&& apt-get update \
&& apt-get install -y --no-install-recommends apt-transport-https ca-certificates curl bzip2 \
&& rm -rf /var/lib/apt/lists/*

# Download and install restic
ARG RESTIC_VERSION=0.18.1
RUN set -x \
&& curl -fsSL -o /tmp/restic.bz2 https://github.com/restic/restic/releases/download/v${RESTIC_VERSION}/restic_${RESTIC_VERSION}_linux_amd64.bz2 \
&& bzip2 -d /tmp/restic.bz2 \
&& mv /tmp/restic /bin/restic \
&& chmod 755 /bin/restic

COPY --from=build-sidecars /workdir/build/csi-provisioner /csi-provisioner
COPY --from=build-sidecars /workdir/build/csi-node-driver-registrar /csi-node-driver-registrar
COPY --from=build-sidecars /workdir/build/csi-resizer /csi-resizer
Expand Down
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ manifests: generate-legacy-api ## Generate WebhookConfiguration, ClusterRole and
output:crd:artifacts:config=config/crd/bases
cat config/crd/bases/topolvm.io_logicalvolumes.yaml | xargs -d" " printf "$$CRD_TEMPLATE" > charts/topolvm/templates/crds/topolvm.io_logicalvolumes.yaml
cat config/crd/bases/topolvm.cybozu.com_logicalvolumes.yaml | xargs -d" " printf "$$LEGACY_CRD_TEMPLATE" > charts/topolvm/templates/crds/topolvm.cybozu.com_logicalvolumes.yaml
cat config/crd/bases/topolvm.io_snapshotbackupstorages.yaml | xargs -d" " printf "$$CRD_TEMPLATE" > charts/topolvm/templates/crds/topolvm.io_snapshotbackupstorages.yaml

.PHONY: generate-api ## Generate code containing DeepCopy, DeepCopyInto, and DeepCopyObject method implementations.
generate-api:
Expand Down
68 changes: 68 additions & 0 deletions api/legacy/v1/backend_types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package v1

type S3Spec struct {
// Endpoint specifies the URL of the S3 or S3 compatible storage bucket.
Endpoint string `json:"endpoint,omitempty"`

// Bucket specifies the name of the bucket that will be used as storage backend.
Bucket string `json:"bucket,omitempty"`

// Prefix specifies a directory inside the bucket/container where the data for this backend will be stored.
Prefix string `json:"prefix,omitempty"`

// Region specifies the region where the bucket is located
// +optional
Region string `json:"region,omitempty"`

// SecretName specifies the name of the Secret that contains the access credential for this storage.
// Must be in the same namespace as TopoLVM components.
// +optional
SecretName string `json:"secretName,omitempty"`

// MaxConnections specifies the maximum number of concurrent connections to use to upload/download/delete data to this backend.
// +optional
MaxConnections int64 `json:"maxConnections,omitempty"`

// InsecureTLS controls whether a client should skip TLS certificate verification.
// Setting this field to true disables verification, which might be necessary in cases
// where the server uses self-signed certificates or certificates from an untrusted CA.
// Use this option with caution, as it can expose the client to man-in-the-middle attacks
// and other security risks. Only use it when absolutely necessary.
// +optional
InsecureTLS bool `json:"insecureTLS,omitempty"`
}

type GCSSpec struct {
// Bucket specifies the name of the bucket that will be used as storage backend.
Bucket string `json:"bucket,omitempty"`

// Prefix specifies a directory inside the bucket/container where the data for this backend will be stored.
Prefix string `json:"prefix,omitempty"`

// MaxConnections specifies the maximum number of concurrent connections to use to upload/download data to this backend.
// +optional
MaxConnections int64 `json:"maxConnections,omitempty"`

// SecretName specifies the name of the Secret that contains the access credential for this storage.
// +optional
SecretName string `json:"secretName,omitempty"`
}

type AzureSpec struct {
// StorageAccount specifies the name of the Azure Storage Account
StorageAccount string `json:"storageAccount,omitempty"`

// Container specifies the name of the Azure Blob container that will be used as storage backend.
Container string `json:"container,omitempty"`

// Prefix specifies a directory inside the bucket/container where the data for this backend will be stored.
Prefix string `json:"prefix,omitempty"`

// MaxConnections specifies the maximum number of concurrent connections to use to upload/download data to this backend.
// +optional
MaxConnections int64 `json:"maxConnections,omitempty"`

// SecretName specifies the name of the Secret that contains the access credential for this storage.
// +optional
SecretName string `json:"secretName,omitempty"`
}
138 changes: 138 additions & 0 deletions api/legacy/v1/constants.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
package v1

type StorageProvider string

const (
ProviderLocal StorageProvider = "local"
ProviderS3 StorageProvider = "s3"
ProviderGCS StorageProvider = "gcs"
ProviderAzure StorageProvider = "azure"
ProviderB2 StorageProvider = "b2"
ProviderSwift StorageProvider = "swift"
ProviderRest StorageProvider = "rest"
)

type BackupEngine string

const (
EngineRestic BackupEngine = "restic"
EngineKopia BackupEngine = "kopia"
)

const (
// PhaseReady Phase constants for SnapshotBackupStorage
PhaseReady = "Ready"
PhaseError = "Error"
)

const (
TopoLVMSnapshotter = "topolvm-snapshotter"
)

// OperationType distinguishes backup vs restore.
type OperationType string

const (
OperationBackup OperationType = "Backup"
OperationRestore OperationType = "Restore"
OperationDelete OperationType = "Delete"
)

// OperationPhase represents the current phase of a backup or restore operation.
type OperationPhase string

const (
// OperationPhasePending indicates that the operation has been accepted by the system, but has not yet begun.
OperationPhasePending OperationPhase = "Pending"
// OperationPhaseRunning indicates that the operation is currently running.
OperationPhaseRunning OperationPhase = "Running"
// OperationPhaseBackingUp indicates that a backup operation is in progress.
OperationPhaseBackingUp OperationPhase = "BackingUp"
// OperationPhaseRestoring indicates that a restore operation is in progress.
OperationPhaseRestoring OperationPhase = "Restoring"
// OperationPhaseSucceeded indicates that the operation completed successfully.
OperationPhaseSucceeded OperationPhase = "Succeeded"
// OperationPhaseCompleted indicates that the operation has completed successfully.
OperationPhaseCompleted OperationPhase = "Completed"
// OperationPhaseFailed indicates that the operation has failed.
OperationPhaseFailed OperationPhase = "Failed"
)

// TypeSnapshotBackupExecutorEnsured indicates whether the Snapshot Backup Executor is ensured or not.
const (
TypeSnapshotBackupExecutorEnsured = "SnapshotBackupExecutorEnsured"
ReasonSuccessfullyEnsuredSnapshotBackupExecutor = "SuccessfullyEnsuredSnapshotBackupExecutor"
ReasonFailedToEnsureSnapshotBackupExecutor = "FailedToEnsureSnapshotBackupExecutor"
)

// TypeSnapshotRestoreExecutorEnsured indicates whether the Snapshot Restore Executor is ensured or not.
const (
TypeSnapshotRestoreExecutorEnsured = "SnapshotRestoreExecutorEnsured"
ReasonSuccessfullyEnsuredSnapshotRestoreExecutor = "SuccessfullyEnsuredSnapshotRestoreExecutor"
ReasonFailedToEnsureSnapshotRestoreExecutor = "FailedToEnsureSnapshotRestoreExecutor"
)

// TypeSnapshotBackupExecutorCleanup indicates whether the Snapshot Backup Executor is cleaned or not.
const (
TypeSnapshotBackupExecutorCleaned = "SnapshotBackupExecutorCleaned"
ReasonSuccessfullyCleanedSnapshotBackupExecutor = "SuccessfullyCleanedSnapshotBackupExecutor"
ReasonFailedToCleanedSnapshotBackupExecutor = "FailedToCleanedSnapshotBackupExecutor"
)

// TypeSnapshotRestoreExecutorCleanup indicates whether the Snapshot Restore Executor is cleaned or not.
const (
TypeSnapshotRestoreExecutorCleaned = "SnapshotRestoreExecutorCleaned"
ReasonSuccessfullyCleanedSnapshotRestoreExecutor = "SuccessfullyCleanedSnapshotRestoreExecutor"
ReasonFailedToCleanedSnapshotRestoreExecutor = "FailedToCleanedSnapshotRestoreExecutor"
)

// TypeLVMSnapshotCleaned indicates whether the LVM snapshot volume has been removed after backup.
const (
TypeLVMSnapshotCleaned = "LVMSnapshotCleaned"
ReasonSuccessfullyCleanedLVMSnapshot = "SuccessfullyCleanedLVMSnapshot"
ReasonFailedToCleanLVMSnapshot = "FailedToCleanLVMSnapshot"
)

// TypeSnapshotDeleteExecutorEnsured indicates whether the Snapshot Delete Executor is ensured or not.
const (
TypeSnapshotDeleteExecutorEnsured = "SnapshotDeleteExecutorEnsured"
ReasonSuccessfullyEnsuredSnapshotDeleteExecutor = "SuccessfullyEnsuredSnapshotDeleteExecutor"
ReasonFailedToEnsureSnapshotDeleteExecutor = "FailedToEnsureSnapshotDeleteExecutor"
)

// Condition types for cleaning a LogicalVolume status
const (
TypeSnapshotDeleteEnsured = "SnapshotDeleteEnsured"
ConditionSnapshotDeleteRunning = "SnapshotDeleteRunning"
ConditionSnapshotDeleteSucceeded = "SnapshotDeleteSucceeded"
ConditionDeleteCleanupFailed = "SnapshotDeleteFailed"
)

// Condition types for LogicalVolume status
const (
// ConditionTypeBackupReady indicates that the backup operation is ready or completed successfully
ConditionTypeBackupReady string = "BackupReady"
// ConditionTypeRestoreReady indicates that the restore operation is ready or completed successfully
ConditionTypeRestoreReady string = "RestoreReady"
)

// Condition reasons for LogicalVolume operations
const (
// ReasonBackupInitialized indicates that backup has been initialized
ReasonBackupInitialized string = "BackupInitialized"
// ReasonBackupInProgress indicates that backup is currently in progress
ReasonBackupInProgress string = "BackupInProgress"
// ReasonBackupSucceeded indicates that backup completed successfully
ReasonBackupSucceeded string = "BackupSucceeded"
// ReasonBackupFailed indicates that backup failed
ReasonBackupFailed string = "BackupFailed"

// ReasonRestoreInitialized indicates that restore has been initialized
ReasonRestoreInitialized string = "RestoreInitialized"
// ReasonRestoreInProgress indicates that restore is currently in progress
ReasonRestoreInProgress string = "RestoreInProgress"
// ReasonRestoreSucceeded indicates that restore completed successfully
ReasonRestoreSucceeded string = "RestoreSucceeded"
// ReasonRestoreFailed indicates that restore failed
ReasonRestoreFailed string = "RestoreFailed"
)
73 changes: 73 additions & 0 deletions api/legacy/v1/logicalvolume_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,79 @@ type LogicalVolumeStatus struct {
Code codes.Code `json:"code,omitempty"`
Message string `json:"message,omitempty"`
CurrentSize *resource.Quantity `json:"currentSize,omitempty"`

// +optional
Conditions []metav1.Condition `json:"conditions,omitempty"`

// +optional
Snapshot *SnapshotStatus `json:"snapshot,omitempty"`
}

// SnapshotStatus defines the observed state of a backup or restore operation.
type SnapshotStatus struct {
// Operation indicates whether this status is for a backup or a restore.
// +optional
Operation OperationType `json:"operation,omitempty"`
// Phase represents the current phase of the backup or restore operation.
Phase OperationPhase `json:"phase"`
// StartTime is the time at which the operation was started.
StartTime metav1.Time `json:"startTime"`
// CompletionTime is the time at which the operation completed (success or failure).
// +optional
CompletionTime *metav1.Time `json:"completionTime,omitempty"`
// Duration is how long operation took to complete.
// +optional
Duration string `json:"duration,omitempty"`
// Progress contains information about the progress of the operation.
// +optional
Progress *OperationProgress `json:"progress,omitempty"`
// Message provides a short description of the snapshot’s state
// +optional
Message string `json:"message,omitempty"`
// Error contains details if the operation encountered an error.
// +optional
Error *SnapshotError `json:"error,omitempty"`
// Path represents the directory inside the SnapshotStorage where this backup was stored.
// +optional
Path string `json:"path,omitempty"`
// Repository is the Restic repository path/url where the snapshot is stored
// +optional
Repository string `json:"repository,omitempty"`
// SnapshotID is the identifier of the Restic snapshot involved in the operation.
// +optional
SnapshotID string `json:"snapshotID,omitempty"`
// Version keeps track of restic binary or backup engine version used
// +optional
Version string `json:"version,omitempty"`
}

type OperationProgress struct {
// +optional
TotalBytes int64 `json:"totalBytes,omitempty"`

// +optional
BytesDone int64 `json:"bytesDone,omitempty"`

// Percentage can be calculated by controller or client (UploadedBytes / TotalBytes * 100)
// +optional
Percentage string `json:"percentage,omitempty"`
}

type SnapshotError struct {
Code string `json:"code,omitempty"` // e.g., "RepositoryNotReachable", "VolumeMountFailed"
Message string `json:"message,omitempty"` // human-readable error
}

type BackupProgress struct {
// +optional
TotalBytes int64 `json:"totalBytes,omitempty"`

// +optional
BytesDone int64 `json:"bytesDone,omitempty"`

// Percentage can be calculated by controller or client (UploadedBytes / TotalBytes * 100)
// +optional
Percentage string `json:"percentage,omitempty"`
}

//+kubebuilder:object:root=true
Expand Down
Loading