From cff5baae4758b73e808a920d52ca0789b8b546e5 Mon Sep 17 00:00:00 2001 From: Kris Moore Date: Thu, 21 Apr 2016 11:28:37 -0400 Subject: [PATCH] Add new API call to return list of ZFS datasets on a particular pool REST Request: ------------------------------- PUT /sysadm/zfs { "action" : "datasets", "zpool" : "tank" } WebSocket Request: ------------------------------- { "namespace" : "sysadm", "id" : "fooid", "args" : { "action" : "datasets", "zpool" : "tank" }, "name" : "zfs" } Response: ------------------------------- { "args": { "datasets": { "tank": { "avail": "320G", "mountpoint": "none", "refer": "96K", "used": "125G" }, "tank/ROOT": { "avail": "320G", "mountpoint": "none", "refer": "96K", "used": "63.7G" }, "tank/ROOT/11.0-CURRENTAPRIL2016-up-20160418_124146": { "avail": "320G", "mountpoint": "/", "refer": "34.7G", "used": "63.7G" }, "tank/ROOT/11.0-CURRENTFEB2016-up-20160303_094216": { "avail": "320G", "mountpoint": "/", "refer": "29.7G", "used": "272K" }, "tank/ROOT/11.0-CURRENTMAR2016-up-20160304_102405": { "avail": "320G", "mountpoint": "/", "refer": "30.5G", "used": "248K" }, "tank/ROOT/11.0-CURRENTMAR2016-up-20160315_092952": { "avail": "320G", "mountpoint": "/", "refer": "31.2G", "used": "256K" }, "tank/ROOT/11.0-CURRENTMAR2016-up-20160318_090405": { "avail": "320G", "mountpoint": "/", "refer": "34.7G", "used": "280K" }, "tank/ROOT/initial": { "avail": "320G", "mountpoint": "/mnt", "refer": "5.60G", "used": "232K" }, "tank/iocage": { "avail": "320G", "mountpoint": "/iocage", "refer": "152K", "used": "1.13G" }, "tank/iocage/.defaults": { "avail": "320G", "mountpoint": "/iocage/.defaults", "refer": "96K", "used": "992K" }, "tank/iocage/download": { "avail": "320G", "mountpoint": "/iocage/download", "refer": "96K", "used": "203M" }, "tank/iocage/download/10.2-RELEASE": { "avail": "320G", "mountpoint": "/iocage/download/10.2-RELEASE", "refer": "202M", "used": "202M" }, "tank/iocage/jails": { "avail": "320G", "mountpoint": "/iocage/jails", "refer": "104K", "used": "1000K" }, "tank/iocage/releases": { "avail": "320G", "mountpoint": "/iocage/releases", "refer": "96K", "used": "953M" }, "tank/iocage/releases/10.2-RELEASE": { "avail": "320G", "mountpoint": "/iocage/releases/10.2-RELEASE", "refer": "96K", "used": "952M" }, "tank/iocage/releases/10.2-RELEASE/root": { "avail": "320G", "mountpoint": "/iocage/releases/10.2-RELEASE/root", "refer": "825M", "used": "951M" }, "tank/iocage/templates": { "avail": "320G", "mountpoint": "/iocage/templates", "refer": "96K", "used": "992K" }, "tank/iohyve": { "avail": "320G", "mountpoint": "/iohyve", "refer": "96K", "used": "22.8G" }, "tank/iohyve/Firmware": { "avail": "320G", "mountpoint": "/iohyve/Firmware", "refer": "96K", "used": "992K" }, "tank/iohyve/ISO": { "avail": "320G", "mountpoint": "/iohyve/ISO", "refer": "96K", "used": "453M" }, "tank/iohyve/ISO/FreeBSD-10.1-RELEASE-amd64-bootonly.iso": { "avail": "320G", "mountpoint": "/iohyve/ISO/FreeBSD-10.1-RELEASE-amd64-bootonly.iso", "refer": "219M", "used": "220M" }, "tank/iohyve/ISO/FreeBSD-10.2-RELEASE-amd64-bootonly.iso": { "avail": "320G", "mountpoint": "/iohyve/ISO/FreeBSD-10.2-RELEASE-amd64-bootonly.iso", "refer": "231M", "used": "232M" }, "tank/iohyve/bsdguest": { "avail": "320G", "mountpoint": "/iohyve/bsdguest", "refer": "96K", "used": "22.4G" }, "tank/iohyve/bsdguest/disk0": { "avail": "341G", "mountpoint": "-", "refer": "1.75G", "used": "22.4G" }, "tank/tmp": { "avail": "320G", "mountpoint": "/tmp", "refer": "2.95M", "used": "18.3M" }, "tank/usr": { "avail": "320G", "mountpoint": "none", "refer": "96K", "used": "37.5G" }, "tank/usr/home": { "avail": "320G", "mountpoint": "/usr/home", "refer": "96K", "used": "27.8G" }, "tank/usr/home/kris": { "avail": "320G", "mountpoint": "/usr/home/kris", "refer": "21.9G", "used": "27.8G" }, "tank/usr/jails": { "avail": "320G", "mountpoint": "/usr/jails", "refer": "96K", "used": "992K" }, "tank/usr/obj": { "avail": "320G", "mountpoint": "/usr/obj", "refer": "4.68G", "used": "4.75G" }, "tank/usr/ports": { "avail": "320G", "mountpoint": "/usr/ports", "refer": "2.20G", "used": "2.96G" }, "tank/usr/src": { "avail": "320G", "mountpoint": "/usr/src", "refer": "1.82G", "used": "2.01G" }, "tank/var": { "avail": "320G", "mountpoint": "none", "refer": "96K", "used": "13.5M" }, "tank/var/audit": { "avail": "320G", "mountpoint": "/var/audit", "refer": "96K", "used": "992K" }, "tank/var/log": { "avail": "320G", "mountpoint": "/var/log", "refer": "1.43M", "used": "5.21M" }, "tank/var/mail": { "avail": "320G", "mountpoint": "/var/mail", "refer": "120K", "used": "1.21M" }, "tank/var/tmp": { "avail": "320G", "mountpoint": "/var/tmp", "refer": "3.20M", "used": "5.99M" } } }, "id": "fooid", "name": "response", "namespace": "sysadm" } --- src/server/WebBackend.cpp | 27 ++++++++++++------ src/server/library/sysadm-zfs.cpp | 46 ++++++++++++++++++++++++++++++- src/server/library/sysadm-zfs.h | 3 +- 3 files changed, 66 insertions(+), 10 deletions(-) diff --git a/src/server/WebBackend.cpp b/src/server/WebBackend.cpp index dbae3e9..a07dc0c 100644 --- a/src/server/WebBackend.cpp +++ b/src/server/WebBackend.cpp @@ -682,16 +682,27 @@ RestOutputStruct::ExitCode WebSocket::EvaluateSysadmIohyveRequest(const QJsonVal // ==== SYSADM ZFS API ==== RestOutputStruct::ExitCode WebSocket::EvaluateSysadmZfsRequest(const QJsonValue in_args, QJsonObject *out){ - if(!in_args.isObject() || !in_args.toObject().contains("action") ){ return RestOutputStruct::BADREQUEST; } - QString act = in_args.toObject().value("action").toString(); - if(act=="list_pools"){ - QJsonObject pools = sysadm::ZFS::zpool_list(); - if(!pools.isEmpty()){ out->insert("list_pools",pools); } - }else{ - //unknown action + if( ! in_args.isObject()){ + return RestOutputStruct::BADREQUEST; + } + QStringList keys = in_args.toObject().keys(); + bool ok = false; + if(keys.contains("action")) { + QString act = JsonValueToString(in_args.toObject().value("action")); + if(act=="list_pools"){ + QJsonObject pools = sysadm::ZFS::zpool_list(); + if(!pools.isEmpty()){ out->insert("list_pools",pools); } + } + else if(act=="datasets"){ + ok = true; + out->insert("datasets", sysadm::ZFS::zfs_list(in_args.toObject())); + } + } //end of "action" key usage + + //If nothing done - return the proper code + if(!ok){ return RestOutputStruct::BADREQUEST; } - return RestOutputStruct::OK; } diff --git a/src/server/library/sysadm-zfs.cpp b/src/server/library/sysadm-zfs.cpp index 5209040..72154e2 100644 --- a/src/server/library/sysadm-zfs.cpp +++ b/src/server/library/sysadm-zfs.cpp @@ -9,6 +9,50 @@ using namespace sysadm; +QJsonObject ZFS::zfs_list(QJsonObject jsin) { + QJsonObject retObject; + QString zpool; + + QStringList keys = jsin.keys(); + if(! keys.contains("zpool")){ + retObject.insert("error", "Requires zpool keys"); + return retObject; + } + + zpool = jsin.value("zpool").toString(); + + if ( zpool.isEmpty() ) { + retObject.insert("error", "Empty zpool name"); + return retObject; + } + + QString tmp; + QStringList output; + output = General::RunCommand("zfs", QStringList() << "list" << "-H" << "-r" << zpool).split("\n"); + + // Now parse the output + for ( int i = 0; i < output.size(); i++) + { + if ( output.at(i).indexOf("cannot open") != -1 ) { + retObject.insert("error", output.at(i)); + return retObject; + } + + // Now assemble your JSON + QJsonObject dsetvals; + tmp = output.at(i).simplified().section(" ", 0, 0).simplified(); + if ( tmp.isEmpty() ) + continue; + dsetvals.insert("used", output.at(i).simplified().section(" ", 1, 1) ); + dsetvals.insert("avail", output.at(i).simplified().section(" ", 2, 2) ); + dsetvals.insert("refer", output.at(i).simplified().section(" ", 3, 3) ); + dsetvals.insert("mountpoint", output.at(i).simplified().section(" ", 4, 4) ); + retObject.insert(tmp, dsetvals); + } + + return retObject; +} + QJsonObject ZFS::zpool_list(){ QJsonObject zpools; bool ok = false; @@ -44,4 +88,4 @@ QJsonObject ZFS::zpool_list(){ zpools.insert(pool, zstats); } //end loop over zpool list lines return zpools; -} \ No newline at end of file +} diff --git a/src/server/library/sysadm-zfs.h b/src/server/library/sysadm-zfs.h index 4047fd0..cd54f33 100644 --- a/src/server/library/sysadm-zfs.h +++ b/src/server/library/sysadm-zfs.h @@ -14,10 +14,11 @@ namespace sysadm{ class ZFS{ public: + static QJsonObject zfs_list(QJsonObject jsin); static QJsonObject zpool_list(); }; }//end of sysadm namespace -#endif \ No newline at end of file +#endif