forked from goodrain/rainbond
/
rainbondsssc.go
135 lines (118 loc) · 4.08 KB
/
rainbondsssc.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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
// RAINBOND, Application Management Platform
// Copyright (C) 2014-2017 Goodrain Co., Ltd.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version. For any non-GPL usage of Rainbond,
// one or multiple Commercial Licenses authorized by Goodrain Co., Ltd.
// must be obtained first.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
package provider
import (
"fmt"
"os"
"path"
"strconv"
"strings"
"github.com/goodrain/rainbond/db"
"github.com/Sirupsen/logrus"
"github.com/goodrain/rainbond/util"
"github.com/goodrain/rainbond/worker/master/volumes/provider/lib/controller"
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
type rainbondssscProvisioner struct {
// The directory to create PV-backing directories in
pvDir string
name string
}
// NewRainbondssscProvisioner creates a new Rainbond statefulset share volume provisioner
func NewRainbondssscProvisioner() controller.Provisioner {
sharePath := os.Getenv("SHARE_DATA_PATH")
if sharePath == "" {
sharePath = "/grdata"
}
return &rainbondssscProvisioner{
pvDir: sharePath,
name: "rainbond.io/provisioner-sssc",
}
}
var _ controller.Provisioner = &rainbondssscProvisioner{}
// Provision creates a storage asset and returns a PV object representing it.
func (p *rainbondssscProvisioner) Provision(options controller.VolumeOptions) (*v1.PersistentVolume, error) {
tenantID := options.PVC.Labels["tenant_id"]
serviceID := options.PVC.Labels["service_id"]
// v5.0.4 Previous versions
hostpath := path.Join(p.pvDir, "tenant", tenantID, "service", serviceID, options.PVC.Name)
// after v5.0.4,change host path
// Directory path has nothing to do with volume ID
// Directory path bound to volume mount path
if util.DirIsEmpty(hostpath) {
podName := getPodNameByPVCName(options.PVC.Name)
volumeID := getVolumeIDByPVCName(options.PVC.Name)
if volumeID != 0 {
volume, err := db.GetManager().TenantServiceVolumeDao().GetVolumeByID(volumeID)
if err != nil {
logrus.Errorf("get volume by id %d failure %s", volumeID, err.Error())
return nil, err
}
hostpath = path.Join(volume.HostPath, podName)
} else {
return nil, fmt.Errorf("can not parse volume id")
}
}
if err := util.CheckAndCreateDirByMode(hostpath, 0777); err != nil {
return nil, err
}
pv := &v1.PersistentVolume{
ObjectMeta: metav1.ObjectMeta{
Name: options.PVName,
Labels: options.PVC.Labels,
},
Spec: v1.PersistentVolumeSpec{
PersistentVolumeReclaimPolicy: options.PersistentVolumeReclaimPolicy,
AccessModes: options.PVC.Spec.AccessModes,
Capacity: v1.ResourceList{
v1.ResourceName(v1.ResourceStorage): options.PVC.Spec.Resources.Requests[v1.ResourceName(v1.ResourceStorage)],
},
PersistentVolumeSource: v1.PersistentVolumeSource{
HostPath: &v1.HostPathVolumeSource{
Path: hostpath,
},
},
},
}
logrus.Infof("create rainbondsssc pv %s for pvc %s", pv.Name, options.PVC.Name)
return pv, nil
}
// Delete removes the storage asset that was created by Provision represented
// by the given PV.
func (p *rainbondssscProvisioner) Delete(volume *v1.PersistentVolume) error {
return nil
}
func (p *rainbondssscProvisioner) Name() string {
return p.name
}
func getPodNameByPVCName(pvcName string) string {
pvcNames := strings.SplitN(pvcName, "-", 2)
if len(pvcNames) == 2 {
return pvcNames[1]
}
return pvcName
}
func getVolumeIDByPVCName(pvcName string) int {
pvcNames := strings.SplitN(pvcName, "-", 2)
fmt.Println(pvcNames)
if len(pvcNames) == 2 {
idStr := pvcNames[0][6:]
fmt.Println(idStr)
id, _ := strconv.Atoi(idStr)
return id
}
return 0
}