Files
my-rook-config/pkg/daemon/ceph/client/filesystem.go
T
Travis Nielsen 0298d1fb29 completed conversion for k8s 1.8 client conversion
move core rados packages under cluster folder

move daemons under daemon pkg

rename flex crd package to attachment

pin dep to k8s 1.8.2
2017-12-11 14:35:07 -08:00

202 lines
6.2 KiB
Go

/*
Copyright 2016 The Rook Authors. All rights reserved.
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 client
import (
"encoding/json"
"fmt"
"strconv"
"github.com/rook/rook/pkg/clusterd"
)
type CephFilesystem struct {
Name string `json:"name"`
MetadataPool string `json:"metadata_pool"`
MetadataPoolID int `json:"metadata_pool_id"`
DataPools []string `json:"data_pools"`
DataPoolIDs []int `json:"data_pool_ids"`
}
type CephFilesystemDetails struct {
ID int `json:"id"`
MDSMap MDSMap `json:"mdsmap"`
}
type MDSMap struct {
FilesystemName string `json:"fs_name"`
Enabled bool `json:"enabled"`
Root int `json:"root"`
TableServer int `json:"tableserver"`
MaxMDS int `json:"max_mds"`
In []int `json:"in"`
Up map[string]int `json:"up"`
MetadataPool int `json:"metadata_pool"`
DataPools []int `json:"data_pools"`
Failed []int `json:"failed"`
Damaged []int `json:"damaged"`
Stopped []int `json:"stopped"`
Info map[string]MDSInfo `json:"info"`
}
type MDSInfo struct {
GID int `json:"gid"`
Name string `json:"name"`
Rank int `json:"rank"`
State string `json:"state"`
Address string `json:"addr"`
}
func ListFilesystems(context *clusterd.Context, clusterName string) ([]CephFilesystem, error) {
args := []string{"fs", "ls"}
buf, err := ExecuteCephCommand(context, clusterName, args)
if err != nil {
return nil, fmt.Errorf("failed to list filesystems: %+v", err)
}
var filesystems []CephFilesystem
err = json.Unmarshal(buf, &filesystems)
if err != nil {
return nil, fmt.Errorf("unmarshal failed: %+v. raw buffer response: %s", err, string(buf))
}
return filesystems, nil
}
func GetFilesystem(context *clusterd.Context, clusterName string, fsName string) (*CephFilesystemDetails, error) {
args := []string{"fs", "get", fsName}
buf, err := ExecuteCephCommand(context, clusterName, args)
if err != nil {
return nil, fmt.Errorf("failed to get file system %s: %+v", fsName, err)
}
var fs CephFilesystemDetails
err = json.Unmarshal(buf, &fs)
if err != nil {
return nil, fmt.Errorf("unmarshal failed: %+v. raw buffer response: %s", err, string(buf))
}
return &fs, nil
}
func CreateFilesystem(context *clusterd.Context, clusterName, name, metadataPool string, dataPools []string, activeMDSCount int32) error {
if len(dataPools) == 0 {
return fmt.Errorf("at least one data pool is required")
}
// enable multiple file systems in case this is not the first
args := []string{"fs", "flag", "set", "enable_multiple", "true", confirmFlag}
_, err := ExecuteCephCommand(context, clusterName, args)
if err != nil {
// continue if this fails
logger.Warning("failed enabling multiple file systems. %+v", err)
}
// create the filesystem
args = []string{"fs", "new", name, metadataPool, dataPools[0]}
_, err = ExecuteCephCommand(context, clusterName, args)
if err != nil {
return fmt.Errorf("failed enabling ceph fs %s. %+v", name, err)
}
// add each additional pool
for i := 1; i < len(dataPools); i++ {
poolName := dataPools[i]
args = []string{"fs", "add_data_pool", name, poolName}
_, err = ExecuteCephCommand(context, clusterName, args)
if err != nil {
logger.Errorf("failed to add pool %s to file system %s. %+v", poolName, name, err)
}
}
// set the number of active mds instances
if activeMDSCount > 1 {
args = []string{"fs", "set", name, "max_mds", strconv.Itoa(int(activeMDSCount))}
_, err = ExecuteCephCommand(context, clusterName, args)
if err != nil {
logger.Warningf("failed setting active mds count to %d. %+v", activeMDSCount, err)
}
}
return nil
}
func MarkFilesystemAsDown(context *clusterd.Context, clusterName string, fsName string) error {
args := []string{"fs", "set", fsName, "cluster_down", "true"}
_, err := ExecuteCephCommand(context, clusterName, args)
if err != nil {
return fmt.Errorf("failed to set file system %s to cluster_down: %+v", fsName, err)
}
return nil
}
func FailMDS(context *clusterd.Context, clusterName string, gid int) error {
args := []string{"mds", "fail", strconv.Itoa(gid)}
_, err := ExecuteCephCommand(context, clusterName, args)
if err != nil {
return fmt.Errorf("failed to fail mds %d: %+v", gid, err)
}
return nil
}
func RemoveFilesystem(context *clusterd.Context, clusterName, fsName string) error {
fs, err := GetFilesystem(context, clusterName, fsName)
if err != nil {
return fmt.Errorf("filesystem %s not found. %+v", fsName, err)
}
args := []string{"fs", "rm", fsName, confirmFlag}
_, err = ExecuteCephCommand(context, clusterName, args)
if err != nil {
return fmt.Errorf("Failed to delete ceph fs %s. err=%+v", fsName, err)
}
err = deleteFSPools(context, clusterName, fs)
if err != nil {
return fmt.Errorf("failed to delete fs %s pools. %+v", fsName, err)
}
return nil
}
func deleteFSPools(context *clusterd.Context, clusterName string, fs *CephFilesystemDetails) error {
poolNames, err := GetPoolNamesByID(context, clusterName)
if err != nil {
return fmt.Errorf("failed to get pool names. %+v", err)
}
// delete the metadata pool
var lastErr error
if err := deleteFSPool(context, clusterName, poolNames, fs.MDSMap.MetadataPool); err != nil {
lastErr = err
}
// delete the data pools
for _, poolID := range fs.MDSMap.DataPools {
if err := deleteFSPool(context, clusterName, poolNames, poolID); err != nil {
lastErr = err
}
}
return lastErr
}
func deleteFSPool(context *clusterd.Context, clusterName string, poolNames map[int]string, id int) error {
name, ok := poolNames[id]
if !ok {
return fmt.Errorf("pool %d not found", id)
}
return DeletePool(context, clusterName, name)
}