-
Notifications
You must be signed in to change notification settings - Fork 316
Develop new storage driver for OpenSDS
Leon Wang edited this page Jun 20, 2019
·
5 revisions
Here is a tutorial guiding vendors and new contributors to get familiar with OpenSDS by demonstrating how to develop new block storage driver.
Since all the new commit will be merged to the development branch firstly, so the new driver branch should be created tracking with the development branch.
cd $GOPATH/src/github.com/opensds/opensds
git checkout -b new_driver origin/development
All drivers should be implement in contrib/drivers/
.
- create a
newdriver
folder.
mkdir -p contrib/drivers/newdriver
touch contrib/drivers/newdriver/driver.go
- Develop some driver code like blow:
// Copyright 2019 The OpenSDS 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 newdriver
import (
log "github.com/golang/glog"
. "github.com/opensds/opensds/contrib/drivers/utils/config"
. "github.com/opensds/opensds/pkg/model"
pb "github.com/opensds/opensds/pkg/model/proto"
"github.com/opensds/opensds/pkg/utils/config"
)
const (
DefaultConfPath = "/etc/opensds/driver/new_driver.yaml"
NamePrefix = "opensds"
)
// These authentication structure an example, you change it depending on you requirements.
type AuthOptions struct {
Endpoint string `yaml:"endpoint"`
Name string `yaml:"name,flow"`
Password string `yaml:"password,flow"`
}
type Config struct {
AuthOptions `yaml:"authOptions"`
Pool map[string]PoolProperties `yaml:"pool,flow"`
}
type Driver struct {
conf *Config
}
func (d *Driver) Setup() error {
conf := &Config{}
d.conf = conf
path := config.CONF.OsdsDock.Backends.NewDriver.ConfigPath
if "" == path {
path = DefaultConfPath
}
Parse(conf, path)
return nil
}
func (d *Driver) Unset() error {
return nil
}
func (d *Driver) CreateVolume(opt *pb.CreateVolumeOpts) (*VolumeSpec, error) {
log.Info("CreateVolume ...")
// TODO: create a volume
return &VolumeSpec{
BaseModel: &BaseModel{
Id: opt.GetId(),
},
Name: opt.GetName(),
Size: opt.Size,
Description: opt.GetDescription(),
AvailabilityZone: opt.GetAvailabilityZone(),
PoolId: opt.GetPoolId(),
Metadata: nil,
}, nil
}
func (d *Driver) PullVolume(volIdentifier string) (*VolumeSpec, error) {
// Not used , do nothing
return nil, nil
}
func (d *Driver) DeleteVolume(opt *pb.DeleteVolumeOpts) error {
log.Info("DeleteVolume ...")
// TODO: delete a volume
return nil
}
func (d *Driver) ExtendVolume(opt *pb.ExtendVolumeOpts) (*VolumeSpec, error) {
log.Info("ExtendVolume ...")
// TODO: extend a volume
return &VolumeSpec{
BaseModel: &BaseModel{
Id: opt.GetId(),
},
Name: opt.GetName(),
Size: opt.GetSize(),
Description: opt.GetDescription(),
AvailabilityZone: opt.GetAvailabilityZone(),
}, nil
}
func (d *Driver) InitializeConnection(opt *pb.CreateVolumeAttachmentOpts) (*ConnectionInfo, error) {
log.Info("InitializeConnection ...")
// TODO: initialize a connection
return &ConnectionInfo{
DriverVolumeType: ISCSIProtocol,
ConnectionData: map[string]interface{}{},
}, nil
}
func (d *Driver) TerminateConnection(opt *pb.DeleteVolumeAttachmentOpts) error {
log.Info("InitializeConnection ...")
//TODO: terminate a connection
return nil
}
func (d *Driver) CreateSnapshot(opt *pb.CreateVolumeSnapshotOpts) (*VolumeSnapshotSpec, error) {
log.Info("CreateSnapshot ...")
// TODO: create a snapshot
return &VolumeSnapshotSpec{
BaseModel: &BaseModel{
Id: opt.GetId(),
},
Name: opt.GetName(),
Description: opt.GetDescription(),
VolumeId: opt.GetVolumeId(),
Size: opt.GetSize(),
}, nil
}
func (d *Driver) PullSnapshot(snapIdentifier string) (*VolumeSnapshotSpec, error) {
// Not used, do nothing
return nil, nil
}
func (d *Driver) DeleteSnapshot(opt *pb.DeleteVolumeSnapshotOpts) error {
log.Info("DeleteSnapshot ...")
// TODO: delete snapshot
return nil
}
func (d *Driver) ListPools() ([]*StoragePoolSpec, error) {
log.Info("ListPools ...")
var pols []*StoragePoolSpec
// TODO: Get all pools from actual storage backend, and
// filter them by items that is configured in /etc/opensds/driver/newdriver.yaml
return pols, nil
}
// The interfaces blow are optional, so implement it or not depends on you.
func (d *Driver) InitializeSnapshotConnection(opt *pb.CreateSnapshotAttachmentOpts) (*ConnectionInfo, error) {
return nil, &NotImplementError{S: "method InitializeSnapshotConnection has not been implemented yet."}
}
func (d *Driver) TerminateSnapshotConnection(opt *pb.DeleteSnapshotAttachmentOpts) error {
return &NotImplementError{S: "method TerminateSnapshotConnection has not been implemented yet."}
}
func (d *Driver) CreateVolumeGroup(
opt *pb.CreateVolumeGroupOpts,
vg *VolumeGroupSpec) (*VolumeGroupSpec, error) {
return nil, &NotImplementError{S: "method CreateVolumeGroup has not been implemented yet."}
}
func (d *Driver) UpdateVolumeGroup(
opt *pb.UpdateVolumeGroupOpts,
vg *VolumeGroupSpec,
addVolumesRef []*VolumeSpec,
removeVolumesRef []*VolumeSpec) (*VolumeGroupSpec, []*VolumeSpec, []*VolumeSpec, error) {
return nil, nil, nil, &NotImplementError{S: "method UpdateVolumeGroup has not been implemented yet."}
}
func (d *Driver) DeleteVolumeGroup(
opt *pb.DeleteVolumeGroupOpts,
vg *VolumeGroupSpec,
volumes []*VolumeSpec) (*VolumeGroupSpec, []*VolumeSpec, error) {
return nil, nil, &NotImplementError{S: "method DeleteVolumeGroup has not been implemented yet."}
}
- Add some code in
contrib/drivers/driver.go
, soosdsdock
can find your driver.
import (
"github.com/opensds/opensds/contrib/drivers/newdriver"
)
// Init
func Init(resourceType string) VolumeDriver {
var d VolumeDriver
switch resourceType {
case config.CinderDriverType:
d = &cinder.Driver{}
break
case config.CephDriverType:
d = &ceph.Driver{}
break
case config.LVMDriverType:
d = &lvm.Driver{}
break
case config.HuaweiDoradoDriverType:
d = &dorado.Driver{}
break
case config.HuaweiFusionStorageDriverType:
d = &fusionstorage.Driver{}
case config.HpeNimbleDriverType:
d = &nimble.Driver{}
break
// the new dirver is here
case "new_driver":
d = &newdriver.Driver{}
default:
d = &sample.Driver{}
break
}
d.Setup()
return d
}
// Clean
func Clean(d VolumeDriver) VolumeDriver {
// Execute different clean operations according to the VolumeDriver type.
switch d.(type) {
case *cinder.Driver:
break
case *ceph.Driver:
break
case *lvm.Driver:
break
case *dorado.Driver:
break
case *fusionstorage.Driver:
break
case *nimble.Driver:
break
// new driver clean up operation
case *newdriver.Driver:
break
default:
break
}
d.Unset()
d = nil
return d
}
- Add global configuration structure in
./pkg/utils/config/config_define.go
type Backends struct {
Ceph BackendProperties `conf:"ceph"`
Cinder BackendProperties `conf:"cinder"`
Sample BackendProperties `conf:"sample"`
LVM BackendProperties `conf:"lvm"`
HuaweiDorado BackendProperties `conf:"huawei_dorado"`
HuaweiFusionStorage BackendProperties `conf:"huawei_fusionstorage"`
HpeNimble BackendProperties `conf:"hpe_nimble"`
NFS BackendProperties `conf:"nfs"`
// new driver global configuration is here
NewDriver BackendProperties `conf:"new_driver"`
}
- Build the OpenSDS binary files, the output files are in the
./build/out/bin
root@ubuntu:~/gopath/src/github.com/opensds/opensds# make
mkdir -p /root/gopath/src/github.com/opensds/opensds/build/out
go build -ldflags '-w -s' -o /root/gopath/src/github.com/opensds/opensds/build/out/bin/osdsdock github.com/opensds/opensds/cmd/osdsdock
go build -ldflags '-w -s' -o /root/gopath/src/github.com/opensds/opensds/build/out/bin/osdslet github.com/opensds/opensds/cmd/osdslet
go build -ldflags '-w -s' -o /root/gopath/src/github.com/opensds/opensds/build/out/bin/osdsapiserver github.com/opensds/opensds/cmd/osdsapiserver
go build -ldflags '-w -s' -o /root/gopath/src/github.com/opensds/opensds/build/out/bin/osdsctl github.com/opensds/opensds/osdsctl
- Edit the global configuration file to enable the 'new_driver' backend.
[osdsapiserver]
api_endpoint = 0.0.0.0:50040
auth_strategy = noauth
[osdslet]
api_endpoint = 127.0.0.1:50049
[osdsdock]
api_endpoint = 127.0.0.1:50050
# Choose the type of dock resource, only support 'provisioner' and 'attacher'.
dock_type = provisioner
# Specify which backends should be enabled, sample,ceph,cinder,lvm and so on.
enabled_backends = new_driver
# new driver section
[new_driver]
name = new_driver
description = New driver Test
driver_name = new_driver
config_path = /etc/opensds/driver/new_driver.yaml
[database]
endpoint = 127.0.0.1:2379,127.0.0.1:2380
driver = etcd
- Add the driver self-defined yaml files ````vim /etc/opensds/driver/new_driver.yaml``. Here is an referenced configuration file based on
driver.go
.
authOptions:
endpoint: 192.168.0.100
name: opensds
password: opensds@123
pool:
pool001:
storageType: block
availabilityZone: nova-01
extras:
dataStorage:
provisioningPolicy: Thin
isSpaceEfficient: false
ioConnectivity:
accessProtocol: DSWARE
maxIOPS: 7000000
maxBWS: 600
advanced:
diskType: SSD
latency: 3ms
- Then start the OpenSDS services: osdsdock, osdslet and osdsapiserver. For debugging reason, you can start these services in terminal.
killall osdsdock osdslet osdsapiserver
./build/out/bin/osdsdock --logtostderr -daemon -v 8
./build/out/bin/osdslet --logtostderr -daemon -v 8
./build/out/bin/osdsapiserver --logtostderr -daemon -v 8
- Check if you driver is you already up.
If you find a new dock named
new_driver
, congratulations your driver is deployed successfully.
root@ubuntu:~/gopath/src/github.com/opensds/opensds# ./build/out/bin/osdsctl dock list
+--------------------------------------+------------+-----------------+--------------------+------------+
| Id | Name | Description | Endpoint | DriverName |
+--------------------------------------+------------+-----------------+--------------------+------------+
| 7acbb377-9bb1-5688-8e8b-48bfa6e48703 | new_driver | New driver Test | 127.0.0.1:50050 | new_driver |
+--------------------------------------+------------+-----------------+--------------------+------------+
Hope you could enjoy it, and more suggestions are welcomed!