cloudstack-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mtutkow...@apache.org
Subject git commit: updated refs/heads/master to 09a62b8
Date Thu, 30 Oct 2014 22:09:03 GMT
Repository: cloudstack
Updated Branches:
  refs/heads/master 771698934 -> 09a62b838


new managed nfs storage adapter

Signed-off-by: Mike Tutkowski <mike.tutkowski@solidfire.com>


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/09a62b83
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/09a62b83
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/09a62b83

Branch: refs/heads/master
Commit: 09a62b8389c8bf67f4bdd5e938d8b95e99d78e99
Parents: 7716989
Author: punith-cloudbyte <punith.s@cloudbyte.com>
Authored: Thu Oct 30 15:28:47 2014 -0600
Committer: Mike Tutkowski <mike.tutkowski@solidfire.com>
Committed: Thu Oct 30 16:07:59 2014 -0600

----------------------------------------------------------------------
 api/src/com/cloud/agent/api/to/DiskTO.java      |   1 +
 api/src/com/cloud/storage/Storage.java          |   3 +-
 .../kvm/storage/KVMStoragePoolManager.java      |   1 +
 .../kvm/storage/LibvirtStoragePool.java         |   5 +
 .../kvm/storage/ManagedNfsStorageAdaptor.java   | 330 +++++++++++++++++++
 5 files changed, 339 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/09a62b83/api/src/com/cloud/agent/api/to/DiskTO.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/agent/api/to/DiskTO.java b/api/src/com/cloud/agent/api/to/DiskTO.java
index 9e4dfd9..f982844 100644
--- a/api/src/com/cloud/agent/api/to/DiskTO.java
+++ b/api/src/com/cloud/agent/api/to/DiskTO.java
@@ -35,6 +35,7 @@ public class DiskTO {
     public static final String MOUNT_POINT = "mountpoint";
     public static final String PROTOCOL_TYPE = "protocoltype";
     public static final String PATH = "path";
+    public static final String UUID = "uuid";
 
     private DataTO data;
     private Long diskSeq;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/09a62b83/api/src/com/cloud/storage/Storage.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/storage/Storage.java b/api/src/com/cloud/storage/Storage.java
index 4d267eb..25ae5ca 100755
--- a/api/src/com/cloud/storage/Storage.java
+++ b/api/src/com/cloud/storage/Storage.java
@@ -131,7 +131,8 @@ public class Storage {
         EXT(false), // XenServer local EXT SR
         OCFS2(true),
         SMB(true),
-        Gluster(true);
+        Gluster(true),
+        ManagedNFS(true);
 
         boolean shared;
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/09a62b83/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStoragePoolManager.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStoragePoolManager.java
b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStoragePoolManager.java
index 583db0f..eaf3ba6 100644
--- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStoragePoolManager.java
+++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStoragePoolManager.java
@@ -96,6 +96,7 @@ public class KVMStoragePoolManager {
         // add other storage adaptors here
         // this._storageMapper.put("newadaptor", new NewStorageAdaptor(storagelayer));
         this._storageMapper.put(StoragePoolType.Iscsi.toString(), new IscsiAdmStorageAdaptor());
+        this._storageMapper.put(StoragePoolType.ManagedNFS.toString(), new ManagedNfsStorageAdaptor(storagelayer));
     }
 
     public boolean connectPhysicalDisk(StoragePoolType type, String poolUuid, String volPath,
Map<String, String> details) {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/09a62b83/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/LibvirtStoragePool.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/LibvirtStoragePool.java
b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/LibvirtStoragePool.java
index 1a756cb..49a8301 100644
--- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/LibvirtStoragePool.java
+++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/LibvirtStoragePool.java
@@ -256,6 +256,11 @@ public class LibvirtStoragePool implements KVMStoragePool {
         return this._pool;
     }
 
+    public void setPool(StoragePool pool) {
+        this._pool = pool;
+    }
+
+
     @Override
     public boolean delete() {
         try {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/09a62b83/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/ManagedNfsStorageAdaptor.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/ManagedNfsStorageAdaptor.java
b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/ManagedNfsStorageAdaptor.java
new file mode 100644
index 0000000..af2e6f6
--- /dev/null
+++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/ManagedNfsStorageAdaptor.java
@@ -0,0 +1,330 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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 com.cloud.hypervisor.kvm.storage;
+
+import java.io.File;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.cloudstack.utils.qemu.QemuImg.PhysicalDiskFormat;
+import org.apache.log4j.Logger;
+import org.libvirt.Connect;
+import org.libvirt.LibvirtException;
+import org.libvirt.StoragePool;
+import org.libvirt.StoragePoolInfo;
+import org.libvirt.StorageVol;
+
+import com.cloud.agent.api.to.DiskTO;
+import com.cloud.hypervisor.kvm.resource.LibvirtConnection;
+import com.cloud.hypervisor.kvm.resource.LibvirtStoragePoolDef;
+import com.cloud.hypervisor.kvm.resource.LibvirtStoragePoolDef.poolType;
+import com.cloud.hypervisor.kvm.resource.LibvirtStorageVolumeDef;
+import com.cloud.hypervisor.kvm.resource.LibvirtStorageVolumeXMLParser;
+import com.cloud.storage.Storage.ImageFormat;
+import com.cloud.storage.Storage.ProvisioningType;
+import com.cloud.storage.Storage.StoragePoolType;
+import com.cloud.storage.StorageLayer;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.script.Script;
+
+public class ManagedNfsStorageAdaptor implements StorageAdaptor {
+    private static final Logger s_logger = Logger.getLogger(ManagedNfsStorageAdaptor.class);
+    private String _mountPoint = "/mnt";
+    private StorageLayer _storageLayer;
+
+    private static final Map<String, KVMStoragePool> MapStorageUuidToStoragePool =
new HashMap<String, KVMStoragePool>();
+
+    public ManagedNfsStorageAdaptor(StorageLayer storagelayer) {
+        _storageLayer = storagelayer;
+    }
+
+    @Override
+    public KVMStoragePool createStoragePool(String uuid, String host, int port, String path,
String userInfo, StoragePoolType storagePoolType) {
+
+        LibvirtStoragePool storagePool = new LibvirtStoragePool(uuid, path, StoragePoolType.ManagedNFS,
this, null);
+        storagePool.setSourceHost(host);
+        storagePool.setSourcePort(port);
+        MapStorageUuidToStoragePool.put(uuid, storagePool);
+
+        return storagePool;
+    }
+
+    @Override
+    public KVMStoragePool getStoragePool(String uuid) {
+        return getStoragePool(uuid, false);
+    }
+
+    @Override
+    public KVMStoragePool getStoragePool(String uuid, boolean refreshInfo) {
+        return MapStorageUuidToStoragePool.get(uuid);
+    }
+
+    @Override
+    public boolean deleteStoragePool(String uuid) {
+        return MapStorageUuidToStoragePool.remove(uuid) != null;
+    }
+
+    @Override
+    public boolean deleteStoragePool(KVMStoragePool pool) {
+        return deleteStoragePool(pool.getUuid());
+    }
+
+    public KVMPhysicalDisk createPhysicalDisk(String volumeUuid, KVMStoragePool pool, PhysicalDiskFormat
format, long size) {
+        throw new UnsupportedOperationException("Creating a physical disk is not supported.");
+    }
+
+    /*
+     * creates a nfs storage pool using libvirt
+     */
+    @Override
+    public boolean connectPhysicalDisk(String volumeUuid, KVMStoragePool pool, Map<String,
String> details) {
+
+        StoragePool sp = null;
+        Connect conn = null;
+        String targetPath = null;
+        LibvirtStoragePoolDef spd = null;
+        try {
+            conn = LibvirtConnection.getConnection();
+
+            targetPath = "/mnt" + volumeUuid;
+            spd = new LibvirtStoragePoolDef(poolType.NETFS, volumeUuid, details.get(DiskTO.UUID),
pool.getSourceHost(), details.get(DiskTO.MOUNT_POINT), targetPath);
+            _storageLayer.mkdir(targetPath);
+
+            s_logger.debug(spd.toString());
+            sp = conn.storagePoolCreateXML(spd.toString(), 0);
+
+            if (sp == null) {
+                throw new CloudRuntimeException("Failed to create storage pool:" + volumeUuid);
+            }
+
+            try {
+                if (sp.isActive() == 0) {
+                    // s_logger.debug("attempting to activate pool " + name);
+                    sp.create(0);
+                }
+                // now add the storage pool
+                LibvirtStoragePool storagePool = (LibvirtStoragePool) getStoragePool(pool.getUuid());
+                storagePool.setPool(sp);
+
+                return true;
+            } catch (LibvirtException e) {
+                String error = e.toString();
+                if (error.contains("Storage source conflict")) {
+                    throw new CloudRuntimeException("A pool matching this location already
exists in libvirt, " + " but has a different UUID/Name. Cannot create new pool without first
"
+                            + " removing it. Check for inactive pools via 'virsh pool-list
--all'. " + error);
+                } else {
+                    throw new CloudRuntimeException(error);
+                }
+            }
+        } catch (LibvirtException e) {
+            s_logger.error(e.toString());
+            // if error is that pool is mounted, try to handle it
+            if (e.toString().contains("already mounted")) {
+                s_logger.error("Attempting to unmount old mount libvirt is unaware of at
" + targetPath);
+                String result = Script.runSimpleBashScript("umount -l " + targetPath);
+                if (result == null) {
+                    s_logger.error("Succeeded in unmounting " + targetPath);
+                    try {
+                        sp = conn.storagePoolCreateXML(spd.toString(), 0);
+                        s_logger.error("Succeeded in redefining storage");
+                        return true;
+                    } catch (LibvirtException l) {
+                        s_logger.error("Target was already mounted, unmounted it but failed
to redefine storage:" + l);
+                    }
+                } else {
+                    s_logger.error("Failed in unmounting and redefining storage");
+                }
+            } else {
+                s_logger.error("Internal error occurred when attempting to mount:" + e.getMessage());
+                // stacktrace for agent.log
+                e.printStackTrace();
+                throw new CloudRuntimeException(e.toString());
+            }
+            return false;
+        }
+
+    }
+
+    /*
+     * creates a disk based on the created nfs storage pool using libvirt
+     */
+    @Override
+    public KVMPhysicalDisk getPhysicalDisk(String volumeUuid, KVMStoragePool pool) {
+        // now create the volume upon the given storage pool in kvm
+        Connect conn;
+        StoragePool virtPool = null;
+        try {
+            conn = LibvirtConnection.getConnection();
+            virtPool = conn.storagePoolLookupByName("/" + volumeUuid);
+        } catch (LibvirtException e1) {
+            throw new CloudRuntimeException(e1.toString());
+        }
+
+        LibvirtStorageVolumeDef.volFormat libvirtformat = null;
+        String volPath = null;
+        String volName = null;
+        long volAllocation = 0;
+        long volCapacity = 0;
+        // check whether the volume is present on the given pool
+        StorageVol vol = getVolume(virtPool, volumeUuid);
+        try {
+            if (vol == null) {
+
+                libvirtformat = LibvirtStorageVolumeDef.volFormat.QCOW2;
+
+                StoragePoolInfo poolinfo = virtPool.getInfo();
+                volCapacity = poolinfo.available;
+
+                LibvirtStorageVolumeDef volDef = new LibvirtStorageVolumeDef(volumeUuid,
volCapacity, libvirtformat, null, null);
+                s_logger.debug(volDef.toString());
+
+                vol = virtPool.storageVolCreateXML(volDef.toString(), 0);
+                volPath = vol.getPath();
+                volName = vol.getName();
+                volAllocation = vol.getInfo().allocation;
+                volCapacity = vol.getInfo().capacity;
+
+            }
+
+            KVMPhysicalDisk disk = new KVMPhysicalDisk(vol.getPath(), volumeUuid, pool);
+            disk.setFormat(PhysicalDiskFormat.QCOW2);
+            disk.setSize(vol.getInfo().allocation);
+            disk.setVirtualSize(vol.getInfo().capacity);
+            return disk;
+
+        } catch (LibvirtException e) {
+            throw new CloudRuntimeException(e.toString());
+        }
+
+    }
+
+    public LibvirtStorageVolumeDef getStorageVolumeDef(Connect conn, StorageVol vol) throws
LibvirtException {
+        String volDefXML = vol.getXMLDesc(0);
+        LibvirtStorageVolumeXMLParser parser = new LibvirtStorageVolumeXMLParser();
+        return parser.parseStorageVolumeXML(volDefXML);
+    }
+
+    public StorageVol getVolume(StoragePool pool, String volName) {
+        StorageVol vol = null;
+
+        try {
+            vol = pool.storageVolLookupByName(volName);
+        } catch (LibvirtException e) {
+            s_logger.debug("Can't find volume: " + e.toString());
+        }
+        if (vol == null) {
+            try {
+                refreshPool(pool);
+            } catch (LibvirtException e) {
+                s_logger.debug("failed to refresh pool: " + e.toString());
+            }
+            s_logger.debug("no volume is present on the pool, creating a new one");
+        }
+        return vol;
+    }
+
+    private void refreshPool(StoragePool pool) throws LibvirtException {
+        pool.refresh(0);
+        return;
+    }
+
+    /*
+     * disconnect the disk by destroying the sp pointer
+     */
+    public boolean disconnectPhysicalDisk(KVMStoragePool pool, String mountpoint) throws
LibvirtException {
+
+        LibvirtStoragePool libvirtPool = (LibvirtStoragePool) pool;
+        StoragePool sp = libvirtPool.getPool();
+        // destroy the pool
+        sp.destroy();
+
+        return true;
+    }
+
+    @Override
+    public boolean disconnectPhysicalDisk(String volumeUuid, KVMStoragePool pool) {
+        try {
+            return disconnectPhysicalDisk(pool, volumeUuid);
+        } catch (LibvirtException e) {
+            throw new CloudRuntimeException(e.getMessage());
+        }
+    }
+
+    @Override
+    public boolean disconnectPhysicalDiskByPath(String localPath) {
+        return false;
+    }
+
+    public boolean deletePhysicalDisk(String volumeUuid, KVMStoragePool pool) {
+        throw new UnsupportedOperationException("Deleting a physical disk is not supported.");
+    }
+
+    @Override
+    public List<KVMPhysicalDisk> listPhysicalDisks(String storagePoolUuid, KVMStoragePool
pool) {
+        throw new UnsupportedOperationException("Listing disks is not supported for this
configuration.");
+    }
+
+    public KVMPhysicalDisk createDiskFromTemplate(KVMPhysicalDisk template, String name,
PhysicalDiskFormat format, long size, KVMStoragePool destPool, int timeout) {
+        throw new UnsupportedOperationException("Creating a disk from a template is not yet
supported for this configuration.");
+    }
+
+    @Override
+    public KVMPhysicalDisk createTemplateFromDisk(KVMPhysicalDisk disk, String name, PhysicalDiskFormat
format, long size, KVMStoragePool destPool) {
+        throw new UnsupportedOperationException("Creating a template from a disk is not yet
supported for this configuration.");
+    }
+
+    @Override
+    public KVMPhysicalDisk copyPhysicalDisk(KVMPhysicalDisk disk, String name, KVMStoragePool
destPool, int timeout) {
+        throw new UnsupportedOperationException("Copying a disk is not supported in this
configuration.");
+    }
+
+    @Override
+    public KVMPhysicalDisk createDiskFromSnapshot(KVMPhysicalDisk snapshot, String snapshotName,
String name, KVMStoragePool destPool) {
+        throw new UnsupportedOperationException("Creating a disk from a snapshot is not supported
in this configuration.");
+    }
+
+    @Override
+    public boolean refresh(KVMStoragePool pool) {
+        return true;
+    }
+
+    @Override
+    public boolean createFolder(String uuid, String path) {
+        String mountPoint = _mountPoint + File.separator + uuid;
+        File f = new File(mountPoint + File.separator + path);
+        if (!f.exists()) {
+            f.mkdirs();
+        }
+        return true;
+    }
+
+    @Override
+    public KVMPhysicalDisk createPhysicalDisk(String name, KVMStoragePool pool, PhysicalDiskFormat
format, ProvisioningType provisioningType, long size) {
+        return null;
+    }
+
+    @Override
+    public boolean deletePhysicalDisk(String uuid, KVMStoragePool pool, ImageFormat format)
{
+        return false;
+    }
+
+    @Override
+    public KVMPhysicalDisk createDiskFromTemplate(KVMPhysicalDisk template, String name,
PhysicalDiskFormat format, ProvisioningType provisioningType, long size, KVMStoragePool destPool,
int timeout) {
+        return null;
+    }
+}


Mime
View raw message