Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
gitpod-io
GitHub Repository: gitpod-io/gitpod
Path: blob/main/install/installer/pkg/common/storage.go
2500 views
1
// Copyright (c) 2021 Gitpod GmbH. All rights reserved.
2
// Licensed under the GNU Affero General Public License (AGPL).
3
// See License.AGPL.txt in the project root for license information.
4
5
package common
6
7
import (
8
"fmt"
9
10
"path/filepath"
11
12
storageconfig "github.com/gitpod-io/gitpod/content-service/api/config"
13
"github.com/gitpod-io/gitpod/installer/pkg/config/v1/experimental"
14
"k8s.io/utils/pointer"
15
16
corev1 "k8s.io/api/core/v1"
17
)
18
19
const StorageMount = "/mnt/secrets/storage"
20
21
// StorageConfig produces config service configuration from the installer config
22
23
func useMinio(context *RenderContext) bool {
24
// Minio is used for in-cluster storage and as a facade to non-GCP providers
25
return pointer.BoolDeref(context.Config.ObjectStorage.InCluster, false)
26
}
27
28
func StorageConfig(context *RenderContext) storageconfig.StorageConfig {
29
var res *storageconfig.StorageConfig
30
if context.Config.ObjectStorage.CloudStorage != nil {
31
res = &storageconfig.StorageConfig{
32
Kind: storageconfig.GCloudStorage,
33
GCloudConfig: storageconfig.GCPConfig{
34
Region: context.Config.Metadata.Region,
35
Project: context.Config.ObjectStorage.CloudStorage.Project,
36
CredentialsFile: filepath.Join(StorageMount, "service-account.json"),
37
},
38
}
39
}
40
41
if context.Config.ObjectStorage.S3 != nil {
42
res = &storageconfig.StorageConfig{
43
Kind: storageconfig.S3Storage,
44
S3Config: &storageconfig.S3Config{
45
Region: context.Config.Metadata.Region,
46
Bucket: context.Config.ObjectStorage.S3.BucketName,
47
},
48
}
49
50
if context.Config.ObjectStorage.S3.Credentials != nil && context.Config.ObjectStorage.S3.Credentials.Kind != "" {
51
res.S3Config.CredentialsFile = filepath.Join(StorageMount, "credentials")
52
}
53
}
54
55
if useMinio(context) {
56
res = &storageconfig.StorageConfig{
57
Kind: storageconfig.MinIOStorage,
58
MinIOConfig: storageconfig.MinIOConfig{
59
Endpoint: fmt.Sprintf("minio.%s.svc.cluster.local:%d", context.Namespace, MinioServiceAPIPort),
60
AccessKeyID: context.Values.StorageAccessKey,
61
SecretAccessKey: context.Values.StorageSecretKey,
62
Secure: false,
63
Region: "local", // Local Minio requires this value - workspace allocation fails if not set to this
64
ParallelUpload: 6,
65
},
66
}
67
}
68
69
if res == nil {
70
panic("no valid storage configuration set")
71
}
72
73
// 5 GiB
74
res.BlobQuota = 5 * 1024 * 1024 * 1024
75
if context.Config.ObjectStorage.BlobQuota != nil {
76
res.BlobQuota = *context.Config.ObjectStorage.BlobQuota
77
}
78
79
_ = context.WithExperimental(func(ucfg *experimental.Config) error {
80
if ucfg.Workspace != nil {
81
res.Stage = storageconfig.Stage(ucfg.Workspace.Stage)
82
}
83
return nil
84
})
85
86
return *res
87
}
88
89
// mountStorage performs the actual storage mount, which is common across all providers
90
func MountStorage(pod *corev1.PodSpec, secret string, container ...string) {
91
volumeName := "storage-volume"
92
93
pod.Volumes = append(pod.Volumes,
94
corev1.Volume{
95
Name: volumeName,
96
VolumeSource: corev1.VolumeSource{
97
Secret: &corev1.SecretVolumeSource{
98
SecretName: secret,
99
},
100
},
101
},
102
)
103
104
idx := make(map[string]struct{}, len(container))
105
if len(container) == 0 {
106
for _, c := range pod.Containers {
107
idx[c.Name] = struct{}{}
108
}
109
} else {
110
for _, c := range container {
111
idx[c] = struct{}{}
112
}
113
}
114
115
for i := range pod.Containers {
116
if _, ok := idx[pod.Containers[i].Name]; !ok {
117
continue
118
}
119
120
pod.Containers[i].VolumeMounts = append(pod.Containers[i].VolumeMounts,
121
corev1.VolumeMount{
122
Name: volumeName,
123
ReadOnly: true,
124
MountPath: StorageMount,
125
},
126
)
127
}
128
}
129
130
// AddStorageMounts adds mounts and volumes to a pod which are required for
131
// the storage configuration to function. If a list of containers is provided,
132
// the mounts are only added to those containers. If the list is empty, they're
133
// added to all containers.
134
func AddStorageMounts(ctx *RenderContext, pod *corev1.PodSpec, container ...string) error {
135
if ctx.Config.ObjectStorage.CloudStorage != nil {
136
MountStorage(pod, ctx.Config.ObjectStorage.CloudStorage.ServiceAccount.Name, container...)
137
138
return nil
139
}
140
141
if ctx.Config.ObjectStorage.S3 != nil {
142
if ctx.Config.ObjectStorage.S3.Credentials != nil {
143
MountStorage(pod, ctx.Config.ObjectStorage.S3.Credentials.Name, container...)
144
}
145
146
return nil
147
}
148
149
if useMinio(ctx) {
150
// builtin storage needs no extra mounts
151
return nil
152
}
153
154
return fmt.Errorf("no valid storage configuration set")
155
}
156
157
func NewEmptyDirVolume(name string) *corev1.Volume {
158
return &corev1.Volume{
159
Name: name,
160
VolumeSource: corev1.VolumeSource{
161
EmptyDir: &corev1.EmptyDirVolumeSource{},
162
},
163
}
164
}
165
166