-
Notifications
You must be signed in to change notification settings - Fork 86
/
restic.go
100 lines (88 loc) · 3.31 KB
/
restic.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
/*
Copyright The Stash Authors.
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 backup
import (
api "stash.appscode.dev/stash/apis/stash/v1alpha1"
"stash.appscode.dev/stash/pkg/eventer"
"stash.appscode.dev/stash/pkg/util"
"github.com/appscode/go/log"
"github.com/golang/glog"
core "k8s.io/api/core/v1"
clientsetscheme "k8s.io/client-go/kubernetes/scheme"
"k8s.io/client-go/tools/cache"
"k8s.io/client-go/tools/reference"
"kmodules.xyz/client-go/tools/queue"
)
func (c *Controller) initResticWatcher() {
// TODO: Watch one Restic object, when support for Kubernetes 1.8 is dropped.
// ref: https://github.com/kubernetes/kubernetes/pull/53345
c.rInformer = c.stashInformerFactory.Stash().V1alpha1().Restics().Informer()
c.rQueue = queue.New("Restic", c.opt.MaxNumRequeues, c.opt.NumThreads, c.runResticScheduler)
c.rInformer.AddEventHandler(cache.ResourceEventHandlerFuncs{
AddFunc: func(obj interface{}) {
if r, ok := obj.(*api.Restic); ok && r.Name == c.opt.ResticName && r.IsValid() == nil {
queue.Enqueue(c.rQueue.GetQueue(), r)
}
},
UpdateFunc: func(oldObj interface{}, newObj interface{}) {
old := oldObj.(*api.Restic)
nu := newObj.(*api.Restic)
if !util.ResticEqual(old, nu) && nu.Name == c.opt.ResticName && nu.IsValid() == nil {
queue.Enqueue(c.rQueue.GetQueue(), nu)
}
},
DeleteFunc: func(obj interface{}) {
// IndexerInformer uses a delta queue, therefore for deletes we have to use this
// key function.
if r, ok := obj.(*api.Restic); ok && r.Name == c.opt.ResticName {
queue.Enqueue(c.rQueue.GetQueue(), obj)
}
},
})
c.rLister = c.stashInformerFactory.Stash().V1alpha1().Restics().Lister()
}
// syncToStdout is the business logic of the controller. In this controller it simply prints
// information about the deployment to stdout. In case an error happened, it has to simply return the error.
// The retry logic should not be part of the business logic.
func (c *Controller) runResticScheduler(key string) error {
obj, exists, err := c.rInformer.GetIndexer().GetByKey(key)
if err != nil {
glog.Errorf("Fetching object with key %s from store failed with %v", key, err)
return err
}
if !exists {
// Below we will warm up our cache with a Restic, so that we will see a delete for one d
glog.Warningf("Restic %s does not exist anymore\n", key)
c.cron.Stop()
} else {
r := obj.(*api.Restic)
glog.Infof("Sync/Add/Update for Restic %s", r.GetName())
err := c.configureScheduler(r)
if err != nil {
ref, rerr := reference.GetReference(clientsetscheme.Scheme, r)
if rerr == nil {
c.recorder.Eventf(
ref,
core.EventTypeWarning,
eventer.EventReasonFailedToBackup,
"Failed to start Stash scheduler reason %v",
err,
)
} else {
log.Errorf("Failed to write event on %s %s. Reason: %s", r.Kind, r.Name, rerr)
}
log.Errorln(err)
}
}
return nil
}