forked from rook/rook
Merge pull request #2317 from jtlayton/filesystem
Allow filesystem specifications without pools
This commit is contained in:
@@ -191,10 +191,10 @@ type FilesystemList struct {
|
||||
// FilesystemSpec represents the spec of a file system
|
||||
type FilesystemSpec struct {
|
||||
// The metadata pool settings
|
||||
MetadataPool PoolSpec `json:"metadataPool"`
|
||||
MetadataPool PoolSpec `json:"metadataPool,omitempty"`
|
||||
|
||||
// The data pool settings
|
||||
DataPools []PoolSpec `json:"dataPools"`
|
||||
DataPools []PoolSpec `json:"dataPools,omitempty"`
|
||||
|
||||
// The mds pod info
|
||||
MetadataServer MetadataServerSpec `json:"metadataServer"`
|
||||
|
||||
@@ -109,7 +109,7 @@ func GetFilesystem(context *clusterd.Context, clusterName string, fsName string)
|
||||
}
|
||||
|
||||
// CreateFilesystem performs software configuration steps for Ceph to provide a new filesystem.
|
||||
func CreateFilesystem(context *clusterd.Context, clusterName, name, metadataPool string, dataPools []string, activeMDSCount int32) error {
|
||||
func CreateFilesystem(context *clusterd.Context, clusterName, name, metadataPool string, dataPools []string) error {
|
||||
if len(dataPools) == 0 {
|
||||
return fmt.Errorf("at least one data pool is required")
|
||||
}
|
||||
@@ -144,13 +144,6 @@ func CreateFilesystem(context *clusterd.Context, clusterName, name, metadataPool
|
||||
}
|
||||
}
|
||||
|
||||
// set the number of active mds instances
|
||||
if activeMDSCount > 1 {
|
||||
if err = SetNumMDSRanks(context, clusterName, name, activeMDSCount); err != nil {
|
||||
logger.Warningf("failed setting active mds count to %d. %+v", activeMDSCount, err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -105,7 +105,7 @@ func (f *Filesystem) CreateFilesystem(context *clusterd.Context, clusterName str
|
||||
}
|
||||
|
||||
// create the filesystem
|
||||
if err := client.CreateFilesystem(context, clusterName, f.Name, f.metadataPool.Name, dataPoolNames, f.activeMDSCount); err != nil {
|
||||
if err := client.CreateFilesystem(context, clusterName, f.Name, f.metadataPool.Name, dataPoolNames); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -113,8 +113,8 @@ func (f *Filesystem) CreateFilesystem(context *clusterd.Context, clusterName str
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeleteFilesystem removes the filesystem in Ceph and removes the Ceph file daemons.
|
||||
func DeleteFilesystem(context *clusterd.Context, clusterName, filesystemName string) error {
|
||||
// DownFilesystem marks the filesystem as down and the MDS' as failed
|
||||
func DownFilesystem(context *clusterd.Context, clusterName, filesystemName string) error {
|
||||
logger.Infof("Removing file system %s", filesystemName)
|
||||
|
||||
// mark the cephFS instance as cluster_down before removing
|
||||
@@ -133,11 +133,6 @@ func DeleteFilesystem(context *clusterd.Context, clusterName, filesystemName str
|
||||
}
|
||||
}
|
||||
|
||||
// Permanently remove the file system
|
||||
if err := client.RemoveFilesystem(context, clusterName, filesystemName); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
logger.Infof("Removed file system %s", filesystemName)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -41,13 +41,15 @@ func createFilesystem(
|
||||
return err
|
||||
}
|
||||
|
||||
var dataPools []*model.Pool
|
||||
for _, p := range fs.Spec.DataPools {
|
||||
dataPools = append(dataPools, p.ToModel(""))
|
||||
}
|
||||
f := mdsdaemon.NewFS(fs.Name, fs.Spec.MetadataPool.ToModel(""), dataPools, fs.Spec.MetadataServer.ActiveCount)
|
||||
if err := f.CreateFilesystem(context, fs.Namespace); err != nil {
|
||||
return fmt.Errorf("failed to create file system %s: %+v", fs.Name, err)
|
||||
if len(fs.Spec.DataPools) != 0 {
|
||||
var dataPools []*model.Pool
|
||||
for _, p := range fs.Spec.DataPools {
|
||||
dataPools = append(dataPools, p.ToModel(""))
|
||||
}
|
||||
f := mdsdaemon.NewFS(fs.Name, fs.Spec.MetadataPool.ToModel(""), dataPools, fs.Spec.MetadataServer.ActiveCount)
|
||||
if err := f.CreateFilesystem(context, fs.Namespace); err != nil {
|
||||
return fmt.Errorf("failed to create file system %s: %+v", fs.Name, err)
|
||||
}
|
||||
}
|
||||
|
||||
filesystem, err := client.GetFilesystem(context, fs.Namespace, fs.Name)
|
||||
@@ -55,6 +57,13 @@ func createFilesystem(
|
||||
return fmt.Errorf("failed to get file system %s: %+v", fs.Name, err)
|
||||
}
|
||||
|
||||
// set the number of active mds instances
|
||||
if fs.Spec.MetadataServer.ActiveCount > 1 {
|
||||
if err = client.SetNumMDSRanks(context, fs.Namespace, fs.Name, fs.Spec.MetadataServer.ActiveCount); err != nil {
|
||||
logger.Warningf("failed setting active mds count to %d. %+v", fs.Spec.MetadataServer.ActiveCount, err)
|
||||
}
|
||||
}
|
||||
|
||||
logger.Infof("start running mdses for file system %s", fs.Name)
|
||||
c := newCluster(context, rookVersion, cephVersion, hostNetwork, fs, filesystem, ownerRefs)
|
||||
if err := c.start(); err != nil {
|
||||
@@ -67,9 +76,16 @@ func createFilesystem(
|
||||
// deleteFileSystem deletes the file system and the metadata servers
|
||||
func deleteFilesystem(context *clusterd.Context, fs cephv1beta1.Filesystem) error {
|
||||
// The most important part of deletion is that the filesystem gets removed from Ceph
|
||||
if err := mdsdaemon.DeleteFilesystem(context, fs.Namespace, fs.Name); err != nil {
|
||||
if err := mdsdaemon.DownFilesystem(context, fs.Namespace, fs.Name); err != nil {
|
||||
// If the fs isn't deleted from Ceph, leave the daemons so it can still be used.
|
||||
return fmt.Errorf("failed to delete filesystem %s: %+v", fs.Name, err)
|
||||
return fmt.Errorf("failed to down filesystem %s: %+v", fs.Name, err)
|
||||
}
|
||||
|
||||
// Permanently remove the file system if it was created by rook
|
||||
if len(fs.Spec.DataPools) != 0 {
|
||||
if err := client.RemoveFilesystem(context, fs.Namespace, fs.Name); err != nil {
|
||||
return fmt.Errorf("failed to remove filesystem %s: %+v", fs.Name, err)
|
||||
}
|
||||
}
|
||||
|
||||
return deleteMdsCluster(context, fs.Namespace, fs.Name)
|
||||
@@ -82,8 +98,12 @@ func validateFilesystem(context *clusterd.Context, f cephv1beta1.Filesystem) err
|
||||
if f.Namespace == "" {
|
||||
return fmt.Errorf("missing namespace")
|
||||
}
|
||||
if f.Spec.MetadataServer.ActiveCount < 1 {
|
||||
return fmt.Errorf("MetadataServer.ActiveCount must be at least 1")
|
||||
}
|
||||
// No data pool means that we expect the fs to exist already
|
||||
if len(f.Spec.DataPools) == 0 {
|
||||
return fmt.Errorf("at least one data pool required")
|
||||
return nil
|
||||
}
|
||||
if err := pool.ValidatePoolSpec(context, f.Namespace, &f.Spec.MetadataPool); err != nil {
|
||||
return fmt.Errorf("invalid metadata pool: %+v", err)
|
||||
@@ -93,9 +113,6 @@ func validateFilesystem(context *clusterd.Context, f cephv1beta1.Filesystem) err
|
||||
return fmt.Errorf("Invalid data pool: %+v", err)
|
||||
}
|
||||
}
|
||||
if f.Spec.MetadataServer.ActiveCount < 1 {
|
||||
return fmt.Errorf("MetadataServer.ActiveCount must be at least 1")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -143,6 +143,57 @@ func TestCreateFilesystem(t *testing.T) {
|
||||
assert.Equal(t, "failed to create file system myfs: Cannot create multiple filesystems. Enable ROOK_ALLOW_MULTIPLE_FILESYSTEMS env variable to create more than one", err.Error())
|
||||
}
|
||||
|
||||
func TestCreateNopoolFilesystem(t *testing.T) {
|
||||
configDir, _ := ioutil.TempDir("", "")
|
||||
// Output to check multiple file system creation
|
||||
fses := `[{"name":"myfs"}]`
|
||||
|
||||
executor := &exectest.MockExecutor{
|
||||
MockExecuteCommandWithOutputFile: func(debug bool, actionName string, command string, outFileArg string, args ...string) (string, error) {
|
||||
return "{\"key\":\"mysecurekey\"}", nil
|
||||
},
|
||||
MockExecuteCommandWithOutput: func(debug bool, actionName string, command string, args ...string) (string, error) {
|
||||
if strings.Contains(command, "ceph-authtool") {
|
||||
cephtest.CreateConfigDir(path.Join(configDir, "ns"))
|
||||
}
|
||||
|
||||
return "", nil
|
||||
},
|
||||
}
|
||||
defer os.RemoveAll(configDir)
|
||||
context := &clusterd.Context{
|
||||
Executor: executor,
|
||||
ConfigDir: configDir,
|
||||
Clientset: testop.New(3)}
|
||||
fs := cephv1beta1.Filesystem{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "myfs", Namespace: "ns"},
|
||||
Spec: cephv1beta1.FilesystemSpec{
|
||||
MetadataServer: cephv1beta1.MetadataServerSpec{
|
||||
ActiveCount: 1,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
// start a basic cluster
|
||||
err := createFilesystem(context, fs, "v0.1", cephv1beta1.CephVersionSpec{}, false, []metav1.OwnerReference{})
|
||||
assert.Nil(t, err)
|
||||
validateStart(t, context, fs)
|
||||
|
||||
// starting again should be a no-op
|
||||
err = createFilesystem(context, fs, "v0.1", cephv1beta1.CephVersionSpec{}, false, []metav1.OwnerReference{})
|
||||
assert.Nil(t, err)
|
||||
validateStart(t, context, fs)
|
||||
|
||||
// Test multiple filesystem creation
|
||||
executor = &exectest.MockExecutor{
|
||||
MockExecuteCommandWithOutputFile: func(debug bool, actionName string, command string, outFileArg string, args ...string) (string, error) {
|
||||
if contains(args, "ls") {
|
||||
return fses, nil
|
||||
}
|
||||
return "{\"key\":\"mysecurekey\"}", errors.New("multiple fs")
|
||||
},
|
||||
}
|
||||
}
|
||||
func contains(arr []string, str string) bool {
|
||||
for _, a := range arr {
|
||||
if a == str {
|
||||
|
||||
Reference in New Issue
Block a user