add restic integration for doing pod volume backups/restores

Signed-off-by: Steve Kriss <steve@heptio.com>
This commit is contained in:
Steve Kriss
2018-06-06 09:48:10 -07:00
parent c2c5b9040c
commit 50d4084fac
86 changed files with 5421 additions and 485 deletions
+10
View File
@@ -58,6 +58,10 @@ type Config struct {
// new backups that should be triggered based on schedules.
ScheduleSyncPeriod metav1.Duration `json:"scheduleSyncPeriod"`
// PodVolumeOperationTimeout is how long backups/restores of pod volumes (i.e.
// using restic) should be allowed to run before timing out.
PodVolumeOperationTimeout metav1.Duration `json:"podVolumeOperationTimeout"`
// ResourcePriorities is an ordered slice of resources specifying the desired
// order of resource restores. Any resources not in the list will be restored
// alphabetically after the prioritized resources.
@@ -86,4 +90,10 @@ type ObjectStorageProviderConfig struct {
// Bucket is the name of the bucket in object storage where Ark backups
// are stored.
Bucket string `json:"bucket"`
// ResticLocation is the bucket and optional prefix in object storage where
// Ark stores restic backups of pod volumes, specified either as "bucket" or
// "bucket/prefix". This bucket must be different than the `Bucket` field.
// Optional.
ResticLocation string `json:"resticLocation"`
}
-5
View File
@@ -33,11 +33,6 @@ const (
DeleteBackupRequestPhaseInProgress DeleteBackupRequestPhase = "InProgress"
// DeleteBackupRequestPhaseProcessed means the DeleteBackupRequest has been processed.
DeleteBackupRequestPhaseProcessed DeleteBackupRequestPhase = "Processed"
// BackupNameLabel is the label key used by a DeleteBackupRequest to identify its backup by name.
BackupNameLabel = "ark.heptio.com/backup-name"
// BackupUIDLabel is the label key used by a DeleteBackupRequest to identify its backup by uid.
BackupUIDLabel = "ark.heptio.com/backup-uid"
)
// DeleteBackupRequestStatus is the current status of a DeleteBackupRequest.
+39
View File
@@ -0,0 +1,39 @@
/*
Copyright 2018 the Heptio Ark contributors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package v1
const (
// BackupNameLabel is the label key used to identify a backup by name.
BackupNameLabel = "ark.heptio.com/backup-name"
// BackupUIDLabel is the label key used to identify a backup by uid.
BackupUIDLabel = "ark.heptio.com/backup-uid"
// RestoreNameLabel is the label key used to identify a restore by name.
RestoreNameLabel = "ark.heptio.com/restore-name"
// RestoreUIDLabel is the label key used to identify a restore by uid.
RestoreUIDLabel = "ark.heptio.com/restore-uid"
// PodUIDLabel is the label key used to identify a pod by uid.
PodUIDLabel = "ark.heptio.com/pod-uid"
// PodVolumeOperationTimeoutAnnotation is the annotation key used to apply
// a backup/restore-specific timeout value for pod volume operations (i.e.
// restic backups/restores).
PodVolumeOperationTimeoutAnnotation = "ark.heptio.com/pod-volume-timeout"
)
+88
View File
@@ -0,0 +1,88 @@
/*
Copyright 2018 the Heptio Ark contributors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package v1
import (
corev1api "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
// PodVolumeBackupSpec is the specification for a PodVolumeBackup.
type PodVolumeBackupSpec struct {
// Node is the name of the node that the Pod is running on.
Node string `json:"node"`
// Pod is a reference to the pod containing the volume to be backed up.
Pod corev1api.ObjectReference `json:"pod"`
// Volume is the name of the volume within the Pod to be backed
// up.
Volume string `json:"volume"`
// RepoPrefix is the restic repository prefix (i.e. not containing
// the repository name itself).
RepoPrefix string `json:"repoPrefix"`
// Tags are a map of key-value pairs that should be applied to the
// volume backup as tags.
Tags map[string]string `json:"tags"`
}
// PodVolumeBackupPhase represents the lifecycle phase of a PodVolumeBackup.
type PodVolumeBackupPhase string
const (
PodVolumeBackupPhaseNew PodVolumeBackupPhase = "New"
PodVolumeBackupPhaseInProgress PodVolumeBackupPhase = "InProgress"
PodVolumeBackupPhaseCompleted PodVolumeBackupPhase = "Completed"
PodVolumeBackupPhaseFailed PodVolumeBackupPhase = "Failed"
)
// PodVolumeBackupStatus is the current status of a PodVolumeBackup.
type PodVolumeBackupStatus struct {
// Phase is the current state of the PodVolumeBackup.
Phase PodVolumeBackupPhase `json:"phase"`
// Path is the full path within the controller pod being backed up.
Path string `json:"path"`
// SnapshotID is the identifier for the snapshot of the pod volume.
SnapshotID string `json:"snapshotID"`
// Message is a message about the pod volume backup's status.
Message string `json:"message"`
}
// +genclient
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
type PodVolumeBackup struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata"`
Spec PodVolumeBackupSpec `json:"spec"`
Status PodVolumeBackupStatus `json:"status,omitempty"`
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// PodVolumeBackupList is a list of PodVolumeBackups.
type PodVolumeBackupList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata"`
Items []PodVolumeBackup `json:"items"`
}
+77
View File
@@ -0,0 +1,77 @@
/*
Copyright 2018 the Heptio Ark contributors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package v1
import (
corev1api "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
// PodVolumeRestoreSpec is the specification for a PodVolumeRestore.
type PodVolumeRestoreSpec struct {
// Pod is a reference to the pod containing the volume to be restored.
Pod corev1api.ObjectReference `json:"pod"`
// Volume is the name of the volume within the Pod to be restored.
Volume string `json:"volume"`
// RepoPrefix is the restic repository prefix (i.e. not containing
// the repository name itself).
RepoPrefix string `json:"repoPrefix"`
// SnapshotID is the ID of the volume snapshot to be restored.
SnapshotID string `json:"snapshotID"`
}
// PodVolumeRestorePhase represents the lifecycle phase of a PodVolumeRestore.
type PodVolumeRestorePhase string
const (
PodVolumeRestorePhaseNew PodVolumeRestorePhase = "New"
PodVolumeRestorePhaseInProgress PodVolumeRestorePhase = "InProgress"
PodVolumeRestorePhaseCompleted PodVolumeRestorePhase = "Completed"
PodVolumeRestorePhaseFailed PodVolumeRestorePhase = "Failed"
)
// PodVolumeRestoreStatus is the current status of a PodVolumeRestore.
type PodVolumeRestoreStatus struct {
// Phase is the current state of the PodVolumeRestore.
Phase PodVolumeRestorePhase `json:"phase"`
// Message is a message about the pod volume restore's status.
Message string `json:"message"`
}
// +genclient
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
type PodVolumeRestore struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata"`
Spec PodVolumeRestoreSpec `json:"spec"`
Status PodVolumeRestoreStatus `json:"status,omitempty"`
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// PodVolumeRestoreList is a list of PodVolumeRestores.
type PodVolumeRestoreList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata"`
Items []PodVolumeRestore `json:"items"`
}
+4
View File
@@ -55,6 +55,10 @@ func addKnownTypes(scheme *runtime.Scheme) error {
&DownloadRequestList{},
&DeleteBackupRequest{},
&DeleteBackupRequestList{},
&PodVolumeBackup{},
&PodVolumeBackupList{},
&PodVolumeRestore{},
&PodVolumeRestoreList{},
)
metav1.AddToGroupVersion(scheme, SchemeGroupVersion)
return nil
+196
View File
@@ -340,6 +340,7 @@ func (in *Config) DeepCopyInto(out *Config) {
out.BackupSyncPeriod = in.BackupSyncPeriod
out.GCSyncPeriod = in.GCSyncPeriod
out.ScheduleSyncPeriod = in.ScheduleSyncPeriod
out.PodVolumeOperationTimeout = in.PodVolumeOperationTimeout
if in.ResourcePriorities != nil {
in, out := &in.ResourcePriorities, &out.ResourcePriorities
*out = make([]string, len(*in))
@@ -647,6 +648,201 @@ func (in *ObjectStorageProviderConfig) DeepCopy() *ObjectStorageProviderConfig {
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *PodVolumeBackup) DeepCopyInto(out *PodVolumeBackup) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
in.Spec.DeepCopyInto(&out.Spec)
out.Status = in.Status
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodVolumeBackup.
func (in *PodVolumeBackup) DeepCopy() *PodVolumeBackup {
if in == nil {
return nil
}
out := new(PodVolumeBackup)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *PodVolumeBackup) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *PodVolumeBackupList) DeepCopyInto(out *PodVolumeBackupList) {
*out = *in
out.TypeMeta = in.TypeMeta
out.ListMeta = in.ListMeta
if in.Items != nil {
in, out := &in.Items, &out.Items
*out = make([]PodVolumeBackup, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodVolumeBackupList.
func (in *PodVolumeBackupList) DeepCopy() *PodVolumeBackupList {
if in == nil {
return nil
}
out := new(PodVolumeBackupList)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *PodVolumeBackupList) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *PodVolumeBackupSpec) DeepCopyInto(out *PodVolumeBackupSpec) {
*out = *in
out.Pod = in.Pod
if in.Tags != nil {
in, out := &in.Tags, &out.Tags
*out = make(map[string]string, len(*in))
for key, val := range *in {
(*out)[key] = val
}
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodVolumeBackupSpec.
func (in *PodVolumeBackupSpec) DeepCopy() *PodVolumeBackupSpec {
if in == nil {
return nil
}
out := new(PodVolumeBackupSpec)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *PodVolumeBackupStatus) DeepCopyInto(out *PodVolumeBackupStatus) {
*out = *in
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodVolumeBackupStatus.
func (in *PodVolumeBackupStatus) DeepCopy() *PodVolumeBackupStatus {
if in == nil {
return nil
}
out := new(PodVolumeBackupStatus)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *PodVolumeRestore) DeepCopyInto(out *PodVolumeRestore) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
out.Spec = in.Spec
out.Status = in.Status
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodVolumeRestore.
func (in *PodVolumeRestore) DeepCopy() *PodVolumeRestore {
if in == nil {
return nil
}
out := new(PodVolumeRestore)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *PodVolumeRestore) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *PodVolumeRestoreList) DeepCopyInto(out *PodVolumeRestoreList) {
*out = *in
out.TypeMeta = in.TypeMeta
out.ListMeta = in.ListMeta
if in.Items != nil {
in, out := &in.Items, &out.Items
*out = make([]PodVolumeRestore, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodVolumeRestoreList.
func (in *PodVolumeRestoreList) DeepCopy() *PodVolumeRestoreList {
if in == nil {
return nil
}
out := new(PodVolumeRestoreList)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *PodVolumeRestoreList) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *PodVolumeRestoreSpec) DeepCopyInto(out *PodVolumeRestoreSpec) {
*out = *in
out.Pod = in.Pod
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodVolumeRestoreSpec.
func (in *PodVolumeRestoreSpec) DeepCopy() *PodVolumeRestoreSpec {
if in == nil {
return nil
}
out := new(PodVolumeRestoreSpec)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *PodVolumeRestoreStatus) DeepCopyInto(out *PodVolumeRestoreStatus) {
*out = *in
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodVolumeRestoreStatus.
func (in *PodVolumeRestoreStatus) DeepCopy() *PodVolumeRestoreStatus {
if in == nil {
return nil
}
out := new(PodVolumeRestoreStatus)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Restore) DeepCopyInto(out *Restore) {
*out = *in