Merge "Implemet framework of flexvolume driver"
This commit is contained in:
commit
6231a2324f
|
@ -0,0 +1,31 @@
|
|||
# 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.
|
||||
|
||||
"""Start FlexVolume driver of Cinder"""
|
||||
|
||||
from oslo_serialization import jsonutils
|
||||
import sys
|
||||
|
||||
from fuxi_kubernetes.common import constants
|
||||
from fuxi_kubernetes.flex_volume_drivers.drivers.cinder import cinder
|
||||
|
||||
|
||||
def main():
|
||||
"""Entry of FlexVolume driver for Cinder
|
||||
|
||||
/fuxi_kubernetes/flex_volume_drivers/driver/cinder/cinder.sh will
|
||||
call this function, then read the output and send it to Kubernetes.
|
||||
"""
|
||||
|
||||
result = cinder.DriverCinder()(sys.argv[1:])
|
||||
print(jsonutils.dumps(result()))
|
||||
sys.exit((0 if result.status == constants.STATUS_SUCCESS else 1))
|
|
@ -0,0 +1,17 @@
|
|||
# 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.
|
||||
|
||||
"""Start server of FlexVolume driver"""
|
||||
|
||||
|
||||
def main():
|
||||
raise NotImplemented()
|
|
@ -0,0 +1,65 @@
|
|||
# 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.
|
||||
|
||||
|
||||
VOLUME_DRIVER_CMD = (
|
||||
CMD_INIT,
|
||||
CMD_GET_VOLUME_NAME,
|
||||
CMD_IS_ATTACHED,
|
||||
CMD_ATTACH,
|
||||
CMD_WAIT_FOR_ATTACH,
|
||||
CMD_MOUNT_DEVICE,
|
||||
CMD_DETACH,
|
||||
CMD_WAIT_FOR_DETACH,
|
||||
CMD_UNMOUNT_DEVICE,
|
||||
CMD_MOUNT,
|
||||
CMD_UNMOUNT
|
||||
) = (
|
||||
"init",
|
||||
"getvolumename",
|
||||
"isattached",
|
||||
"attach",
|
||||
"waitforattach",
|
||||
"mountdevice",
|
||||
"detach",
|
||||
"waitfordetach",
|
||||
"unmountdevice",
|
||||
"mount",
|
||||
"unmount",
|
||||
)
|
||||
|
||||
|
||||
VOLUME_DRIVER_CMD_OPT_ARG = (
|
||||
ARG_FSTYPE,
|
||||
ARG_RW,
|
||||
ARG_SECRET,
|
||||
ARG_FSGROUP,
|
||||
ARG_MOUNTS_DIR
|
||||
) = (
|
||||
"kubernetes.io/fsType",
|
||||
"kubernetes.io/readwrite",
|
||||
"kubernetes.io/secret",
|
||||
"kubernetes.io/fsGroup",
|
||||
"kubernetes.io/mountsDir",
|
||||
|
||||
)
|
||||
|
||||
|
||||
VOLUME_DRIVER_CMD_RESULT_STATUS = (
|
||||
STATUS_SUCCESS,
|
||||
STATUS_FAILURE,
|
||||
STATUS_NOT_SUPPORT
|
||||
) = (
|
||||
'Success',
|
||||
'Failed',
|
||||
'Not supported',
|
||||
)
|
|
@ -0,0 +1,21 @@
|
|||
# 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.
|
||||
|
||||
|
||||
class FuxiKubernetesException(Exception):
|
||||
"""Default Fuxi-kubernetes exception"""
|
||||
|
||||
|
||||
class InvalidVolumeDriverCmdParameter(FuxiKubernetesException):
|
||||
def __init__(self, reason):
|
||||
super(InvalidVolumeDriverCmdParameter, self).__init__(
|
||||
"Invalid FlexVolume driver cmd parameter, reason:%s" % reason)
|
|
@ -0,0 +1,153 @@
|
|||
# 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.
|
||||
|
||||
from oslo_serialization import jsonutils
|
||||
|
||||
from fuxi_kubernetes.common import constants
|
||||
from fuxi_kubernetes import exceptions
|
||||
|
||||
|
||||
class Result(object):
|
||||
__slots__ = ('status', 'message', 'device', 'volumeName', 'attached')
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
for k, v in kwargs.items():
|
||||
if k in self.__slots__:
|
||||
setattr(self, k, v)
|
||||
|
||||
def __call__(self):
|
||||
return {
|
||||
k: getattr(self, k)
|
||||
for k in self.__slots__ if hasattr(self, k)
|
||||
}
|
||||
|
||||
|
||||
class BaseVolumeDriver(object):
|
||||
|
||||
default_result = Result(status=constants.STATUS_NOT_SUPPORT)
|
||||
|
||||
def init(self):
|
||||
return Result(status=constants.STATUS_SUCCESS)
|
||||
|
||||
def get_volume_name(self, **kwargs):
|
||||
return self.default_result
|
||||
|
||||
def is_attached(self, host_name, **kwargs):
|
||||
return self.default_result
|
||||
|
||||
def attach(self, host_name, **kwargs):
|
||||
return self.default_result
|
||||
|
||||
def wait_for_attach(self, device_path, **kwargs):
|
||||
return self.default_result
|
||||
|
||||
def mount_device(self, device_mount_path, device_path, **kwargs):
|
||||
return self.default_result
|
||||
|
||||
def detach(self, device_path, host_name):
|
||||
return self.default_result
|
||||
|
||||
def wait_for_detach(self, device_path):
|
||||
return self.default_result
|
||||
|
||||
def unmount_device(self, device_mount_path):
|
||||
return self.default_result
|
||||
|
||||
def mount(self, mount_dir, **kwargs):
|
||||
return self.default_result
|
||||
|
||||
def unmount(self, mount_dir):
|
||||
return self.default_result
|
||||
|
||||
def __call__(self, argv):
|
||||
if not argv:
|
||||
return self.default_result
|
||||
|
||||
cmd = argv[0]
|
||||
if cmd not in constants.VOLUME_DRIVER_CMD:
|
||||
return self.default_result
|
||||
argv = argv[1:]
|
||||
|
||||
cmd_info = self._get_cmd_info(cmd)
|
||||
if len(argv) != cmd_info['required_params_num']:
|
||||
return Result(
|
||||
status=constants.STATUS_FAILURE,
|
||||
message='Miss parameters, require %d parameters, '
|
||||
'but receive %d' % (cmd_info['required_params_num'],
|
||||
len(argv)))
|
||||
try:
|
||||
return cmd_info['func'](argv)
|
||||
except Exception as ex:
|
||||
return Result(status=constants.STATUS_FAILURE,
|
||||
message=str(ex))
|
||||
|
||||
def _get_cmd_info(self, cmd):
|
||||
|
||||
def _load_json_param(data):
|
||||
try:
|
||||
return jsonutils.loads(data)
|
||||
except Exception:
|
||||
raise exceptions.InvalidVolumeDriverCmdParameter(
|
||||
"can not load json parameter:(%s)" % data)
|
||||
|
||||
return {
|
||||
constants.CMD_INIT: {
|
||||
'required_params_num': 0,
|
||||
'func': lambda argv: self.init()
|
||||
},
|
||||
constants.CMD_GET_VOLUME_NAME: {
|
||||
'required_params_num': 1,
|
||||
'func': lambda argv: self.get_volume_name(
|
||||
**(_load_json_param(argv[0])))
|
||||
},
|
||||
constants.CMD_IS_ATTACHED: {
|
||||
'required_params_num': 2,
|
||||
'func': lambda argv: self.is_attached(
|
||||
argv[1], **(_load_json_param(argv[0])))
|
||||
},
|
||||
constants.CMD_ATTACH: {
|
||||
'required_params_num': 2,
|
||||
'func': lambda argv: self.attach(
|
||||
argv[1], **(_load_json_param(argv[0])))
|
||||
},
|
||||
constants.CMD_WAIT_FOR_ATTACH: {
|
||||
'required_params_num': 2,
|
||||
'func': lambda argv: self.wait_for_attach(
|
||||
argv[0], **(_load_json_param(argv[1])))
|
||||
},
|
||||
constants.CMD_MOUNT_DEVICE: {
|
||||
'required_params_num': 3,
|
||||
'func': lambda argv: self.mount_device(
|
||||
argv[0], argv[1], **(_load_json_param(argv[2])))
|
||||
},
|
||||
constants.CMD_DETACH: {
|
||||
'required_params_num': 2,
|
||||
'func': lambda argv: self.detach(*argv)
|
||||
},
|
||||
constants.CMD_WAIT_FOR_DETACH: {
|
||||
'required_params_num': 1,
|
||||
'func': lambda argv: self.wait_for_detach(*argv)
|
||||
},
|
||||
constants.CMD_UNMOUNT_DEVICE: {
|
||||
'required_params_num': 1,
|
||||
'func': lambda argv: self.unmount_device(*argv)
|
||||
},
|
||||
constants.CMD_MOUNT: {
|
||||
'required_params_num': 2,
|
||||
'func': lambda argv: self.mount(
|
||||
argv[0], **(_load_json_param(argv[1])))
|
||||
},
|
||||
constants.CMD_UNMOUNT: {
|
||||
'required_params_num': 1,
|
||||
'func': lambda argv: self.unmount(*argv)
|
||||
},
|
||||
}.get(cmd)
|
|
@ -0,0 +1,20 @@
|
|||
# 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.
|
||||
|
||||
from fuxi_kubernetes.flex_volume_drivers.drivers import base
|
||||
|
||||
|
||||
class DriverCinder(base.BaseVolumeDriver):
|
||||
# TODO(zengchen): implement it.
|
||||
|
||||
def __init__(self):
|
||||
raise NotImplemented()
|
|
@ -0,0 +1,53 @@
|
|||
#!/bin/sh
|
||||
# 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.
|
||||
|
||||
|
||||
err() {
|
||||
echo -ne "$@" 1>&2
|
||||
}
|
||||
|
||||
|
||||
log() {
|
||||
echo -ne "$@" >&1
|
||||
}
|
||||
|
||||
|
||||
usage() {
|
||||
err "Invalid usage. Usage: "
|
||||
err "\t$0 init"
|
||||
err "\t$0 getvolumename <json params>"
|
||||
err "\t$0 isattached <json params> <nodename>"
|
||||
err "\t$0 attach <json params> <nodename>"
|
||||
err "\t$0 waitforattach <mount device> <json params>"
|
||||
err "\t$0 mountdevice <mount dir> <mount device> <json params>"
|
||||
err "\t$0 detach <mount device> <nodename>"
|
||||
err "\t$0 waitfordetach <mount device>"
|
||||
err "\t$0 unmountdevice <mount device>"
|
||||
err "\t$0 mount <mount dir> <json params>"
|
||||
err "\t$0 unmount <mount dir>"
|
||||
exit 1
|
||||
}
|
||||
|
||||
|
||||
if [ $# -lt 1 ]; then
|
||||
usage
|
||||
fi
|
||||
|
||||
out=$(fuxi-k8s-volume-driver-cinder "$@")
|
||||
code=$?
|
||||
if [ $code -eq 0 ]; then
|
||||
log "$out"
|
||||
else
|
||||
err "$out"
|
||||
fi
|
||||
exit $code
|
|
@ -0,0 +1,15 @@
|
|||
# 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.
|
||||
|
||||
"""Server of FlexVolume driver"""
|
||||
|
||||
# TODO(zengchen): implement it.
|
|
@ -0,0 +1,35 @@
|
|||
# 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.
|
||||
|
||||
from fuxi_kubernetes.common import constants
|
||||
from fuxi_kubernetes.flex_volume_drivers.drivers import base as base_driver
|
||||
from fuxi_kubernetes.tests.unit import base
|
||||
|
||||
|
||||
class TestBaseVolumeDriver(base.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(TestBaseVolumeDriver, self).setUp()
|
||||
self._driver = base_driver.BaseVolumeDriver()
|
||||
|
||||
def test_empty_argument(self):
|
||||
self.assertEqual(constants.STATUS_NOT_SUPPORT,
|
||||
self._driver([]).status)
|
||||
|
||||
def test_invalid_cmd(self):
|
||||
self.assertEqual(constants.STATUS_NOT_SUPPORT,
|
||||
self._driver(['abc']).status)
|
||||
|
||||
def test_load_json_fail(self):
|
||||
r = self._driver(['attach', 'abc', 'abc'])
|
||||
self.assertEqual(constants.STATUS_FAILURE, r.status)
|
||||
self.assertIn('can not load json parameter', r.message)
|
|
@ -3,3 +3,4 @@
|
|||
# process, which may cause wedges in the gate later.
|
||||
|
||||
pbr!=2.1.0,>=2.0.0 # Apache-2.0
|
||||
oslo.serialization>=1.10.0 # Apache-2.0
|
||||
|
|
|
@ -20,7 +20,12 @@ classifier =
|
|||
|
||||
[files]
|
||||
packages =
|
||||
fuxi-kubernetes
|
||||
fuxi_kubernetes
|
||||
|
||||
[entry_points]
|
||||
console_scripts =
|
||||
fuxi-k8s-volume-driver-cinder = fuxi_kubernetes.cmd.cinder:main
|
||||
fuxi-k8s-volume-driver-server = fuxi_kubernetes.cmd.driver_server:main
|
||||
|
||||
[build_sphinx]
|
||||
source-dir = doc/source
|
||||
|
|
Loading…
Reference in New Issue