Skip to content
This repository was archived by the owner on Dec 6, 2024. It is now read-only.

Commit 97eaa46

Browse files
committed
Sample driver: Implement ProvisionerCreateBucket
- Fix deployment files - Make repository org and version configurable for easier dev-test lifecycle - Fix EnvVar <-> CLI flag parsing in both sidecar and sample driver - Respond to context cancels correctly from grpc server
1 parent 756cfd2 commit 97eaa46

File tree

20 files changed

+464
-103
lines changed

20 files changed

+464
-103
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
FROM gcr.io/distroless/static:latest
2+
LABEL maintainers="Kubernetes COSI Authors"
3+
LABEL description="MinIO COSI driver"
4+
5+
COPY ./bin/minio-cosi-driver minio-cosi-driver
6+
ENTRYPOINT ["/minio-cosi-driver"]

Diff for: container-object-storage-interface-provisioner-sidecar/cmd/minio-cosi-driver/cmd.go

+44-3
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,14 @@ package main
1616
import (
1717
"context"
1818
"flag"
19+
"strings"
1920

2021
"github.com/spf13/cobra"
22+
"github.com/spf13/pflag"
2123
"github.com/spf13/viper"
2224

25+
"sigs.k8s.io/container-object-storage-interface-provisioner-sidecar/cmd/minio-cosi-driver/internal"
2326
"sigs.k8s.io/container-object-storage-interface-provisioner-sidecar/pkg/provisioner"
24-
"sigs.k8s.io/container-object-storage-interface-provisioner-sidecar/pkg/sampledriver"
2527

2628
"k8s.io/klog/v2"
2729
)
@@ -30,6 +32,10 @@ const provisionerName = "minio.objectstorage.k8s.io"
3032

3133
var (
3234
driverAddress = "unix:///var/lib/cosi/cosi.sock"
35+
36+
minioAccessKey = ""
37+
minioSecretKey = ""
38+
minioHost = ""
3339
)
3440

3541
var cmd = &cobra.Command{
@@ -45,6 +51,7 @@ var cmd = &cobra.Command{
4551

4652
func init() {
4753
viper.AutomaticEnv()
54+
viper.SetEnvKeyReplacer(strings.NewReplacer("-", "_"))
4855

4956
flag.Set("alsologtostderr", "true")
5057
kflags := flag.NewFlagSet("klog", flag.ExitOnError)
@@ -54,18 +61,52 @@ func init() {
5461
persistentFlags.AddGoFlagSet(kflags)
5562

5663
stringFlag := persistentFlags.StringVarP
64+
5765
stringFlag(&driverAddress,
5866
"driver-addr",
5967
"d",
6068
driverAddress,
6169
"path to unix domain socket where driver should listen")
6270

71+
stringFlag(&minioHost,
72+
"minio-host",
73+
"m",
74+
minioHost,
75+
"endpoint where minio server is listening")
76+
77+
stringFlag(&minioAccessKey,
78+
"minio-access-key",
79+
"a",
80+
minioAccessKey,
81+
"access key for minio")
82+
83+
stringFlag(&minioSecretKey,
84+
"minio-secret-key",
85+
"s",
86+
minioSecretKey,
87+
"secret key for minio")
88+
6389
viper.BindPFlags(cmd.PersistentFlags())
90+
cmd.PersistentFlags().VisitAll(func(f *pflag.Flag) {
91+
if viper.IsSet(f.Name) && viper.GetString(f.Name) != "" {
92+
cmd.PersistentFlags().Set(f.Name, viper.GetString(f.Name))
93+
}
94+
})
6495
}
6596

6697
func run(ctx context.Context, args []string) error {
67-
identityServer, bucketProvisioner := sampledriver.NewDriver(provisionerName)
68-
server, err := provisioner.NewDefaultCOSIProvisionerServer(driverAddress, identityServer, bucketProvisioner)
98+
identityServer, bucketProvisioner, err := internal.NewDriver(ctx,
99+
provisionerName,
100+
minioHost,
101+
minioAccessKey,
102+
minioSecretKey)
103+
if err != nil {
104+
return err
105+
}
106+
107+
server, err := provisioner.NewDefaultCOSIProvisionerServer(driverAddress,
108+
identityServer,
109+
bucketProvisioner)
69110
if err != nil {
70111
return err
71112
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// Copyright 2021 The Kubernetes Authors.
2+
// Licensed under the Apache License, Version 2.0 (the "License");
3+
// You may not use this file except in compliance with the License.
4+
// You may obtain a copy of the License at
5+
//
6+
// http://www.apache.org/licenses/LICENSE-2.0
7+
//
8+
// Unless required by applicable law or agreed to in writing, software
9+
// distributed under the License is distributed on an "AS IS" BASIS,
10+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
// See the License for the specific language governing permissions and
12+
// limitations under the License.
13+
14+
package internal
15+
16+
import (
17+
"context"
18+
19+
"sigs.k8s.io/container-object-storage-interface-provisioner-sidecar/cmd/minio-cosi-driver/internal/minio"
20+
)
21+
22+
func NewDriver(ctx context.Context, provisioner, minioHost, accessKey, secretKey string) (*IdentityServer, *ProvisionerServer, error) {
23+
mc, err := minio.NewClient(ctx, minioHost, accessKey, secretKey)
24+
if err != nil {
25+
return nil, nil, err
26+
}
27+
28+
return &IdentityServer{
29+
provisioner: provisioner,
30+
}, &ProvisionerServer{
31+
provisioner: provisioner,
32+
mc: mc,
33+
}, nil
34+
}

Diff for: container-object-storage-interface-provisioner-sidecar/pkg/sampledriver/identity.go renamed to container-object-storage-interface-provisioner-sidecar/cmd/minio-cosi-driver/internal/identity.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
// See the License for the specific language governing permissions and
1212
// limitations under the License.
1313

14-
package sampledriver
14+
package internal
1515

1616
import (
1717
"context"
@@ -33,7 +33,7 @@ func (id *IdentityServer) ProvisionerGetInfo(ctx context.Context,
3333

3434
if id.provisioner == "" {
3535
klog.ErrorS(errors.New("provisioner name cannot be empty"), "Invalid argument")
36-
return nil, status.Error(codes.Unavailable, "Provisioner name not configured")
36+
return nil, status.Error(codes.InvalidArgument, "ProvisionerName is empty")
3737
}
3838

3939
return &cosi.ProvisionerGetInfoResponse{
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// Copyright 2021 The Kubernetes Authors.
2+
// Licensed under the Apache License, Version 2.0 (the "License");
3+
// You may not use this file except in compliance with the License.
4+
// You may obtain a copy of the License at
5+
//
6+
// http://www.apache.org/licenses/LICENSE-2.0
7+
//
8+
// Unless required by applicable law or agreed to in writing, software
9+
// distributed under the License is distributed on an "AS IS" BASIS,
10+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
// See the License for the specific language governing permissions and
12+
// limitations under the License.
13+
14+
package minio
15+
16+
import (
17+
"context"
18+
19+
"github.com/minio/minio-go/v7"
20+
"github.com/pkg/errors"
21+
)
22+
23+
var ErrBucketAlreadyExists = errors.New("Bucket Already Exists")
24+
25+
type MakeBucketOptions minio.MakeBucketOptions
26+
27+
func (x *C) CreateBucket(ctx context.Context, bucketName string, options MakeBucketOptions) (string, error) {
28+
if err := x.client.MakeBucket(ctx, bucketName, minio.MakeBucketOptions(options)); err != nil {
29+
errCode := minio.ToErrorResponse(err).Code
30+
if errCode == "BucketAlreadyExists" || errCode == "BucketAlreadyOwnedByYou" {
31+
return bucketName, ErrBucketAlreadyExists
32+
}
33+
return "", err
34+
}
35+
return bucketName, nil
36+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
// Copyright 2021 The Kubernetes Authors.
2+
// Licensed under the Apache License, Version 2.0 (the "License");
3+
// You may not use this file except in compliance with the License.
4+
// You may obtain a copy of the License at
5+
//
6+
// http://www.apache.org/licenses/LICENSE-2.0
7+
//
8+
// Unless required by applicable law or agreed to in writing, software
9+
// distributed under the License is distributed on an "AS IS" BASIS,
10+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
// See the License for the specific language governing permissions and
12+
// limitations under the License.
13+
14+
package minio
15+
16+
import (
17+
"context"
18+
"net/url"
19+
20+
"github.com/google/uuid"
21+
"github.com/pkg/errors"
22+
23+
min "github.com/minio/minio-go/v7"
24+
"github.com/minio/minio-go/v7/pkg/credentials"
25+
26+
"k8s.io/klog/v2"
27+
)
28+
29+
type C struct {
30+
accessKey string
31+
secretKey string
32+
host *url.URL
33+
34+
client *min.Client
35+
}
36+
37+
func NewClient(ctx context.Context, minioHost, accessKey, secretKey string) (*C, error) {
38+
if minioHost == "" {
39+
return nil, errors.New("minio host cannot be empty")
40+
}
41+
host, err := url.Parse(minioHost)
42+
if err != nil {
43+
return nil, err
44+
}
45+
46+
secure := false
47+
switch host.Scheme {
48+
case "http":
49+
case "https":
50+
secure = true
51+
default:
52+
return nil, errors.New("invalid url scheme for minio endpoint")
53+
}
54+
55+
clChan := make(chan *min.Client)
56+
errChan := make(chan error)
57+
go func() {
58+
klog.V(3).InfoS("Connecting to MinIO", "endpoint", host.Host)
59+
60+
cl, err := min.New(host.Host, &min.Options{
61+
Creds: credentials.NewStaticV4(accessKey, secretKey, ""),
62+
Secure: secure,
63+
})
64+
if err != nil {
65+
errChan <- err
66+
}
67+
_, err = cl.BucketExists(ctx, uuid.New().String())
68+
if err != nil {
69+
if errResp, ok := err.(min.ErrorResponse); ok {
70+
if errResp.Code == "NoSuchBucket" {
71+
clChan <- cl
72+
return
73+
}
74+
if errResp.StatusCode == 403 {
75+
errChan <- errors.Wrap(errors.New("Access Denied"), "Connection to MinIO Failed")
76+
return
77+
}
78+
}
79+
errChan <- errors.Wrap(err, "Connection to MinIO Failed")
80+
return
81+
}
82+
83+
clChan <- cl
84+
klog.InfoS("Successfully connected to MinIO")
85+
}()
86+
87+
select {
88+
case <-ctx.Done():
89+
return nil, ctx.Err()
90+
case cl := <-clChan:
91+
return &C{
92+
accessKey: accessKey,
93+
secretKey: secretKey,
94+
host: host,
95+
96+
client: cl,
97+
}, nil
98+
case err := <-errChan:
99+
return nil, err
100+
}
101+
}

Diff for: container-object-storage-interface-provisioner-sidecar/pkg/sampledriver/driver.go renamed to container-object-storage-interface-provisioner-sidecar/cmd/minio-cosi-driver/internal/minio/const.go

+4-8
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,8 @@
1111
// See the License for the specific language governing permissions and
1212
// limitations under the License.
1313

14-
package sampledriver
14+
package minio
1515

16-
func NewDriver(provisioner string) (*IdentityServer, *ProvisionerServer) {
17-
return &IdentityServer{
18-
provisioner: provisioner,
19-
}, &ProvisionerServer{
20-
provisioner: provisioner,
21-
}
22-
}
16+
const (
17+
ObjectLocking = "objectlocking.min.io"
18+
)

0 commit comments

Comments
 (0)