diff --git a/README.md b/README.md index 0913c5501..664b9d888 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ -[![Go Report Card](https://goreportcard.com/badge/github.com/appscode/restik)](https://goreportcard.com/report/github.com/appscode/restik) +[![Go Report Card](https://goreportcard.com/badge/github.com/appscode/stash)](https://goreportcard.com/report/github.com/appscode/stash) -## Restik - Restik provides support to backup your Kubernetes Volumes +## Stash + Stash provides support to backup your Kubernetes Volumes **Feautures** - Support backup for any kubernetes [volumes](https://kubernetes.io/docs/concepts/storage/volumes/). @@ -10,7 +10,7 @@ Kubernetes 1.5+ ## Supported Workloads -Restik supports backup of following Workloads +Stash supports backup of following Workloads * Replication Controller * Replica Set @@ -27,7 +27,7 @@ One can start the backup process by following this [guide](docs/user-guide/backu ## How to recover -The recover process will be left to users for now. It can be done by running `$ /restic -r restore snapshot_id --target ` inside the restic-sidecar container. +The recover process will be left to users for now. It can be done by running `$ /restic -r restore snapshot_id --target ` inside the restic-sidecar container. You can find the details [here](https://restic.readthedocs.io/en/stable/Manual/#restore-a-snapshot) ## Developer Guide @@ -38,17 +38,17 @@ If you want to know how Backup Controller is working, read this [doc](docs/devel ## Versioning Policy There are 2 parts to versioning policy: - - Operator version: Restik __does not follow semver__, rather the _major_ version of operator points to the + - Operator version: Stash __does not follow semver__, rather the _major_ version of operator points to the Kubernetes [client-go](https://github.com/kubernetes/client-go#branches-and-tags) version. You can verify this from the `glide.yaml` file. This means there might be breaking changes between point releases of the operator. This generally manifests as changed annotation keys or their meaning. Please always check the release notes for upgrade instructions. - - TPR version: backup.appscode.com/v1alpha1 is considered in alpha. This means breaking changes to the YAML format + - TPR version: stash.appscode.com/v1alpha1 is considered in alpha. This means breaking changes to the YAML format might happen among different releases of the operator. --- -**The restik operator collects anonymous usage statistics to help us learn how the software is being used and how we can improve it. To disable stats collection, run the operator with the flag** `--analytics=false`. +**The stash operator collects anonymous usage statistics to help us learn how the software is being used and how we can improve it. To disable stats collection, run the operator with the flag** `--analytics=false`. --- diff --git a/api/extensions/restik.yaml b/api/extensions/restik.yaml deleted file mode 100644 index dd97dc61e..000000000 --- a/api/extensions/restik.yaml +++ /dev/null @@ -1,7 +0,0 @@ -apiVersion: extensions/v1beta1 -kind: ThirdPartyResource -metadata: - name: restik.backup.appscode.com -description: "Backup and restore support for Kubernetes persistent volumes by AppsCode" -versions: - - name: v1alpha1 diff --git a/api/extensions/stash.yaml b/api/extensions/stash.yaml new file mode 100644 index 000000000..f85fe49ef --- /dev/null +++ b/api/extensions/stash.yaml @@ -0,0 +1,7 @@ +apiVersion: extensions/v1beta1 +kind: ThirdPartyResource +metadata: + name: restic.stash.appscode.com +description: "Stash by AppsCode - Backup Kubernetes persistent volumes" +versions: + - name: v1alpha1 diff --git a/api/install/install.go b/api/install/install.go index 526367d13..04667bd24 100644 --- a/api/install/install.go +++ b/api/install/install.go @@ -1,7 +1,7 @@ package install import ( - rapi "github.com/appscode/restik/api" + rapi "github.com/appscode/stash/api" "k8s.io/apimachinery/pkg/apimachinery/announced" "k8s.io/apimachinery/pkg/util/sets" "k8s.io/client-go/pkg/api" @@ -12,7 +12,7 @@ func init() { &announced.GroupMetaFactoryArgs{ GroupName: rapi.GroupName, VersionPreferenceOrder: []string{rapi.V1alpha1SchemeGroupVersion.Version}, - ImportPrefix: "github.com/appscode/restik/api", + ImportPrefix: "github.com/appscode/stash/api", RootScopedKinds: sets.NewString("ThirdPartyResource"), AddInternalObjectsToScheme: rapi.AddToScheme, }, diff --git a/api/register.go b/api/register.go index 736a4f394..37cfcc454 100644 --- a/api/register.go +++ b/api/register.go @@ -30,13 +30,13 @@ var ( // Adds the list of known types to apiv1.Scheme. func addKnownTypes(scheme *runtime.Scheme) error { scheme.AddKnownTypes(SchemeGroupVersion, - &Restik{}, - &RestikList{}, + &Restic{}, + &ResticList{}, &metav1.ListOptions{}, ) return nil } -func (obj *Restik) GetObjectKind() schema.ObjectKind { return &obj.TypeMeta } -func (obj *RestikList) GetObjectKind() schema.ObjectKind { return &obj.TypeMeta } +func (obj *Restic) GetObjectKind() schema.ObjectKind { return &obj.TypeMeta } +func (obj *ResticList) GetObjectKind() schema.ObjectKind { return &obj.TypeMeta } diff --git a/api/register_v1alpha1.go b/api/register_v1alpha1.go index 94f77a326..a6f5f5f23 100644 --- a/api/register_v1alpha1.go +++ b/api/register_v1alpha1.go @@ -17,8 +17,8 @@ var ( // Adds the list of known types to api.Scheme. func v1addKnownTypes(scheme *runtime.Scheme) error { scheme.AddKnownTypes(V1alpha1SchemeGroupVersion, - &Restik{}, - &RestikList{}, + &Restic{}, + &ResticList{}, &metav1.ListOptions{}, ) diff --git a/api/restik_types.go b/api/restic_types.go similarity index 89% rename from api/restik_types.go rename to api/restic_types.go index 2b8ff7efc..236a2261b 100644 --- a/api/restik_types.go +++ b/api/restic_types.go @@ -16,14 +16,14 @@ const ( KeepYearly RetentionStrategy = "keep-yearly" ) -type Restik struct { +type Restic struct { metav1.TypeMeta `json:",inline,omitempty"` metav1.ObjectMeta `json:"metadata,omitempty"` - Spec RestikSpec `json:"spec,omitempty"` - Status RestikStatus `json:"status,omitempty"` + Spec ResticSpec `json:"spec,omitempty"` + Status ResticStatus `json:"status,omitempty"` } -type RestikSpec struct { +type ResticSpec struct { // Source of the backup volumeName:path Source Source `json:"source"` // Destination of the backup @@ -36,7 +36,7 @@ type RestikSpec struct { RetentionPolicy RetentionPolicy `json:"retentionPolicy,omitempty"` } -type RestikStatus struct { +type ResticStatus struct { FirstBackupTime *metav1.Time `json:"firstBackupTime,omitempty"` LastBackupTime *metav1.Time `json:"lastBackupTime,omitempty"` LastSuccessfulBackupTime *metav1.Time `json:"lastSuccessfulBackupTime,omitempty"` @@ -44,10 +44,10 @@ type RestikStatus struct { BackupCount int64 `json:"backupCount,omitempty"` } -type RestikList struct { +type ResticList struct { metav1.TypeMeta `json:",inline"` metav1.ListMeta `json:"metadata,omitempty"` - Items []Restik `json:"items,omitempty"` + Items []Restic `json:"items,omitempty"` } type Source struct { diff --git a/chart/restik/Chart.yaml b/chart/restik/Chart.yaml index ce68c1ac4..e81f39f69 100755 --- a/chart/restik/Chart.yaml +++ b/chart/restik/Chart.yaml @@ -1,10 +1,10 @@ apiVersion: v1 -description: Restik provides controller that takes backup of kubernetes volume. -icon: https://cdn.appscode.com/images/icon/restik.png -name: restik +description: Stash provides controller that takes backup of kubernetes volume. +icon: https://cdn.appscode.com/images/icon/stash.png +name: stash version: 0.1.0 sources: - - https://github.com/appscode/restik + - https://github.com/appscode/stash maintainers: - - name: 'AppsCode Inc.' + - name: appscode email: support@appscode.com diff --git a/chart/restik/README.md b/chart/restik/README.md index cbab71801..55cf042e7 100644 --- a/chart/restik/README.md +++ b/chart/restik/README.md @@ -1,14 +1,14 @@ -# Restik -[Restik](https://github.com/appscode/restik) provides support to backup your Kubernetes Volumes +# Stash +[Stash](https://github.com/appscode/stash) provides support to backup your Kubernetes Volumes ## TL;DR; ```bash -$ helm install hack/chart/restik +$ helm install chart/stash ``` ## Introduction -This chart bootstraps a [Restik controller](https://github.com/appscode/restik) deployment on a [Kubernetes](http://kubernetes.io) cluster using the [Helm](https://helm.sh) package manager. +This chart bootstraps a [Stash controller](https://github.com/appscode/stash) deployment on a [Kubernetes](http://kubernetes.io) cluster using the [Helm](https://helm.sh) package manager. ## Prerequisites @@ -17,9 +17,9 @@ This chart bootstraps a [Restik controller](https://github.com/appscode/restik) ## Installing the Chart To install the chart with the release name `my-release`: ```bash -$ helm install --name my-release hack/chart/restik +$ helm install --name my-release chart/stash ``` -The command deploys Restik Controller on the Kubernetes cluster in the default configuration. The [configuration](#configuration) section lists the parameters that can be configured during installation. +The command deploys Stash Controller on the Kubernetes cluster in the default configuration. The [configuration](#configuration) section lists the parameters that can be configured during installation. > **Tip**: List all releases using `helm list` @@ -35,10 +35,10 @@ The command removes all the Kubernetes components associated with the chart and ## Configuration -The following tables lists the configurable parameters of the Restik chart and their default values. +The following tables lists the configurable parameters of the Stash chart and their default values. | Parameter | Description | Default | | ----------------------- | ---------------------- | ------------------- | -| `image` | Container image to run | `appscode/restik` | +| `image` | Container image to run | `appscode/stash` | | `imageTag` | Image tag of container | `latest` | diff --git a/chart/restik/templates/NOTES.txt b/chart/restik/templates/NOTES.txt index d0227edcb..3518e04a0 100644 --- a/chart/restik/templates/NOTES.txt +++ b/chart/restik/templates/NOTES.txt @@ -1,3 +1,3 @@ -To verify that Restik has started, run: +To verify that Stash has started, run: kubectl --namespace={{ .Release.Namespace }} get deployments -l "release={{ .Release.Name }}, app={{ template "fullname" . }}" \ No newline at end of file diff --git a/chart/restik/values.yaml b/chart/restik/values.yaml index e73c617ea..ce8a6cf23 100644 --- a/chart/restik/values.yaml +++ b/chart/restik/values.yaml @@ -1,8 +1,8 @@ ## -## Restik chart configuration +## Stash chart configuration ## -## Image that will be used in Restik controller and in Restik sidecar container +## Image that will be used in Stash controller and in Stash sidecar container -image: appscode/restik +image: appscode/stash imageTag: latest diff --git a/client/clientset/codec.go b/client/clientset/codec.go index 87dbca5c5..0968d80a8 100644 --- a/client/clientset/codec.go +++ b/client/clientset/codec.go @@ -8,7 +8,7 @@ import ( "strings" "github.com/appscode/log" - rapi "github.com/appscode/restik/api" + sapi "github.com/appscode/stash/api" "github.com/ghodss/yaml" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" @@ -149,8 +149,8 @@ func (c *extendedCodec) EncodeParameters(obj runtime.Object, to schema.GroupVers func setDefaultVersionKind(obj runtime.Object) { // Check the values can are In type Extended Ingress defaultGVK := schema.GroupVersionKind{ - Group: rapi.V1alpha1SchemeGroupVersion.Group, - Version: rapi.V1alpha1SchemeGroupVersion.Version, + Group: sapi.V1alpha1SchemeGroupVersion.Group, + Version: sapi.V1alpha1SchemeGroupVersion.Version, } fullyQualifiedKind := reflect.ValueOf(obj).Type().String() diff --git a/client/clientset/extensions.go b/client/clientset/extensions.go index fc0261fa9..bc08be9a3 100644 --- a/client/clientset/extensions.go +++ b/client/clientset/extensions.go @@ -3,6 +3,7 @@ package clientset import ( "fmt" + sapi "github.com/appscode/stash/api" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/client-go/pkg/api" "k8s.io/client-go/rest" @@ -14,7 +15,7 @@ const ( type ExtensionInterface interface { RESTClient() rest.Interface - RestikNamespacer + ResticGetter } // ExtensionsClient is used to interact with experimental Kubernetes features. @@ -26,8 +27,8 @@ type ExtensionClient struct { var _ ExtensionInterface = &ExtensionClient{} -func (a *ExtensionClient) Restiks(namespace string) RestikInterface { - return newRestik(a, namespace) +func (c *ExtensionClient) Restics(namespace string) ResticInterface { + return newRestic(c, namespace) } // NewForConfig creates a new ExtensionClient for the given config. This client @@ -64,21 +65,21 @@ func New(c rest.Interface) *ExtensionClient { } func setExtensionsDefaults(config *rest.Config) error { - gv, err := schema.ParseGroupVersion("backup.appscode.com/v1alpha1") + gv, err := schema.ParseGroupVersion(sapi.GroupName + "/v1alpha1") if err != nil { return err } - // if backup.appscode.com/v1alpha1 is not enabled, return an error + // if stash.appscode.com/v1alpha1 is not enabled, return an error if !api.Registry.IsEnabledVersion(gv) { - return fmt.Errorf("backup.appscode.com/v1alpha1 is not enabled") + return fmt.Errorf(sapi.GroupName + "/v1alpha1 is not enabled") } config.APIPath = defaultAPIPath if config.UserAgent == "" { config.UserAgent = rest.DefaultKubernetesUserAgent() } - if config.GroupVersion == nil || config.GroupVersion.Group != "backup.appscode.com" { - g, err := api.Registry.Group("backup.appscode.com") + if config.GroupVersion == nil || config.GroupVersion.Group != sapi.GroupName { + g, err := api.Registry.Group(sapi.GroupName) if err != nil { return err } diff --git a/client/clientset/fake/extensions.go b/client/clientset/fake/extensions.go index 58740f345..e632d0a81 100644 --- a/client/clientset/fake/extensions.go +++ b/client/clientset/fake/extensions.go @@ -1,7 +1,8 @@ package fake import ( - "github.com/appscode/restik/client/clientset" + sapi "github.com/appscode/stash/api" + "github.com/appscode/stash/client/clientset" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/watch" "k8s.io/client-go/pkg/api" @@ -15,10 +16,10 @@ type FakeExtensionClient struct { var _ clientset.ExtensionInterface = &FakeExtensionClient{} -func NewFakeRestikClient(objects ...runtime.Object) *FakeExtensionClient { +func NewFakeStashClient(objects ...runtime.Object) *FakeExtensionClient { o := testing.NewObjectTracker(api.Registry, api.Scheme, api.Codecs.UniversalDecoder()) for _, obj := range objects { - if obj.GetObjectKind().GroupVersionKind().Group == "backup.appscode.com" { + if obj.GetObjectKind().GroupVersionKind().Group == sapi.GroupName { if err := o.Add(obj); err != nil { panic(err) } @@ -33,8 +34,8 @@ func NewFakeRestikClient(objects ...runtime.Object) *FakeExtensionClient { return &FakeExtensionClient{&fakePtr} } -func (m *FakeExtensionClient) Restiks(ns string) clientset.RestikInterface { - return &FakeRestik{m.Fake, ns} +func (m *FakeExtensionClient) Restics(ns string) clientset.ResticInterface { + return &FakeStash{m.Fake, ns} } // RESTClient returns a RESTClient that is used to communicate diff --git a/client/clientset/fake/restic.go b/client/clientset/fake/restic.go new file mode 100644 index 000000000..61c4eb6cf --- /dev/null +++ b/client/clientset/fake/restic.go @@ -0,0 +1,98 @@ +package fake + +import ( + sapi "github.com/appscode/stash/api" + "github.com/appscode/stash/client/clientset" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/testing" +) + +type FakeStash struct { + Fake *testing.Fake + ns string +} + +var stashResource = schema.GroupVersionResource{Group: sapi.GroupName, Version: "v1alpha1", Resource: "stashs"} + +var _ clientset.ResticInterface = &FakeStash{} + +// Get returns the Stashs by name. +func (mock *FakeStash) Get(name string) (*sapi.Restic, error) { + obj, err := mock.Fake. + Invokes(testing.NewGetAction(stashResource, mock.ns, name), &sapi.Restic{}) + + if obj == nil { + return nil, err + } + return obj.(*sapi.Restic), err +} + +// List returns the a of Stashs. +func (mock *FakeStash) List(opts metav1.ListOptions) (*sapi.ResticList, error) { + obj, err := mock.Fake. + Invokes(testing.NewListAction(stashResource, mock.ns, opts), &sapi.Restic{}) + + if obj == nil { + return nil, err + } + + label, _, _ := testing.ExtractFromListOptions(opts) + if label == nil { + label = labels.Everything() + } + list := &sapi.ResticList{} + for _, item := range obj.(*sapi.ResticList).Items { + if label.Matches(labels.Set(item.Labels)) { + list.Items = append(list.Items, item) + } + } + return list, err +} + +// Create creates a new Stash. +func (mock *FakeStash) Create(svc *sapi.Restic) (*sapi.Restic, error) { + obj, err := mock.Fake. + Invokes(testing.NewCreateAction(stashResource, mock.ns, svc), &sapi.Restic{}) + + if obj == nil { + return nil, err + } + return obj.(*sapi.Restic), err +} + +// Update updates a Stash. +func (mock *FakeStash) Update(svc *sapi.Restic) (*sapi.Restic, error) { + obj, err := mock.Fake. + Invokes(testing.NewUpdateAction(stashResource, mock.ns, svc), &sapi.Restic{}) + + if obj == nil { + return nil, err + } + return obj.(*sapi.Restic), err +} + +// Delete deletes a Stash by name. +func (mock *FakeStash) Delete(name string, _ *metav1.DeleteOptions) error { + _, err := mock.Fake. + Invokes(testing.NewDeleteAction(stashResource, mock.ns, name), &sapi.Restic{}) + + return err +} + +func (mock *FakeStash) UpdateStatus(srv *sapi.Restic) (*sapi.Restic, error) { + obj, err := mock.Fake. + Invokes(testing.NewUpdateSubresourceAction(stashResource, "status", mock.ns, srv), &sapi.Restic{}) + + if obj == nil { + return nil, err + } + return obj.(*sapi.Restic), err +} + +func (mock *FakeStash) Watch(opts metav1.ListOptions) (watch.Interface, error) { + return mock.Fake. + InvokesWatch(testing.NewWatchAction(stashResource, mock.ns, opts)) +} diff --git a/client/clientset/fake/restik.go b/client/clientset/fake/restik.go deleted file mode 100644 index 14223f9b9..000000000 --- a/client/clientset/fake/restik.go +++ /dev/null @@ -1,98 +0,0 @@ -package fake - -import ( - rapi "github.com/appscode/restik/api" - "github.com/appscode/restik/client/clientset" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/apimachinery/pkg/runtime/schema" - "k8s.io/apimachinery/pkg/watch" - "k8s.io/client-go/testing" -) - -type FakeRestik struct { - Fake *testing.Fake - ns string -} - -var restikResource = schema.GroupVersionResource{Group: "backup.appscode.com", Version: "v1alpha1", Resource: "restiks"} - -var _ clientset.RestikInterface = &FakeRestik{} - -// Get returns the Restiks by name. -func (mock *FakeRestik) Get(name string) (*rapi.Restik, error) { - obj, err := mock.Fake. - Invokes(testing.NewGetAction(restikResource, mock.ns, name), &rapi.Restik{}) - - if obj == nil { - return nil, err - } - return obj.(*rapi.Restik), err -} - -// List returns the a of Restiks. -func (mock *FakeRestik) List(opts metav1.ListOptions) (*rapi.RestikList, error) { - obj, err := mock.Fake. - Invokes(testing.NewListAction(restikResource, mock.ns, opts), &rapi.Restik{}) - - if obj == nil { - return nil, err - } - - label, _, _ := testing.ExtractFromListOptions(opts) - if label == nil { - label = labels.Everything() - } - list := &rapi.RestikList{} - for _, item := range obj.(*rapi.RestikList).Items { - if label.Matches(labels.Set(item.Labels)) { - list.Items = append(list.Items, item) - } - } - return list, err -} - -// Create creates a new Restik. -func (mock *FakeRestik) Create(svc *rapi.Restik) (*rapi.Restik, error) { - obj, err := mock.Fake. - Invokes(testing.NewCreateAction(restikResource, mock.ns, svc), &rapi.Restik{}) - - if obj == nil { - return nil, err - } - return obj.(*rapi.Restik), err -} - -// Update updates a Restik. -func (mock *FakeRestik) Update(svc *rapi.Restik) (*rapi.Restik, error) { - obj, err := mock.Fake. - Invokes(testing.NewUpdateAction(restikResource, mock.ns, svc), &rapi.Restik{}) - - if obj == nil { - return nil, err - } - return obj.(*rapi.Restik), err -} - -// Delete deletes a Restik by name. -func (mock *FakeRestik) Delete(name string, _ *metav1.DeleteOptions) error { - _, err := mock.Fake. - Invokes(testing.NewDeleteAction(restikResource, mock.ns, name), &rapi.Restik{}) - - return err -} - -func (mock *FakeRestik) UpdateStatus(srv *rapi.Restik) (*rapi.Restik, error) { - obj, err := mock.Fake. - Invokes(testing.NewUpdateSubresourceAction(restikResource, "status", mock.ns, srv), &rapi.Restik{}) - - if obj == nil { - return nil, err - } - return obj.(*rapi.Restik), err -} - -func (mock *FakeRestik) Watch(opts metav1.ListOptions) (watch.Interface, error) { - return mock.Fake. - InvokesWatch(testing.NewWatchAction(restikResource, mock.ns, opts)) -} diff --git a/client/clientset/imports.go b/client/clientset/imports.go index 6019a6351..ee25cc90c 100644 --- a/client/clientset/imports.go +++ b/client/clientset/imports.go @@ -4,7 +4,7 @@ package clientset import ( "fmt" - _ "github.com/appscode/restik/api/install" + _ "github.com/appscode/stash/api/install" "k8s.io/client-go/pkg/api" ) diff --git a/client/clientset/restic.go b/client/clientset/restic.go new file mode 100644 index 000000000..fc1d8629d --- /dev/null +++ b/client/clientset/restic.go @@ -0,0 +1,116 @@ +package clientset + +import ( + sapi "github.com/appscode/stash/api" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/rest" +) + +type ResticGetter interface { + Restics(namespace string) ResticInterface +} + +const ( + ResourceKindRestic = "Restic" + ResourceNameRestic = "restic" + ResourceTypeRestic = "restics" +) + +type ResticInterface interface { + List(opts metav1.ListOptions) (*sapi.ResticList, error) + Get(name string) (*sapi.Restic, error) + Create(stash *sapi.Restic) (*sapi.Restic, error) + Update(stash *sapi.Restic) (*sapi.Restic, error) + Delete(name string, options *metav1.DeleteOptions) error + Watch(opts metav1.ListOptions) (watch.Interface, error) + UpdateStatus(stash *sapi.Restic) (*sapi.Restic, error) +} + +type ResticImpl struct { + r rest.Interface + ns string +} + +var _ ResticInterface = &ResticImpl{} + +func newRestic(c *ExtensionClient, namespace string) *ResticImpl { + return &ResticImpl{c.restClient, namespace} +} + +func (c *ResticImpl) List(opts metav1.ListOptions) (result *sapi.ResticList, err error) { + result = &sapi.ResticList{} + err = c.r.Get(). + Namespace(c.ns). + Resource(ResourceTypeRestic). + VersionedParams(&opts, ExtendedCodec). + Do(). + Into(result) + return +} + +func (c *ResticImpl) Get(name string) (result *sapi.Restic, err error) { + result = &sapi.Restic{} + err = c.r.Get(). + Namespace(c.ns). + Resource(ResourceTypeRestic). + Name(name). + Do(). + Into(result) + return +} + +func (c *ResticImpl) Create(stash *sapi.Restic) (result *sapi.Restic, err error) { + result = &sapi.Restic{} + err = c.r.Post(). + Namespace(c.ns). + Resource(ResourceTypeRestic). + Body(stash). + Do(). + Into(result) + return +} + +func (c *ResticImpl) Update(stash *sapi.Restic) (result *sapi.Restic, err error) { + result = &sapi.Restic{} + err = c.r.Put(). + Namespace(c.ns). + Resource(ResourceTypeRestic). + Name(stash.Name). + Body(stash). + Do(). + Into(result) + return +} + +func (c *ResticImpl) Delete(name string, options *metav1.DeleteOptions) (err error) { + return c.r.Delete(). + Namespace(c.ns). + Resource(ResourceTypeRestic). + Name(name). + Body(options). + Do(). + Error() +} + +func (c *ResticImpl) Watch(opts metav1.ListOptions) (watch.Interface, error) { + return c.r.Get(). + Prefix("watch"). + Namespace(c.ns). + Resource(ResourceTypeRestic). + VersionedParams(&opts, ExtendedCodec). + Watch() +} + +func (c *ResticImpl) UpdateStatus(stash *sapi.Restic) (result *sapi.Restic, err error) { + result = &sapi.Restic{} + err = c.r.Put(). + Namespace(c.ns). + Resource(ResourceTypeRestic). + Name(stash.Name). + SubResource("status"). + Body(stash). + Do(). + Into(result) + return +} diff --git a/client/clientset/restik.go b/client/clientset/restik.go deleted file mode 100644 index fff19d585..000000000 --- a/client/clientset/restik.go +++ /dev/null @@ -1,116 +0,0 @@ -package clientset - -import ( - rapi "github.com/appscode/restik/api" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/watch" - "k8s.io/client-go/rest" -) - -type RestikNamespacer interface { - Restiks(namespace string) RestikInterface -} - -const ( - ResourceKindRestik = "Restik" - ResourceNameRestik = "restik" - ResourceTypeRestik = "restiks" -) - -type RestikInterface interface { - List(opts metav1.ListOptions) (*rapi.RestikList, error) - Get(name string) (*rapi.Restik, error) - Create(restik *rapi.Restik) (*rapi.Restik, error) - Update(restik *rapi.Restik) (*rapi.Restik, error) - Delete(name string, options *metav1.DeleteOptions) error - Watch(opts metav1.ListOptions) (watch.Interface, error) - UpdateStatus(restik *rapi.Restik) (*rapi.Restik, error) -} - -type RestikImpl struct { - r rest.Interface - ns string -} - -var _ RestikInterface = &RestikImpl{} - -func newRestik(c *ExtensionClient, namespace string) *RestikImpl { - return &RestikImpl{c.restClient, namespace} -} - -func (c *RestikImpl) List(opts metav1.ListOptions) (result *rapi.RestikList, err error) { - result = &rapi.RestikList{} - err = c.r.Get(). - Namespace(c.ns). - Resource(ResourceTypeRestik). - VersionedParams(&opts, ExtendedCodec). - Do(). - Into(result) - return -} - -func (c *RestikImpl) Get(name string) (result *rapi.Restik, err error) { - result = &rapi.Restik{} - err = c.r.Get(). - Namespace(c.ns). - Resource(ResourceTypeRestik). - Name(name). - Do(). - Into(result) - return -} - -func (c *RestikImpl) Create(restik *rapi.Restik) (result *rapi.Restik, err error) { - result = &rapi.Restik{} - err = c.r.Post(). - Namespace(c.ns). - Resource(ResourceTypeRestik). - Body(restik). - Do(). - Into(result) - return -} - -func (c *RestikImpl) Update(restik *rapi.Restik) (result *rapi.Restik, err error) { - result = &rapi.Restik{} - err = c.r.Put(). - Namespace(c.ns). - Resource(ResourceTypeRestik). - Name(restik.Name). - Body(restik). - Do(). - Into(result) - return -} - -func (c *RestikImpl) Delete(name string, options *metav1.DeleteOptions) (err error) { - return c.r.Delete(). - Namespace(c.ns). - Resource(ResourceTypeRestik). - Name(name). - Body(options). - Do(). - Error() -} - -func (c *RestikImpl) Watch(opts metav1.ListOptions) (watch.Interface, error) { - return c.r.Get(). - Prefix("watch"). - Namespace(c.ns). - Resource(ResourceTypeRestik). - VersionedParams(&opts, ExtendedCodec). - Watch() -} - -func (c *RestikImpl) UpdateStatus(restik *rapi.Restik) (result *rapi.Restik, err error) { - result = &rapi.Restik{} - err = c.r.Put(). - Namespace(c.ns). - Resource(ResourceTypeRestik). - Name(restik.Name). - SubResource("status"). - Body(restik). - Do(). - Into(result) - return -} diff --git a/cron.go b/cron.go index 74dc16f3a..bb40874c9 100644 --- a/cron.go +++ b/cron.go @@ -2,9 +2,9 @@ package main import ( "github.com/appscode/log" - rcs "github.com/appscode/restik/client/clientset" - "github.com/appscode/restik/pkg/analytics" - "github.com/appscode/restik/pkg/cron" + rcs "github.com/appscode/stash/client/clientset" + "github.com/appscode/stash/pkg/analytics" + "github.com/appscode/stash/pkg/cron" "github.com/spf13/cobra" clientset "k8s.io/client-go/kubernetes" "k8s.io/client-go/tools/clientcmd" @@ -21,7 +21,7 @@ func NewCmdCrond(version string) *cobra.Command { cmd := &cobra.Command{ Use: "crond", - Short: "Run restik cron daemon", + Short: "Run Stash cron daemon", PreRun: func(cmd *cobra.Command, args []string) { if enableAnalytics { analytics.Enable() @@ -37,9 +37,9 @@ func NewCmdCrond(version string) *cobra.Command { log.Fatalf("Could not get kubernetes config: %s", err) } kubeClient := clientset.NewForConfigOrDie(config) - restikClient := rcs.NewForConfigOrDie(config) + stashClient := rcs.NewForConfigOrDie(config) - ctrl := cron.NewController(kubeClient, restikClient, namespace, name) + ctrl := cron.NewController(kubeClient, stashClient, namespace, name) ctrl.RunAndHold() }, } diff --git a/docs/contribution/README.md b/docs/contribution/README.md index 4d8343e33..73d9c20d7 100644 --- a/docs/contribution/README.md +++ b/docs/contribution/README.md @@ -7,8 +7,8 @@ We have a [Developer's Guide](../developer-guide/README.md) that outlines everyt please feel free to send a Pull Request. ## Filing issues -If you have a question about Restik or have a problem using it, please start with contacting us. -If that doesn't answer your questions, or if you think you found a bug, please [file an issue](https://github.com/appscode/restik/issues/new). +If you have a question about Stash or have a problem using it, please start with contacting us. +If that doesn't answer your questions, or if you think you found a bug, please [file an issue](https://github.com/appscode/stash/issues/new). ## Submit PR If you fix a bug or developed a new feature feel free to submit a PR. @@ -24,5 +24,5 @@ If you fix a bug or developed a new feature feel free to submit a PR. ### Adding Dependency If your patch Depends on new packagees, add that to vendor with glide. -### Building Restik -Read [build instruction](../developer-guide/build.md) to build Restik. \ No newline at end of file +### Building Stash +Read [build instruction](../developer-guide/build.md) to build Stash. \ No newline at end of file diff --git a/docs/developer-guide/README.md b/docs/developer-guide/README.md index 4a1e3fd89..2a6ec6415 100644 --- a/docs/developer-guide/README.md +++ b/docs/developer-guide/README.md @@ -1,11 +1,11 @@ ## Development Guide ### Go development environment -Restik is written in the go programming language. The release is built and tested on **go 1.8**. If you haven't set up a Go +Stash is written in the go programming language. The release is built and tested on **go 1.8**. If you haven't set up a Go development environment, please follow [these instructions](https://golang.org/doc/code.html) to install the go tools. ### Dependency management -Restik build and test scripts use glide to manage dependencies. +Stash build and test scripts use glide to manage dependencies. To install glide follow [these instructions](https://github.com/Masterminds/glide#install). @@ -23,7 +23,7 @@ Currently the project includes all its required dependencies inside `vendor` to ``` ### Local Build -To build Restik using your local Go development environment (generate linux binaries): +To build Stash using your local Go development environment (generate linux binaries): ```sh $ ./hack/make.py ``` diff --git a/docs/developer-guide/build.md b/docs/developer-guide/build.md index 3e34b301f..2710f4f0d 100644 --- a/docs/developer-guide/build.md +++ b/docs/developer-guide/build.md @@ -25,12 +25,12 @@ glide slow # This will push docker image to other repositories # Add docker tag for your repository -docker tag appscode/restik: : +docker tag appscode/stash: : # Push Image docker push : # Example: -docker tag appscode/restik:default sauman/restik:default -docker push sauman/restik:default +docker tag appscode/stash:default sauman/stash:default +docker push sauman/stash:default ``` diff --git a/docs/developer-guide/design.md b/docs/developer-guide/design.md index e7e6e97fc..cc866eeb1 100644 --- a/docs/developer-guide/design.md +++ b/docs/developer-guide/design.md @@ -11,9 +11,9 @@ Controller detects following ResourceEventType: * DELETED ## Workflow -User deploys restik TPR controller. This will automatically create TPR if not present. -User creates a TPR object defining the information needed for taking backups. User adds a label `backup.appscode.com/config:` Replication Controllers, Deployments, Replica Sets, Replication Controllers, Statefulsets that TPR controller watches for. -Once TPR controller finds RC etc that has enabled backup, it will add a sidecar container with restik image. So, restik will restart the pods for the first time. In restic-sidecar container backup process will be done through a cron schedule. +User deploys stash TPR controller. This will automatically create TPR if not present. +User creates a TPR object defining the information needed for taking backups. User adds a label `restic.appscode.com/config:` Replication Controllers, Deployments, Replica Sets, Replication Controllers, Statefulsets that TPR controller watches for. +Once TPR controller finds RC etc that has enabled backup, it will add a sidecar container with stash image. So, stash will restart the pods for the first time. In restic-sidecar container backup process will be done through a cron schedule. When a snapshot is taken an event will be created under the same namespace. Event name will be `-`. If a backup precess successful event reason will show us `Success` else event reason will be `Failed` If the RC, Deployments, Replica Sets, Replication Controllers, and TPR association is later removed, TPR controller will also remove the side car container. @@ -22,8 +22,8 @@ If the RC, Deployments, Replica Sets, Replication Controllers, and TPR associati Since restic process will be run on a schedule, some process will be needed to be running as the entrypoint. This is a loader type process that watches restic TPR and translates that into the restic compatiable config. eg, -* restik run: This is the main TPR controller entrypoint that is run as a single deployment in Kubernetes. -* restik watch: This will watch Kubernetes restic TPR and start the cron process. +* stash run: This is the main TPR controller entrypoint that is run as a single deployment in Kubernetes. +* stash watch: This will watch Kubernetes restic TPR and start the cron process. ## Restarting pods @@ -31,4 +31,4 @@ As mentioned before, first time side car containers are added, pods will be rest For example, Kubernetes itself will restarts pods behind a deployment. In such cases, TPR controller will let Kubernetes do that. ## Original Tracking Issue: -https://github.com/appscode/restik/issues/1 +https://github.com/appscode/stash/issues/1 diff --git a/docs/user-guide/backup.md b/docs/user-guide/backup.md index 52bdc928c..26f143c61 100644 --- a/docs/user-guide/backup.md +++ b/docs/user-guide/backup.md @@ -3,19 +3,19 @@ ## High Level Tasks -* Create `restik.backup.appscode.com` Third Party Resource +* Create `stash.backup.appscode.com` Third Party Resource * Create Backup Deployment ## Deploying Backup ### Create Third Party Resource -`Backup process` depends on Third Party Resource Object `restik.backup.appscode.com`. This object can be created using following data. +`Backup process` depends on Third Party Resource Object `stash.backup.appscode.com`. This object can be created using following data. ```yaml apiVersion: extensions/v1beta1 kind: ThirdPartyResource metadata: - name: restik.backup.appscode.com + name: stash.backup.appscode.com description: "Backup and restore support for Kubernetes persistent volumes by AppsCode" versions: - name: v1alpha1 @@ -24,32 +24,32 @@ versions: ```sh # Create Third Party Resource -$ kubectl apply -f https://raw.githubusercontent.com/appscode/restik/master/api/extensions/backup.yaml +$ kubectl apply -f https://raw.githubusercontent.com/appscode/stash/master/api/extensions/backup.yaml ``` ### Deploy Controller -Restik controller communicates with kube-apiserver at inCluster mode if no master or kubeconfig is provided. It watches Restik resource to handle backup process. +Stash controller communicates with kube-apiserver at inCluster mode if no master or kubeconfig is provided. It watches Stash resource to handle backup process. ``` -$ kubectl apply -f https://raw.githubusercontent.com/appscode/restik/master/hack/deploy/deployments.yaml +$ kubectl apply -f https://raw.githubusercontent.com/appscode/stash/master/hack/deploy/deployments.yaml ``` #### Configuration Options ``` --master // The address of the Kubernetes API server (overrides any value in kubeconfig) --kubeconfig // Path to kubeconfig file with authorization information (the master location is set by the master flag) ---image // Restik image name with version to be run in restic-sidecar (appscode/restik:latest) +--image // Stash image name with version to be run in restic-sidecar (appscode/stash:latest) ``` -## Restik +## Stash This resource type is backed by a controller which take backup of kubernetes volumes from any running pod in Kubernetes. It can also take backup of host paths from Nodes in Kubernetes. ### Resource -A AppsCode Restik resource Looks like at the kubernetes level: +A AppsCode Stash resource Looks like at the kubernetes level: ```yaml -apiVersion: backup.appscode.com/v1alpha1 -kind: Restik +apiVersion: stash.appscode.com/v1alpha1 +kind: Restic metadata: name: test-backup namespace: default @@ -58,11 +58,11 @@ spec: volumeName: "test-volume" path: /mypath destination: - path: /restikrepo + path: /stashrepo repositorySecretName: test-secret volume: emptyDir: {} - name: restik-volume + name: stash-volume schedule: "0 * * * * *" tags: - testTag @@ -70,10 +70,10 @@ spec: keepLastSnapshots: 3 ``` -**Line 1-3**: With all other Kubernetes config, AppsCode Restik resource needs `apiVersion`, `kind` and `metadata` fields. `apiVersion` and `kind` needs to be exactly same as `backup.appscode.com/v1alpha1`, and, `specific version` currently as `v1alpha1`, to identify the resource -as AppsCode Restik. In metadata the `name` and `namespace` indicates the resource identifying name and its Kubernetes namespace. +**Line 1-3**: With all other Kubernetes config, AppsCode Stash resource needs `apiVersion`, `kind` and `metadata` fields. `apiVersion` and `kind` needs to be exactly same as `stash.appscode.com/v1alpha1`, and, `specific version` currently as `v1alpha1`, to identify the resource +as AppsCode Stash. In metadata the `name` and `namespace` indicates the resource identifying name and its Kubernetes namespace. -**Line 6-20**: Restik spec has all the information needed to configure the backup process. +**Line 6-20**: Stash spec has all the information needed to configure the backup process. * In `source` field user needs to specify the volume name and the path of which he/she wants to take backup. * In `destination` field user needs to specify the path and the volume where he/she wants to store the backup snapshots. @@ -96,7 +96,7 @@ When multiple `retainTags` are specified, only the snapshots which have all the ## Enable Backup -For enabling the backup process for a particular kubernetes object like `RC`, `Replica Set`, `Deployment`, `DaemonSet` user adds a label `backup.appscode.com/config: `. `` is the name of Restik object. And then user creates the Restik object for starting backup process. +For enabling the backup process for a particular kubernetes object like `RC`, `Replica Set`, `Deployment`, `DaemonSet` user adds a label `restic.appscode.com/config: `. `` is the name of Stash object. And then user creates the Stash object for starting backup process. In case of StaefulSet user has to add the restic-sidecar container manually. ```yaml @@ -104,7 +104,7 @@ apiVersion: apps/v1beta1 kind: StatefulSet metadata: labels: - backup.appscode.com/config: test-backup + restic.appscode.com/config: test-backup name: test-statefulset namespace: default spec: @@ -130,37 +130,37 @@ spec: - watch - --v=10 env: - - name: RESTIK_NAMESPACE + - name: STASH_NAMESPACE value: default - name: TPR value: test-backup - image: appscode/restik:latest + image: appscode/stash:latest imagePullPolicy: Always name: restic-sidecar volumeMounts: - mountPath: /source_path name: test-volume - mountPath: /repo_path - name: restik-vol + name: stash-vol volumes: - emptyDir: {} name: test-volume - emptyDir: {} - name: restik-vol + name: stash-vol ``` ## Backup Nodes If one interested in take backup of host paths, this can be done by deploying a `DaemonSet` with a do nothing busybox container. -Restik TPR controller can use that as a vessel for running restic sidecar containers. +Stash TPR controller can use that as a vessel for running restic sidecar containers. ## Update Backup -One can update the source, retention policy, tags, cron schedule of the Restik object. After updating the Restik object backup process will follow the new backup strategy. -If user wants to update the image of restic-sidecar container he/she needs to update the `backup.appscode.com/image` in field annotation in the backup object. This will automatically update the restic-sidecar container. +One can update the source, retention policy, tags, cron schedule of the Stash object. After updating the Stash object backup process will follow the new backup strategy. +If user wants to update the image of restic-sidecar container he/she needs to update the `restic.appscode.com/image` in field annotation in the backup object. This will automatically update the restic-sidecar container. In case of Statefulset user needs to update the sidecar container manually. ## Disable Backup -For disabling backup process one needs to delete the corresponding Restik object in case of `RC`, `Replica Set`, `Deployment`, `DaemonSet`. +For disabling backup process one needs to delete the corresponding Stash object in case of `RC`, `Replica Set`, `Deployment`, `DaemonSet`. In case of `Statefulset` user needs to delete the corresponding backup object as well as remove the side container from the Statefulset manually. \ No newline at end of file diff --git a/docs/user-guide/install.md b/docs/user-guide/install.md index 598258635..997cb37ce 100644 --- a/docs/user-guide/install.md +++ b/docs/user-guide/install.md @@ -1,10 +1,10 @@ -## Install Restik +## Install Stash ``` -git clone https://github.com/appscode/restik.git +git clone https://github.com/appscode/stash.git ./hack/make.py ``` -## Upgrade Restik +## Upgrade Stash ``` -To upgrade Restik User needs to pull the particular branch and rebuild it for now. +To upgrade Stash User needs to pull the particular branch and rebuild it for now. ``` \ No newline at end of file diff --git a/glide-slow b/glide-slow index e70da888b..a627a166e 100755 --- a/glide-slow +++ b/glide-slow @@ -5,7 +5,7 @@ # - ??? # - Profit -pushd $GOPATH/src/github.com/appscode/restik +pushd $GOPATH/src/github.com/appscode/stash glide up -v glide vc --only-code --no-tests diff --git a/glide.yaml b/glide.yaml index 5c26e9180..13286a89d 100644 --- a/glide.yaml +++ b/glide.yaml @@ -1,4 +1,4 @@ -package: github.com/appscode/restik +package: github.com/appscode/stash import: - package: github.com/appscode/go - package: github.com/appscode/log diff --git a/hack/deploy/deployments.yaml b/hack/deploy/deployments.yaml index b148a2eb2..b6690bb5d 100644 --- a/hack/deploy/deployments.yaml +++ b/hack/deploy/deployments.yaml @@ -2,25 +2,25 @@ apiVersion: extensions/v1beta1 kind: Deployment metadata: labels: - app: restik-operator - name: restik-operator + app: stash-operator + name: stash-operator namespace: kube-system spec: replicas: 1 selector: matchLabels: - app: restik-operator + app: stash-operator template: metadata: labels: - app: restik-operator + app: stash-operator spec: containers: - - name: restik-operator + - name: stash-operator args: - run - --v=3 - image: appscode/restik:$TAG + image: appscode/stash:$TAG ports: - containerPort: 56790 name: http @@ -45,8 +45,8 @@ apiVersion: v1 kind: Service metadata: labels: - app: restik-operator - name: restik-operator + app: stash-operator + name: stash-operator namespace: kube-system spec: ports: @@ -57,4 +57,4 @@ spec: port: 56790 targetPort: http selector: - app: restik-operator + app: stash-operator diff --git a/hack/docker/setup.sh b/hack/docker/setup.sh index 1977074fb..50e577065 100755 --- a/hack/docker/setup.sh +++ b/hack/docker/setup.sh @@ -7,13 +7,13 @@ set -o pipefail GOPATH=$(go env GOPATH) SRC=$GOPATH/src BIN=$GOPATH/bin -REPO_ROOT=$GOPATH/src/github.com/appscode/restik +REPO_ROOT=$GOPATH/src/github.com/appscode/stash source "$REPO_ROOT/hack/libbuild/common/lib.sh" source "$REPO_ROOT/hack/libbuild/common/public_image.sh" APPSCODE_ENV=${APPSCODE_ENV:-dev} -IMG=restik +IMG=stash RESTIC_VER=0.6.1 DIST=$REPO_ROOT/dist @@ -24,14 +24,14 @@ fi clean() { pushd $REPO_ROOT/hack/docker - rm -rf restic restik Dockerfile + rm -rf restic stash Dockerfile popd } build_binary() { pushd $REPO_ROOT ./hack/builddeps.sh - ./hack/make.py build restik + ./hack/make.py build stash detect_tag $DIST/.tag popd } @@ -40,8 +40,8 @@ build_docker() { pushd $REPO_ROOT/hack/docker # Download restic - cp $DIST/restik/restik-linux-amd64 restik - chmod 755 restik + cp $DIST/stash/stash-linux-amd64 stash + chmod 755 stash # Download restic wget https://github.com/restic/restic/releases/download/v${RESTIC_VER}/restic_${RESTIC_VER}_linux_amd64.bz2 @@ -58,14 +58,14 @@ RUN set -x \ && rm -rf /var/cache/apk/* COPY restic /restic -COPY restik /restik +COPY stash /stash -ENTRYPOINT ["/restik"] +ENTRYPOINT ["/stash"] EOL local cmd="docker build -t appscode/$IMG:$TAG ." echo $cmd; $cmd - rm restik Dockerfile restic + rm stash Dockerfile restic popd } diff --git a/hack/examples/backup_example.yaml b/hack/examples/backup_example.yaml index 60886e6df..76db6dacd 100644 --- a/hack/examples/backup_example.yaml +++ b/hack/examples/backup_example.yaml @@ -1,5 +1,5 @@ -apiVersion: backup.appscode.com/v1alpha1 -kind: Restik +apiVersion: stash.appscode.com/v1alpha1 +kind: Restic metadata: name: testbackup namespace: test @@ -8,13 +8,13 @@ spec: volumeName: "test-volume" path: /mypathreplicaset destination: - path: /restikreporeplicaset + path: /stashreporeplicaset repositorySecretName: testsecret volume: awsElasticBlockStore: fsType: ext4 volumeID: vol-******* - name: restik-volume + name: stash-volume schedule: "0 * * * * *" tags: - test diff --git a/hack/make.py b/hack/make.py index 0f3238b2c..e3670d094 100755 --- a/hack/make.py +++ b/hack/make.py @@ -35,10 +35,10 @@ def check_antipackage(): import sys from os.path import expandvars -libbuild.REPO_ROOT = expandvars('$GOPATH') + '/src/github.com/appscode/restik' +libbuild.REPO_ROOT = expandvars('$GOPATH') + '/src/github.com/appscode/stash' BUILD_METADATA = libbuild.metadata(libbuild.REPO_ROOT) libbuild.BIN_MATRIX = { - 'restik': { + 'stash': { 'type': 'go', 'go_version': True, 'use_cgo': False, diff --git a/pkg/cron/controller.go b/pkg/cron/controller.go index 5d145e210..047054d26 100644 --- a/pkg/cron/controller.go +++ b/pkg/cron/controller.go @@ -12,10 +12,9 @@ import ( "time" "github.com/appscode/log" - rapi "github.com/appscode/restik/api" - rcs "github.com/appscode/restik/client/clientset" - "github.com/appscode/restik/pkg/analytics" - "github.com/appscode/restik/pkg/eventer" + sapi "github.com/appscode/stash/api" + scs "github.com/appscode/stash/client/clientset" + "github.com/appscode/stash/pkg/eventer" "gopkg.in/robfig/cron.v2" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" @@ -28,11 +27,11 @@ import ( ) const ( - ContainerName = "restik" - RestikNamespace = "RESTIK_NAMESPACE" - RestikResourceName = "RESTIK_RESOURCE_NAME" + ContainerName = "stash" + StashNamespace = "STASH_NAMESPACE" + StashResourceName = "STASH_RESOURCE_NAME" - BackupConfig = "backup.appscode.com/config" + BackupConfig = "restic.appscode.com/config" RESTIC_PASSWORD = "RESTIC_PASSWORD" ReplicationController = "ReplicationController" ReplicaSet = "ReplicaSet" @@ -40,30 +39,30 @@ const ( DaemonSet = "DaemonSet" StatefulSet = "StatefulSet" Password = "password" - ImageAnnotation = "backup.appscode.com/image" + ImageAnnotation = "restic.appscode.com/image" Force = "force" ) type controller struct { - KubeClient clientset.Interface - RestikClient rcs.ExtensionInterface + KubeClient clientset.Interface + StashClient scs.ExtensionInterface resourceNamespace string resourceName string - resource *rapi.Restik + resource *sapi.Restic crons *cron.Cron eventRecorder record.EventRecorder } -func NewController(kubeClient clientset.Interface, restikClient rcs.ExtensionInterface, namespace, name string) *controller { +func NewController(kubeClient clientset.Interface, stashClient scs.ExtensionInterface, namespace, name string) *controller { return &controller{ KubeClient: kubeClient, - RestikClient: restikClient, + StashClient: stashClient, resourceNamespace: namespace, resourceName: name, crons: cron.New(), - eventRecorder: eventer.NewEventRecorder(kubeClient, "restik-crond"), + eventRecorder: eventer.NewEventRecorder(kubeClient, "stash-crond"), } } @@ -72,23 +71,23 @@ func (c *controller) RunAndHold() { lw := &cache.ListWatch{ ListFunc: func(opts metav1.ListOptions) (runtime.Object, error) { - return c.RestikClient.Restiks(c.resourceNamespace).List(metav1.ListOptions{}) + return c.StashClient.Restics(c.resourceNamespace).List(metav1.ListOptions{}) }, WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { - return c.RestikClient.Restiks(c.resourceNamespace).Watch(metav1.ListOptions{}) + return c.StashClient.Restics(c.resourceNamespace).Watch(metav1.ListOptions{}) }, } _, ctrl := cache.NewInformer(lw, - &rapi.Restik{}, + &sapi.Restic{}, time.Minute*2, cache.ResourceEventHandlerFuncs{ AddFunc: func(obj interface{}) { - if r, ok := obj.(*rapi.Restik); ok { + if r, ok := obj.(*sapi.Restic); ok { if r.Name == c.resourceName { c.resource = r err := c.startCronBackupProcedure() if err != nil { - restikCronFailedToAdd() + crondFailedToAdd() c.eventRecorder.Eventf( r, apiv1.EventTypeWarning, @@ -97,27 +96,27 @@ func (c *controller) RunAndHold() { ) log.Errorln(err) } else { - restikCronSuccessfullyAdded() + crondSuccessfullyAdded() } } } }, UpdateFunc: func(old, new interface{}) { - oldObj, ok := old.(*rapi.Restik) + oldObj, ok := old.(*sapi.Restic) if !ok { - log.Errorln(errors.New("Error validating Restik object")) + log.Errorln(errors.New("Error validating Stash object")) return } - newObj, ok := new.(*rapi.Restik) + newObj, ok := new.(*sapi.Restic) if !ok { - log.Errorln(errors.New("Error validating Restik object")) + log.Errorln(errors.New("Error validating Stash object")) return } if !reflect.DeepEqual(oldObj.Spec, newObj.Spec) && newObj.Name == c.resourceName { c.resource = newObj err := c.startCronBackupProcedure() if err != nil { - restikCronFailedToModify() + crondFailedToModify() c.eventRecorder.Eventf( newObj, apiv1.EventTypeWarning, @@ -126,7 +125,7 @@ func (c *controller) RunAndHold() { ) log.Errorln(err) } else { - restikCronSuccessfullyModified() + crondSuccessfullyModified() } } }, @@ -134,9 +133,9 @@ func (c *controller) RunAndHold() { ctrl.Run(wait.NeverStop) } -func (cronWatcher *controller) startCronBackupProcedure() error { - restik := cronWatcher.resource - password, err := getPasswordFromSecret(cronWatcher.KubeClient, restik.Spec.Destination.RepositorySecretName, restik.Namespace) +func (c *controller) startCronBackupProcedure() error { + stash := c.resource + password, err := getPasswordFromSecret(c.KubeClient, stash.Spec.Destination.RepositorySecretName, stash.Namespace) if err != nil { return err } @@ -144,7 +143,7 @@ func (cronWatcher *controller) startCronBackupProcedure() error { if err != nil { return err } - repo := restik.Spec.Destination.Path + repo := stash.Spec.Destination.Path _, err = os.Stat(filepath.Join(repo, "config")) if os.IsNotExist(err) { if _, err = execLocal(fmt.Sprintf("/restic init --repo %s", repo)); err != nil { @@ -152,29 +151,29 @@ func (cronWatcher *controller) startCronBackupProcedure() error { } } // Remove previous jobs - for _, v := range cronWatcher.crons.Entries() { - cronWatcher.crons.Remove(v.ID) + for _, v := range c.crons.Entries() { + c.crons.Remove(v.ID) } - interval := restik.Spec.Schedule + interval := stash.Spec.Schedule if _, err = cron.Parse(interval); err != nil { log.Errorln(err) - cronWatcher.eventRecorder.Event(restik, apiv1.EventTypeWarning, eventer.EventReasonInvalidCronExpression, err.Error()) + c.eventRecorder.Event(stash, apiv1.EventTypeWarning, eventer.EventReasonInvalidCronExpression, err.Error()) //Reset Wrong Schedule - restik.Spec.Schedule = "" - _, err = cronWatcher.RestikClient.Restiks(restik.Namespace).Update(restik) + stash.Spec.Schedule = "" + _, err = c.StashClient.Restics(stash.Namespace).Update(stash) if err != nil { return err } - cronWatcher.eventRecorder.Event(restik, apiv1.EventTypeNormal, eventer.EventReasonSuccessfulCronExpressionReset, "Cron expression reset") + c.eventRecorder.Event(stash, apiv1.EventTypeNormal, eventer.EventReasonSuccessfulCronExpressionReset, "Cron expression reset") return nil } - _, err = cronWatcher.crons.AddFunc(interval, func() { - if err := cronWatcher.runCronJob(); err != nil { - restikJobFailure() - cronWatcher.eventRecorder.Event(restik, apiv1.EventTypeWarning, eventer.EventReasonFailedCronJob, err.Error()) + _, err = c.crons.AddFunc(interval, func() { + if err := c.runCronJob(); err != nil { + stashJobFailure() + c.eventRecorder.Event(stash, apiv1.EventTypeWarning, eventer.EventReasonFailedCronJob, err.Error()) log.Errorln(err) } else { - restikJobSuccess() + stashJobSuccess() } }) if err != nil { @@ -183,9 +182,9 @@ func (cronWatcher *controller) startCronBackupProcedure() error { return nil } -func (cronWatcher *controller) runCronJob() error { - backup := cronWatcher.resource - password, err := getPasswordFromSecret(cronWatcher.KubeClient, cronWatcher.resource.Spec.Destination.RepositorySecretName, backup.Namespace) +func (c *controller) runCronJob() error { + backup := c.resource + password, err := getPasswordFromSecret(c.KubeClient, c.resource.Spec.Destination.RepositorySecretName, backup.Namespace) if err != nil { return err } @@ -206,57 +205,57 @@ func (cronWatcher *controller) runCronJob() error { errMessage := "" _, err = execLocal(cmd) if err != nil { - log.Errorln("Restik backup failed cause ", err) + log.Errorln("Stash backup failed cause ", err) errMessage = " ERROR: " + err.Error() reason = eventer.EventReasonFailedToBackup - restikBackupFailure() + backupFailure() } else { backup.Status.LastSuccessfulBackupTime = &backupStartTime reason = eventer.EventReasonSuccessfulBackup - restikBackupSuccess() + backupSuccess() } backup.Status.BackupCount++ message := "Backup operation number = " + strconv.Itoa(int(backup.Status.BackupCount)) - cronWatcher.eventRecorder.Event(backup, apiv1.EventTypeNormal, reason, message+errMessage) + c.eventRecorder.Event(backup, apiv1.EventTypeNormal, reason, message+errMessage) backupEndTime := metav1.Now() _, err = snapshotRetention(backup) if err != nil { log.Errorln("Snapshot retention failed cause ", err) - cronWatcher.eventRecorder.Event(backup, apiv1.EventTypeNormal, eventer.EventReasonFailedToRetention, message+" ERROR: "+err.Error()) + c.eventRecorder.Event(backup, apiv1.EventTypeNormal, eventer.EventReasonFailedToRetention, message+" ERROR: "+err.Error()) } backup.Status.LastBackupTime = &backupStartTime if reflect.DeepEqual(backup.Status.FirstBackupTime, time.Time{}) { backup.Status.FirstBackupTime = &backupStartTime } backup.Status.LastBackupDuration = backupEndTime.Sub(backupStartTime.Time).String() - backup, err = cronWatcher.RestikClient.Restiks(backup.Namespace).Update(backup) + backup, err = c.StashClient.Restics(backup.Namespace).Update(backup) if err != nil { log.Errorln(err) - cronWatcher.eventRecorder.Event(backup, apiv1.EventTypeNormal, eventer.EventReasonFailedToUpdate, err.Error()) + c.eventRecorder.Event(backup, apiv1.EventTypeNormal, eventer.EventReasonFailedToUpdate, err.Error()) } - cronWatcher.resource = backup + c.resource = backup return nil } -func snapshotRetention(r *rapi.Restik) (string, error) { +func snapshotRetention(r *sapi.Restic) (string, error) { cmd := fmt.Sprintf("/restic -r %s forget", r.Spec.Destination.Path) if r.Spec.RetentionPolicy.KeepLastSnapshots > 0 { - cmd = fmt.Sprintf("%s --%s %d", cmd, rapi.KeepLast, r.Spec.RetentionPolicy.KeepLastSnapshots) + cmd = fmt.Sprintf("%s --%s %d", cmd, sapi.KeepLast, r.Spec.RetentionPolicy.KeepLastSnapshots) } if r.Spec.RetentionPolicy.KeepHourlySnapshots > 0 { - cmd = fmt.Sprintf("%s --%s %d", cmd, rapi.KeepHourly, r.Spec.RetentionPolicy.KeepHourlySnapshots) + cmd = fmt.Sprintf("%s --%s %d", cmd, sapi.KeepHourly, r.Spec.RetentionPolicy.KeepHourlySnapshots) } if r.Spec.RetentionPolicy.KeepDailySnapshots > 0 { - cmd = fmt.Sprintf("%s --%s %d", cmd, rapi.KeepDaily, r.Spec.RetentionPolicy.KeepDailySnapshots) + cmd = fmt.Sprintf("%s --%s %d", cmd, sapi.KeepDaily, r.Spec.RetentionPolicy.KeepDailySnapshots) } if r.Spec.RetentionPolicy.KeepWeeklySnapshots > 0 { - cmd = fmt.Sprintf("%s --%s %d", cmd, rapi.KeepWeekly, r.Spec.RetentionPolicy.KeepWeeklySnapshots) + cmd = fmt.Sprintf("%s --%s %d", cmd, sapi.KeepWeekly, r.Spec.RetentionPolicy.KeepWeeklySnapshots) } if r.Spec.RetentionPolicy.KeepMonthlySnapshots > 0 { - cmd = fmt.Sprintf("%s --%s %d", cmd, rapi.KeepMonthly, r.Spec.RetentionPolicy.KeepMonthlySnapshots) + cmd = fmt.Sprintf("%s --%s %d", cmd, sapi.KeepMonthly, r.Spec.RetentionPolicy.KeepMonthlySnapshots) } if r.Spec.RetentionPolicy.KeepYearlySnapshots > 0 { - cmd = fmt.Sprintf("%s --%s %d", cmd, rapi.KeepYearly, r.Spec.RetentionPolicy.KeepYearlySnapshots) + cmd = fmt.Sprintf("%s --%s %d", cmd, sapi.KeepYearly, r.Spec.RetentionPolicy.KeepYearlySnapshots) } if len(r.Spec.RetentionPolicy.KeepTags) != 0 { for _, t := range r.Spec.RetentionPolicy.KeepTags { @@ -294,35 +293,3 @@ func getPasswordFromSecret(client clientset.Interface, secretName, namespace str } return string(password), nil } - -func restikCronSuccessfullyAdded() { - analytics.SendEvent("restic-cron", "added", "success") -} - -func restikCronFailedToAdd() { - analytics.SendEvent("restic-cron", "added", "failure") -} - -func restikCronSuccessfullyModified() { - analytics.SendEvent("restic-cron", "modified", "success") -} - -func restikCronFailedToModify() { - analytics.SendEvent("restic-cron", "modified", "failure") -} - -func restikBackupSuccess() { - analytics.SendEvent("restic-cron", "backup", "success") -} - -func restikBackupFailure() { - analytics.SendEvent("restic-cron", "backup", "failure") -} - -func restikJobSuccess() { - analytics.SendEvent("restic-cron", "job", "success") -} - -func restikJobFailure() { - analytics.SendEvent("restic-cron", "job", "failure") -} diff --git a/pkg/cron/events.go b/pkg/cron/events.go new file mode 100644 index 000000000..3a0abbbc1 --- /dev/null +++ b/pkg/cron/events.go @@ -0,0 +1,37 @@ +package cron + +import ( + "github.com/appscode/stash/pkg/analytics" +) + +func crondSuccessfullyAdded() { + analytics.SendEvent("crond", "added", "success") +} + +func crondFailedToAdd() { + analytics.SendEvent("crond", "added", "failure") +} + +func crondSuccessfullyModified() { + analytics.SendEvent("crond", "modified", "success") +} + +func crondFailedToModify() { + analytics.SendEvent("crond", "modified", "failure") +} + +func backupSuccess() { + analytics.SendEvent("crond", "backup", "success") +} + +func backupFailure() { + analytics.SendEvent("crond", "backup", "failure") +} + +func stashJobSuccess() { + analytics.SendEvent("crond", "job", "success") +} + +func stashJobFailure() { + analytics.SendEvent("crond", "job", "failure") +} diff --git a/pkg/docker/images.go b/pkg/docker/images.go index 4493fb04a..e51db431b 100644 --- a/pkg/docker/images.go +++ b/pkg/docker/images.go @@ -1,12 +1,12 @@ package docker const ( - ImageOperator = "appscode/restik" + ImageOperator = "appscode/stash" ) const ( - OperatorName = "restik-operator" - RestikContainer = "restik" - RestikNamespace = "RESTIK_NAMESPACE" - RestikName = "RESTIK_NAME" + OperatorName = "stash-operator" + StashContainer = "stash" + StashNamespace = "STASH_NAMESPACE" + StashName = "STASH_NAME" ) diff --git a/run.go b/run.go index 3de9506f8..f15836793 100644 --- a/run.go +++ b/run.go @@ -6,10 +6,10 @@ import ( stringz "github.com/appscode/go/strings" v "github.com/appscode/go/version" "github.com/appscode/log" - rcs "github.com/appscode/restik/client/clientset" - "github.com/appscode/restik/pkg/analytics" - "github.com/appscode/restik/pkg/controller" - "github.com/appscode/restik/pkg/docker" + rcs "github.com/appscode/stash/client/clientset" + "github.com/appscode/stash/pkg/analytics" + "github.com/appscode/stash/pkg/controller" + "github.com/appscode/stash/pkg/docker" "github.com/prometheus/client_golang/prometheus/promhttp" "github.com/spf13/cobra" clientset "k8s.io/client-go/kubernetes" @@ -27,7 +27,7 @@ func NewCmdRun(version string) *cobra.Command { cmd := &cobra.Command{ Use: "run", - Short: "Run restik operator", + Short: "Run Stash operator", PreRun: func(cmd *cobra.Command, args []string) { if enableAnalytics { analytics.Enable() @@ -47,9 +47,9 @@ func NewCmdRun(version string) *cobra.Command { log.Fatalln(err) } kubeClient := clientset.NewForConfigOrDie(config) - restikClient := rcs.NewForConfigOrDie(config) + stashClient := rcs.NewForConfigOrDie(config) - ctrl := controller.NewController(kubeClient, restikClient, tag) + ctrl := controller.NewController(kubeClient, stashClient, tag) err = ctrl.Setup() if err != nil { log.Fatalln(err) @@ -65,7 +65,6 @@ func NewCmdRun(version string) *cobra.Command { } cmd.Flags().StringVar(&masterURL, "master", masterURL, "The address of the Kubernetes API server (overrides any value in kubeconfig)") cmd.Flags().StringVar(&kubeconfigPath, "kubeconfig", kubeconfigPath, "Path to kubeconfig file with authorization information (the master location is set by the master flag).") - cmd.Flags().StringVar(&tag, "sidecar-tag", tag, "Tag of appscode/restik used as sidecar") cmd.Flags().StringVar(&address, "address", address, "Address to listen on for web interface and telemetry.") cmd.Flags().BoolVar(&enableAnalytics, "analytics", enableAnalytics, "Send analytical event to Google Analytics")