diff --git a/zfs/zfs2.js b/zfs/zfs2.js deleted file mode 100644 index 073dc90..0000000 --- a/zfs/zfs2.js +++ /dev/null @@ -1,20888 +0,0 @@ -/* - * This file is part of Cockpit ZFS Manager. - * - * Copyright (C) 2019-2020 OPTIMANS Pty Ltd. - * - * Cockpit ZFS Manager is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your option) - * any later version. - * - * Cockpit ZFS Manager is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for - * more details. - * - * You should have received a copy of the GNU Lesser General Public License along - * with Cockpit ZFS Manager; If not, see . - */ - - -//#region Configuration - Edit With Configure ZFS Manager Modal - -let zfsmanager = { - cockpit: { - datelocale: (navigator.languages && navigator.languages.length ? navigator.languages[0] : (navigator.userLanguage || navigator.language || navigator.browserLanguage || cockpit.language)), - legacy: false, - permission: null, - zfspermission: null, - smbpermission: null - }, - configuration: { - cockpit: { - manage: false //Remove packages that cause problems for ZFS - }, - disks: { - base2: false //Use Base-2 calculation for disk sizes - }, - loglevel: 2, //Console logging. 1=Minimal Logging, 2=Enhanced Logging, 3=Enhanced Logging and Process Commands, 4=Verbose - samba: { - manage: false, //Manage Samba shares - windowscompatibility: true //Disable special characters in share name that don't work with Microsoft Windows - }, - updates: { - check: true //Check for updates on launch - }, - zfs: { - filesystem: { - cloneorigin: false, //Display clone origin in tooltip - quotarestrict: true, //Restrict quota maximum to size of storage pool - readonlylockdown: false, //Prevent changes to read only file systems and clone file systems - snapshotactions: true, //Display snapshot actions in file system actions menu - }, - status: { - errorcolors: true, //Display warning and danger colors for error counts - trimunsupported: false //Display TRIM unsupported message - }, - storagepool: { - activetab: 1, //Default active tab for storage pool. 1=File Systems, 2=Snapshots, 3=Status - boot: true, //Display boot storage pool - bootlockdown: true, //Prevent changes to boot storage pool. Changes may cause an unbootable system - root: true, //Display root storage pool - refreshall: false //Refresh all components - } - } - }, - system: { - operatingsystem: "" - }, - user: { - admin: true, - zfs: false, - smb: false, - configuration: false, - name: "" - }, - version: "0.2.0.233", - zfs: { - storagepool: { - boot: "", - root: "", - refreshid: [] - }, - warnings: { - nvmevdev: false - }, - version: null - } -}; - -//#endregion - -//#region Document Ready - -$(document).ready(function () { - FnConsoleInitialize(); - - FnConsole.log[1]("Cockpit ZFS Manager, Version: " + zfsmanager.version); - - FnConfigurationGet() - .always(function () { - Requirements({ zfs: false }); - }); - - $("body").tooltip({ - html: "true", - selector: `[data-toggle="tooltip"]` - }); - - $(cockpit.info).on("changed", function () { - zfsmanager.cockpit.legacy = (cockpit.info["version"] < 207 ? true : false); - }); -}); - -//#endregion - -//#region Requirements - -function Requirements(skip = { zfs: false }) { - if (!skip.zfs) { - FnZfsVersionGet() - .done(function () { - if ($("#alerts-requirements").hasClass("hidden")) { - if (zfsmanager.configuration.samba.manage) { - FnSambaVersionGet() - .done(function () { - FnFirstSteps(); - }); - } else { - FnFirstSteps(); - } - } - }); - } else { - if (zfsmanager.configuration.samba.manage) { - FnSambaVersionGet() - .done(function () { - FnFirstSteps(); - }); - } else { - FnFirstSteps(); - } - } -} - -//#endregion - -//#region First Steps - -function FnFirstSteps() { - FnSystemOperatingSystemGet(); - FnCockpitPermissionsGet(); - - FnModalsRegister(); - FnStoragePoolsGet(); - - FnVersionWarning(); - FnZfsVersionWarnings() -} - -function FnFirstStepsPrivileged() { - //Execute functions when user is an administrator - - FnConfigurationDirectoryCreate(); - FnConfigurationDirectoryRuntimeCreate(); - - if (!zfsmanager.user.configuration) { - FnConfigurationLegacyGet(); - } else { - if (zfsmanager.configuration.cockpit.manage) { - FnCockpitManage(); - } - if (zfsmanager.configuration.samba.manage) { - FnSambaManage(); - } - FnSambaUsersharesDirectoryCreate(); - if (zfsmanager.configuration.updates.check) { - FnUpdatesCheck({ alert: true }); - } - } -} - -//#endregion - -//#region Fixed Content Click Actions - -$(document).on("click", "#btn-alerts-requirements-samba-refresh", function () { - Requirements({ zfs: true }); -}); - -$(document).on("click", "#btn-alerts-requirements-zfs-refresh", function () { - Requirements({ zfs: false }); -}); - -$(document).on("click", "#btn-storagepools-refresh", function () { - FnStoragePoolsGet(); -}); - -$(document).on("click", "#table-storagepools tr.listing-ct-item", function (element) { - if (!$(this).hasClass("listing-ct-storagepoolsnotfound") && !$(element.target).is("a, button, .fa.fa-ellipsis-v, input")) { - if (!$(this).parent().hasClass("open")) { - $(this).parent().addClass("open"); - - $(this).attr("data-pool-refresh-filesystems", "false"); - $(this).attr("data-pool-refresh-snapshots", "false"); - $(this).attr("data-pool-refresh-status", "false"); - - FnStoragePoolRefresh({ name: $(this).attr("data-pool-name"), id: $(this).attr("data-pool-id") }, { storagepool: true, filesystems: true, snapshots: true, status: true }); - } else { - if (!$("#spinner-storagepool-" + $(this).attr("data-pool-id")).hasClass("hidden")) { - //Disable click action while information is still loading - } else { - $(this).parent().removeClass("open"); - - $(this).attr("data-pool-refresh-filesystems", "false"); - $(this).attr("data-pool-refresh-snapshots", "false"); - $(this).attr("data-pool-refresh-status", "false"); - - $("#spinner-storagepool-" + $(this).attr("data-pool-id")).removeClass("hidden"); - $("#listingcthead-storagepool-" + $(this).attr("data-pool-id")).addClass("hidden"); - $("#listingctbody-storagepool-" + $(this).attr("data-pool-id")).addClass("hidden"); - - FnStoragePoolRefreshAutoDisable({ name: $(this).attr("data-pool-name"), id: $(this).attr("data-pool-id") }); - } - } - } -}); - -//#endregion - -//#region Helper Functions - -String.prototype.format = function () { - let args = arguments; - - return this.replace(/\{(\d+)\}/g, function (m, n) { - return args[n]; - }); -} - -function FnAppendLeadingZeroes(data = { value }) { - if (data.value < 10) { - return "0" + data.value; - } - - return data.value; -} - -function FnFormatBytes(data = { base2: true, decimals: 0, value }) { - if (data.value == 0) { - return "0 B"; - } - - data.bytes = (data.base2 ? 1024 : 1000); - data.sizes = (data.base2 ? ["B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB"] : ["B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB"]); - data.integer = Math.floor(Math.log(data.value) / Math.log(data.bytes)); - data.decimals = (data.decimals <= 0 ? 0 : data.decimals); - - data.sizefriendly = parseFloat((data.value / Math.pow(data.bytes, data.integer)).toFixed(data.decimals)).toString() + " " + data.sizes[data.integer]; - - if (data.sizefriendly == "NaN undefined") { - data.sizefriendly = "-"; - } - - return data.sizefriendly; -} - -function FnGenerateId(character = { at: false, colon: false, forwardslash: false, period: false, underscore: false, whitespace: false }, data = { name, attribute: true }) { - let replacement = { - character: (data.attribute ? "\u22C5" : "_"), - regexp: [] - }; - - if (character.underscore) { - replacement.regexp.push({ pattern: /[_]/g, replacement: (data.attribute ? replacement.character + "u" + replacement.character : replacement.character) }) - } - if (character.at) { - replacement.regexp.push({ pattern: /[@]/g, replacement: (data.attribute ? replacement.character + "a" + replacement.character : replacement.character) }) - } - if (character.colon) { - replacement.regexp.push({ pattern: /[:]/g, replacement: (data.attribute ? replacement.character + "c" + replacement.character : replacement.character) }) - } - if (character.forwardslash) { - replacement.regexp.push({ pattern: /[/]/g, replacement: (data.attribute ? replacement.character + "f" + replacement.character : replacement.character) }) - } - if (character.period) { - replacement.regexp.push({ pattern: /[.]/g, replacement: (data.attribute ? replacement.character + "p" + replacement.character : replacement.character) }) - } - if (character.whitespace) { - replacement.regexp.push({ pattern: /[ ]/g, replacement: (data.attribute ? replacement.character + "w" + replacement.character : replacement.character) }) - } - - return replacement.regexp.reduce((n, r) => n.replace(r.pattern, r.replacement), data.name); -} - -function FnGenerateShareFileName(data = { name }) { - replacement = { - character: "_", - regexp: [] - }; - - replacement.regexp.push({ pattern: /[/]/g, replacement: replacement.character }); - - return replacement.regexp.reduce((n, r) => n.replace(r.pattern, r.replacement), data.name); -} - -function FnGenerateShareName(character = { at: false, colon: false, period: false, whitespace: false }, data = { name }) { - let replacement = { - character: "_", - regexp: [] - }; - - replacement.regexp.push({ pattern: /[/]/g, replacement: replacement.character }); - - if (character.at) { - replacement.regexp.push({ pattern: /[@]/g, replacement: replacement.character }) - } - if (character.colon || zfsmanager.configuration.samba.windowscompatibility) { - replacement.regexp.push({ pattern: /[:]/g, replacement: replacement.character }) - } - if (character.period) { - replacement.regexp.push({ pattern: /[.]/g, replacement: replacement.character }) - } else if (zfsmanager.configuration.samba.windowscompatibility) { - replacement.regexp.push({ pattern: /[.]$/g, replacement: replacement.character }) - } - if (character.whitespace) { - replacement.regexp.push({ pattern: /[ ]/g, replacement: replacement.character }) - } - - return replacement.regexp.reduce((n, r) => n.replace(r.pattern, r.replacement), data.name); -} - -function FnRound(data = { decimals: 0, value }) { - data.multiplier = Math.pow(10, data.decimals); - - return Math.round(data.value * data.multiplier) / data.multiplier; -} - -//#endregion - -//#region Date/Time - -function FnDateTime() { - return (new Date).toLocaleString(zfsmanager.cockpit.datelocale, { day: "numeric", month: "numeric", year: "numeric", hour: "numeric", minute: "numeric", second: "numeric", hour12: true }); -} - -function FnDateTimeEpoch(data = { date }) { - return (new Date(data.date * 1000)).toLocaleString(zfsmanager.cockpit.datelocale, { hour12: true }); -} - -function FnDateTimeSnapshot(data = { date }) { - if (!data.date) { - data.date = new Date(); - } - - return data.date.getFullYear() + "." + FnAppendLeadingZeroes({ value: data.date.getMonth() + 1 }) + "." + FnAppendLeadingZeroes({ value: data.date.getDate() }) + "-" + FnAppendLeadingZeroes({ value: data.date.getHours() }) + "." + FnAppendLeadingZeroes({ value: data.date.getMinutes() }) + "." + FnAppendLeadingZeroes({ value: data.date.getSeconds() }); -} - -//#endregion - -//#region Display Alert - -function FnDisplayAlert(notification = { status, title, description, breakword: false }, toast = { name, id, timeout: 4 }) { - if (zfsmanager.cockpit.legacy) { //Dirty way of handling alerts for PF3 and PF4 - FnDisplayAlertLegacy({ status: notification.status, title: notification.title, description: notification.description, breakword: notification.breakword }, { name: toast.name, id: toast.id, timeout: toast.timeout }); - - return; - } - - toast.timeout = ($.isNumeric(toast.timeout) ? toast.timeout : 4); - toast.uniqueid = (new Date).getTime() + "-" + Math.round(Math.random() * 20); - - switch (notification.status) { - case "danger": - toast.icon = "fa fa-exclamation-circle"; - toast.statusaria = "Danger"; - break; - case "info": - toast.icon = "fa fa-info-circle"; - toast.statusaria = "Information"; - break; - case "success": - toast.icon = "fa fa-check-circle"; - toast.statusaria = "Success"; - break; - case "warning": - toast.icon = "fa fa-exclamation-triangle"; - toast.statusaria = "Warning"; - break; - default: - notification.status = ""; - toast.icon = "fa fa-bell"; - toast.statusaria = "Default"; - break; - } - - notification.output = ` -
  • -
    -
    - -
    -

    ` + toast.statusaria + ` alert:` + notification.title + `

    - ` + (notification.description ? `

    ` + notification.description + `

    ` : ``) + ` -
    - -
    -
    - - \x3Cscript nonce="1t55lZ7tzuKTreHVNwE66Ox32Mc="> - $("#alert-` + toast.name + (toast.id ? `-` + toast.id : ``) + `-` + toast.uniqueid + ` .pf-c-alert__action").on("click",".pf-c-button",function(){ - $("#alert-` + toast.name + (toast.id ? `-` + toast.id : ``) + `-` + toast.uniqueid + `").fadeTo(150, 0).slideUp(150, function () { - $(this).remove(); - }); - }); - - setTimeout(function () { - $("#alert-` + toast.name + (toast.id ? `-` + toast.id : ``) + `-` + toast.uniqueid + `").fadeTo(500, 0).slideUp(500, function () { - $(this).remove(); - }); - }, ` + toast.timeout + `000); - \x3C/script> -
  • - `; - - $("#alerts-notifications").append(notification.output); -} - -function FnDisplayAlertLegacy(notification = { status, title, description, breakword: false }, toast = { name, id, timeout: 4 }) { - toast.timeout = ($.isNumeric(toast.timeout) ? toast.timeout : 4); - toast.uniqueid = (new Date).getTime() + "-" + Math.round(Math.random() * 20); - - switch (notification.status) { - case "danger": - toast.icon = "pficon pficon-error-circle-o"; - break; - case "success": - toast.icon = "pficon pficon-ok"; - break; - case "warning": - toast.icon = "pficon pficon-warning-triangle-o"; - break; - default: - notification.status = "info"; - toast.icon = "pficon pficon-info"; - break; - } - - notification.output = ` -
    - - - ` + notification.title + (notification.description ? `:` : ``) + ` ` + (notification.description ? notification.description : ``) + ` - - \x3Cscript nonce="1t55lZ7tzuKTreHVNwE66Ox32Mc="> - setTimeout(function () { - $("#toast-` + toast.name + (toast.id ? `-` + toast.id : ``) + `-` + toast.uniqueid + `").fadeTo(500, 0).slideUp(500, function () { - $(this).remove(); - }); - }, ` + toast.timeout + `000); - \x3C/script> -
    - `; - - $("#alerts-notifications-legacy").append(notification.output); -} - -function FnDisplayInlineAlert(notification = { status, title, description }, inline = { name, id, hidden: false }) { - if (zfsmanager.cockpit.legacy) { //Dirty way of handling alerts for PF3 and PF4 - return FnDisplayInlineAlertLegacy({ status: notification.status, title: notification.title, description: notification.description }, { name: inline.name, id: inline.id, hidden: inline.hidden }); - } - - switch (notification.status) { - case "danger": - inline.icon = "fa fa-exclamation-circle"; - inline.statusaria = "Danger"; - break; - case "info": - inline.icon = "fa fa-info-circle"; - inline.statusaria = "Information"; - break; - case "success": - inline.icon = "fa fa-check-circle"; - inline.statusaria = "Success"; - break; - case "warning": - inline.icon = "fa fa-exclamation-triangle"; - inline.statusaria = "Warning"; - break; - default: - notification.status = ""; - inline.icon = "fa fa-bell"; - inline.statusaria = "Default"; - break; - } - - notification.output = ` -
    -
    - -
    -

    ` + inline.statusaria + ` inline alert:` + notification.title + `

    - ` + (notification.description ? `

    ` + notification.description + `

    ` : ``) + ` -
    - `; - - return notification.output; -} - -function FnDisplayInlineAlertLegacy(notification = { status, title, description }, inline = { name, id, hidden: false }) { - switch (notification.status) { - case "danger": - inline.icon = "pficon pficon-error-circle-o"; - break; - case "success": - inline.icon = "pficon pficon-ok"; - break; - case "warning": - inline.icon = "pficon pficon-warning-triangle-o"; - break; - default: - notification.status = "info"; - inline.icon = "pficon pficon-info"; - break; - } - - notification.output = ` -
    ` + notification.title + (notification.description ? `: ` + notification.description : ``) + `
    - `; - - return notification.output; -} - -//#endregion - -//#region Console Logging - -let FnConsole = () => { }; - -function FnConsoleCommand(process = { command: [] }) { - return JSON.stringify(process.command.join(" ")); -} - -function FnConsoleInitialize() { - FnConsole = (() => { - let time = () => { }; - - time.toString = () => { - return (new Date).toLocaleString(zfsmanager.cockpit.datelocale, { hour: "numeric", minute: "numeric", second: "numeric", hour12: true }) + ":"; - }; - - return { - error: console.error.bind(console, "%s", time), - log: { - 1: (zfsmanager.configuration.loglevel >= 1 ? console.log.bind(console, "%s", time) : FnConsoleNull), - 2: (zfsmanager.configuration.loglevel >= 2 ? console.log.bind(console, "%s", time) : FnConsoleNull), - 3: (zfsmanager.configuration.loglevel >= 3 ? console.log.bind(console, "%c%s Command: %s", "color: #0066CC", time) : FnConsoleNull), - 4: (zfsmanager.configuration.loglevel == 4 ? console.log.bind(console, "%c%s %s", "color: #486B00", time) : FnConsoleNull) - }, - warn: console.warn.bind(console, "%s", time) - } - })(); -} - -function FnConsoleNull() { - //Do not display console message -} - -function FnConsoleVerbose(process = { data, message }) { - return process.message + " Verbose\n" + process.data; -} - -//#endregion - -//#region Cockpit ZFS Manager - -function FnConfigurationGet() { - FnConsole.log[2]("Cockpit ZFS Manager, Configuration, Get: In Progress"); - FnConsole.log[3](FnConsoleCommand({ command: [`cockpit.file("/etc/cockpit/zfs/config.json").read()`] })); - - return cockpit.file("/etc/cockpit/zfs/config.json").read() - .done(function (user) { - FnConsole.log[4](FnConsoleVerbose({ data: user, message: "Cockpit ZFS Manager, Configuration, Get:" })); - - try { - user = JSON.parse(user, (key, value) => { - if (/^#[0-9]/.test(key) == false) { - return value; - } - }); - - user.cockpit = (user.cockpit === undefined ? zfsmanager.configuration.cockpit : user.cockpit); - user.cockpit.manage = (user.cockpit.manage === undefined ? zfsmanager.configuration.cockpit.manage : user.cockpit.manage); - - user.disks = (user.disks === undefined ? zfsmanager.configuration.disks : user.disks); - user.disks.base2 = (user.disks.base2 === undefined ? zfsmanager.configuration.disks.base2 : user.disks.base2); - - user.loglevel = (user.loglevel === undefined ? zfsmanager.configuration.loglevel : user.loglevel); - - user.samba = (user.samba === undefined ? zfsmanager.configuration.samba : user.samba); - user.samba.manage = (user.samba.manage === undefined ? zfsmanager.configuration.samba.manage : user.samba.manage); - user.samba.windowscompatibility = (user.samba.windowscompatibility === undefined ? zfsmanager.configuration.samba.windowscompatibility : user.samba.windowscompatibility); - - user.updates = (user.updates === undefined ? zfsmanager.configuration.updates : user.updates); - user.updates.check = (user.updates.check === undefined ? zfsmanager.configuration.updates.check : user.updates.check); - - user.zfs = (user.zfs === undefined ? zfsmanager.configuration.zfs : user.zfs); - user.zfs.filesystem = (user.zfs.filesystem === undefined ? zfsmanager.configuration.zfs.filesystem : user.zfs.filesystem); - user.zfs.filesystem.snapshotactions = (user.zfs.filesystem.snapshotactions === undefined ? zfsmanager.configuration.zfs.filesystem.snapshotactions : user.zfs.filesystem.snapshotactions); - user.zfs.filesystem.cloneorigin = (user.zfs.filesystem.cloneorigin === undefined ? zfsmanager.configuration.zfs.filesystem.cloneorigin : user.zfs.filesystem.cloneorigin); - user.zfs.filesystem.quotarestrict = (user.zfs.filesystem.quotarestrict === undefined ? zfsmanager.configuration.zfs.filesystem.quotarestrict : user.zfs.filesystem.quotarestrict); - user.zfs.filesystem.readonlylockdown = (user.zfs.filesystem.readonlylockdown === undefined ? zfsmanager.configuration.zfs.filesystem.readonlylockdown : user.zfs.filesystem.readonlylockdown); - user.zfs.status = (user.zfs.status === undefined ? zfsmanager.configuration.zfs.status : user.zfs.status); - user.zfs.status.errorcolors = (user.zfs.status.errorcolors === undefined ? zfsmanager.configuration.zfs.status.errorcolors : user.zfs.status.errorcolors); - user.zfs.status.trimunsupported = (user.zfs.status.trimunsupported === undefined ? zfsmanager.configuration.zfs.status.trimunsupported : user.zfs.status.trimunsupported); - user.zfs.storagepool = (user.zfs.storagepool === undefined ? zfsmanager.configuration.zfs.storagepool : user.zfs.storagepool); - user.zfs.storagepool.activetab = (user.zfs.storagepool.activetab === undefined ? zfsmanager.configuration.zfs.storagepool.activetab : user.zfs.storagepool.activetab); - user.zfs.storagepool.boot = (user.zfs.storagepool.boot === undefined ? zfsmanager.configuration.zfs.storagepool.boot : user.zfs.storagepool.boot); - user.zfs.storagepool.bootlockdown = (user.zfs.storagepool.bootlockdown === undefined ? zfsmanager.configuration.zfs.storagepool.bootlockdown : user.zfs.storagepool.bootlockdown); - user.zfs.storagepool.root = (user.zfs.storagepool.root === undefined ? zfsmanager.configuration.zfs.storagepool.root : user.zfs.storagepool.root); - user.zfs.storagepool.refreshall = (user.zfs.storagepool.refreshall === undefined ? zfsmanager.configuration.zfs.storagepool.refreshall : user.zfs.storagepool.refreshall); - - zfsmanager.configuration = user; - zfsmanager.user.configuration = true; - - FnConsole.log[1]("Cockpit ZFS Manager, Configuration, Get: Success"); - - FnConsoleInitialize(); - } - catch (error) { - FnConsole.warn("Cockpit ZFS Manager, Configuration, Get: Failed, Message: Configuration does not exist. Using defaults."); - }; - }) - .fail(function (message) { - FnConsole.warn("Cockpit ZFS Manager, Configuration, Get: Failed, Message: Configuration does not exist. Using defaults."); - }); -}; - -function FnConfigure(user = { cockpit: { manage: true }, disks: { base2: false }, loglevel: 1, samba: { manage: true, windowscompatibility: true }, updates: { check: true }, zfs: { filesystem: { cloneorigin: false, quotarestrict: true, readonlylockdown: true, snapshotactions: true }, status: { errorcolors: true, trimunsupported: false }, storagepool: { activetab: 1, boot: true, bootlockdown: true, refreshall: false, root: true } } }, modal = { name, welcome: false }) { - let process = { - command: ["/bin/sh", "-c", "echo '" + JSON.stringify(user, null, " ").replace(/^\{\n/, `{\n "#1": "COCKPIT ZFS MANAGER",\n "#2": "WARNING: DO NOT EDIT, AUTO-GENERATED CONFIGURATION",\n`) + "' > /etc/cockpit/zfs/config.json"] - }; - - FnConsole.log[2]("Cockpit ZFS Manager, Configure: In Progress"); - FnConsole.log[2](FnConsoleCommand({ command: process.command })); - - $("#spinner-" + modal.name + " span").text("Saving configuration..."); - - return cockpit.spawn(process.command, { err: "out", superuser: "require" }) - .done(function (data) { - FnDisplayAlert({ status: "success", title: "Configuration successfully updated", description: null, breakword: false }, { name: modal.name, id: null, timeout: 4 }); - - FnConsole.log[1]("Cockpit ZFS Manager, Configure: Success"); - }) - .fail(function (message, data) { - FnDisplayAlert({ status: "danger", title: "Configuration could not be updated", description: null, breakword: false }, { name: modal.name, id: null, timeout: 4 }); - - FnConsole.warn("Cockpit ZFS Manager, Configure: Failed, Message: " + (data ? data : message)); - }) - .finally(function () { - if ((modal.welcome || !modal.welcome && zfsmanager.configuration.samba.manage) && !user.samba.manage) { - FnSambaSharesDestroyAll({ restart: false }, { silent: true }, { name: modal.name }) - .finally(function () { - FnConfigureFinally({ name: modal.name, welcome: modal.welcome }); - }); - } else if ((modal.welcome || !modal.welcome && !zfsmanager.configuration.samba.manage) && user.samba.manage) { - FnSambaSharesEnableAll({ restart: false }, { silent: false }, { name: modal.name }) - .finally(function () { - FnConfigureFinally({ name: modal.name, welcome: modal.welcome }); - }); - } else { - FnConfigureFinally({ name: modal.name, welcome: modal.welcome }); - } - }); -} - -function FnConfigureFinally(modal = { name, welcome: false }) { - $("#spinner-" + modal.name + " span").text("Reloading Cockpit ZFS Manager..."); - - setTimeout(function () { - location.reload(true); - }, 2000); -} - -function FnConfigurationDirectoryCreate() { - let process = { - command: ["/bin/sh", "-c", `[ ! -d /etc/cockpit/zfs ] || [ ! -d /etc/cockpit/zfs/shares ] || [ ! -d /etc/cockpit/zfs/snapshots ] && /bin/mkdir -p /etc/cockpit/zfs/shares /etc/cockpit/zfs/snapshots || printf "Skipped"`] - }; - - FnConsole.log[2]("Cockpit ZFS Manager, Configuration Directory, Create: In Progress"); - FnConsole.log[2](FnConsoleCommand({ command: process.command })); - - return cockpit.spawn(process.command, { err: "out" }) - .done(function (data) { - FnConsole.log[4](FnConsoleVerbose({ data: data, message: "Cockpit ZFS Manager, Configuration Directory, Create:" })); - - if (data == "Skipped") { - FnConsole.log[2]("Cockpit ZFS Manager, Configuration Directory, Create: Skipped"); - } else { - FnConsole.log[1]("Cockpit ZFS Manager, Configuration Directory, Create: Success"); - } - }) - .fail(function (message, data) { - FnConsole.warn("Cockpit ZFS Manager, Configuration Directory, Create: Failed, Message: " + (data ? data : message)); - }); -} - -function FnConfigurationDirectoryRuntimeCreate() { - let process = { - command: ["/bin/sh", "-c", `[ ! -d /run/cockpit/zfs/shares ] && /bin/mkdir -p /run/cockpit/zfs/shares || printf "Skipped"`] - }; - - FnConsole.log[2]("Cockpit ZFS Manager, Runtime Configuration Directory, Create: In Progress"); - FnConsole.log[3](FnConsoleCommand({ command: process.command })); - - return cockpit.spawn(process.command, { err: "out" }) - .done(function (data) { - FnConsole.log[4](FnConsoleVerbose({ data: data, message: "Cockpit ZFS Manager, Runtime Configuration Directory, Create:" })); - - if (data == "Skipped") { - FnConsole.log[2]("Cockpit ZFS Manager, Runtime Configuration Directory, Create: Skipped"); - } else { - FnConsole.log[1]("Cockpit ZFS Manager, Runtime Configuration Directory, Create: Success"); - } - }) - .fail(function (message, data) { - FnConsole.warn("Cockpit ZFS Manager, Runtime Configuration Directory, Create: Failed, Message: " + (data ? data : message)); - }); -} - -function FnConfigurationLegacyGet() { - let process = { - command: ["/bin/sh", "-c"] - }; - - FnCockpitPackagePathGet({ sosreport: false }) - .done(function (data) { - let path = data.replace(/\s +/g, "\u22C5").replace(/\/$/, "").replace(/\n/, "").split("\u22C5")[2]; - - if (!path || /\/cockpit\/zfs/.test(path) == false) { - path = "/usr/share/cockpit/zfs" - } - - process.command.push(`[ -e '` + path + `/config.json' ] && printf "true" || printf "false"`); - - FnConsole.log[2]("Cockpit ZFS Manager, Configuration, Legacy, Get: In Progress"); - FnConsole.log[3](FnConsoleCommand({ command: process.command })); - - cockpit.spawn(process.command, { err: "out" }) - .done(function (_data) { - FnConsole.log[4](FnConsoleVerbose({ data: _data, message: "Cockpit ZFS Manager, Configuration, Legacy, Get:" })); - - if (_data == "true") { - FnConsole.log[1]("Cockpit ZFS Manager, Configuration, Legacy, Get: Success"); - - FnModalUpdateContent({ id: $("#modal-update") }); - - $("#modal-update").modal("show"); - $("#spinner-update span").text("Relocating configuration file..."); - - FnConfigurationLegacyRelocate({ path: path }) - .done(function () { - $("#spinner-update span").text("Reloading Cockpit ZFS Manager..."); - - setTimeout(function () { - location.reload(true); - }, 2000); - }) - .fail(function () { - FnModalWelcomeContent({ id: $("#modal-welcome") }); - - $("#modal-update").modal("hide"); - $("#modal-welcome").modal("show"); - }); - } else { - FnConsole.log[2]("Cockpit ZFS Manager, Configuration, Legacy, Get: " + (_data == "false" ? "Skipped" : "Failed")); - - FnModalWelcomeContent({ id: $("#modal-welcome") }); - - $("#modal-welcome").modal("show"); - } - }) - .fail(function (_message, _data) { - FnConsole.warn("Cockpit ZFS Manager, Configuration, Legacy, Get: Failed, Message: " + (_data ? _data : _message)); - - FnModalWelcomeContent({ id: $("#modal-welcome") }); - - $("#modal-welcome").modal("show"); - }); - }) - .fail(function () { - FnModalWelcomeContent({ id: $("#modal-welcome") }); - - $("#modal-welcome").modal("show"); - }); -} - -function FnConfigurationLegacyRelocate(legacy = { path }) { - let process = { - command: ["/bin/sh", "-c", `/bin/mv -f ` + legacy.path + `/config.json /etc/cockpit/zfs/config.json`] - }; - - FnConsole.log[2]("Cockpit ZFS Manager, Configuration, Legacy, Relocate: In Progress"); - FnConsole.log[3](FnConsoleCommand({ command: process.command })); - - return cockpit.spawn(process.command, { err: "out", superuser: "require" }) - .done(function (data) { - FnConsole.log[4](FnConsoleVerbose({ data: data, message: "Cockpit ZFS Manager, Configuration, Legacy, Relocate:" })); - - FnConsole.log[1]("Cockpit ZFS Manager, Configuration, Legacy, Relocate: Success"); - }) - .fail(function (message, data) { - FnConsole.warn("Cockpit ZFS Manager, Configuration, Legacy, Relocate: Failed, Message: " + (data ? data : message)); - }); -} - -function FnUpdatesCheck(display = { alert: true }) { - FnConsole.log[2]("Cockpit ZFS Manager, Updates, Check: In Progress"); - - $.ajax({ url: "https://api.github.com/repos/optimans/cockpit-zfs-manager/releases", dataType: "json", cache: false }) - .done(function (data) { - if (data[0].name) { - if (FnUpdatesVersionCompare({ installed: zfsmanager.version, latest: data[0].name }) < 0) { - setTimeout(function () { - $("#alert-about-update").removeClass("hidden"); - $("#span-about-update-version").html(`` + data[0].name + ` ` + (data[0].prerelease === true ? `(Pre-release)` : `(Release)`) + ``); - - if (display.alert) { - FnDisplayAlert({ status: "info", title: "A new version of Cockpit ZFS Manager is now available", description: ` ` + data[0].name + ` ` + (data[0].prerelease === true ? `(Pre-release)` : `(Release)`) + ``, breakword: true }, { name: "update", id: null, timeout: 30 }); - } - }, 500); - } - - FnConsole.log[2]("Cockpit ZFS Manager, Updates, Check: Success"); - } else { - FnConsole.warn("Cockpit ZFS Manager, Updates, Check: Failed, Message: Unable to retrieve release information."); - } - }) - .fail(function (message) { - FnConsole.warn("Cockpit ZFS Manager, Updates, Check: Failed, Message: " + message); - }); -} - -function FnUpdatesVersionCompare(version = { installed, latest }) { - version.installed = version.installed.replace(/[^0-9.-]/g, "").replace(/\s+/g, "").replace(/-/g, ".").split("."); - version.latest = version.latest.replace(/[^0-9.-]/g, "").replace(/\s+/g, "").replace(/-/g, ".").split("."); - - let min = Math.min(version.installed.length, version.latest.length); - - for (let i = 0; i < min; ++i) { - version.installed[i] = parseInt(version.installed[i], 10); - version.latest[i] = parseInt(version.latest[i], 10); - - if (version.installed[i] > version.latest[i]) { - return 1; - } - if (version.installed[i] < version.latest[i]) { - return -1; - } - } - - return version.installed.length == (version.latest.length ? 0 : (version.installed.length < version.latest.length ? -1 : 1)); -} - -function FnVersionWarning() { - if (/alpha|beta|dev|internal|pre|rc/gi.test(zfsmanager.version)) { - FnDisplayAlert({ status: "warning", title: "Pre-release version of Cockpit ZFS Manager is installed", description: zfsmanager.version + ` is an unstable build and features may not work as intended`, breakword: true }, { name: "version-warning", id: null, timeout: 60 }); - } -} - -//#endregion - -//#region Cockpit - -function FnCockpitElementsDisable() { - let message = `The user ` + zfsmanager.user.name + ` is not permitted to`; - - //Disable buttons - $("#btn-configure").addClass("disabled"); - $("#btn-storagepools-filesystems-unlock").addClass("disabled"); - $("#btn-storagepools-create").prop("title", message + " create a storage pool").attr("data-placement", "auto bottom").attr("data-toggle", "tooltip").addClass("disabled"); - $("#btn-storagepools-import").prop("title", message + " import a storage pool").attr("data-placement", "auto bottom").attr("data-toggle", "tooltip").addClass("disabled"); - $("[id^=btn-storagepool-filesystems-create-]").prop("title", message + " create a file system").attr("data-placement", "auto top").attr("data-toggle", "tooltip").addClass("disabled"); - $("[id^=btn-storagepool-snapshots-create-]").prop("title", message + " create a snapshot").attr("data-placement", "auto top").attr("data-toggle", "tooltip").addClass("disabled"); - $("[id^=btn-storagepool-snapshot-dropdown-]").prop("title", message + " manage this snapshot").attr("data-placement", "auto left").attr("data-toggle", "tooltip").addClass("disabled"); - $("[id^=btn-storagepool-status-dropdown-]").prop("title", message + " manage this storage pool").attr("data-placement", "auto left").attr("data-toggle", "tooltip").addClass("disabled"); - - //Disable privileged items - $(".privileged").addClass("disabled"); - - //Disable privileged modal items - $(".privileged-modal").prop("disabled", true); - $(".privileged-modal button").prop("disabled", true); - $(".privileged-modal input").prop("disabled", true); - - //Disable sliders - $("#validationwrapper-storagepools-create-refreservation .slider-pf .slider *").addClass("disabled"); - $("#slider-storagepools-create-refreservation").slider("disable"); - $("[id^=validationwrapper-storagepool-filesystems-create-quota-] .slider-pf .slider *").addClass("disabled"); - $("[id^=slider-storagepool-filesystems-create-quota-]").slider("disable"); - $("[id^=validationwrapper-storagepool-filesystem-configure-quota-] .slider-pf .slider *").addClass("disabled"); - $("[id^=slider-storagepool-filesystem-configure-quota-]").slider("disable"); - $("[id^=validationwrapper-storagepool-filesystem-configure-refreservation-] .slider-pf .slider *").addClass("disabled"); - $("[id^=slider-storagepool-filesystem-configure-refreservation-]").slider("disable"); - - //Remove primary color from unlock file system menu item - $("[id^=btn-storagepool-filesystem-unlock-] > strong").removeClass("text-ct-locked"); - $("[id^=btn-storagepool-filesystem-unlock-icon-]").removeClass("pficon-ct-locked"); -} - -function FnCockpitSmbDisable() { - let message = `The user ` + zfsmanager.user.name + ` is not permitted to`; - FnConsole.log[2]("FnCockpitSmbDisable: " + zfsmanager.user.name ); - // Disable buttons - $("#btn-configure").addClass("disabled"); - $("#btn-storagepools-filesystems-unlock").addClass("disabled"); - $("#btn-storagepools-create").prop("title", message + " create a storage pool").attr("data-placement", "auto bottom").attr("data-toggle", "tooltip").addClass("disabled"); - $("#btn-storagepools-import").prop("title", message + " import a storage pool").attr("data-placement", "auto bottom").attr("data-toggle", "tooltip").addClass("disabled"); - $("#btn-storagepool-configure-test").prop("title", message + " configure a storage pool").attr("data-placement", "auto bottom").attr("data-toggle", "tooltip").addClass("disabled"); - //$("[id^=btn-storagepool-filesystems-create-]").prop("title", message + " create a file system").attr("data-placement", "auto top").attr("data-toggle", "tooltip").addClass("disabled"); - //$("[id^=btn-storagepool-snapshots-create-]").prop("title", message + " create a snapshot").attr("data-placement", "auto top").attr("data-toggle", "tooltip").addClass("disabled"); - //$("[id^=btn-storagepool-snapshot-dropdown-]").prop("title", message + " manage this snapshot").attr("data-placement", "auto left").attr("data-toggle", "tooltip").addClass("disabled"); - $("[id^=btn-storagepool-status-dropdown-]").prop("title", message + " manage this storage pool").attr("data-placement", "auto left").attr("data-toggle", "tooltip").addClass("disabled"); - - //Disable privileged items - //$(".privileged").addClass("disabled"); - - //Disable privileged modal items - $(".privileged-modal").prop("disabled", true); - $(".privileged-modal button").prop("disabled", true); - $(".privileged-modal input").prop("disabled", true); - - //Disable sliders - $("#validationwrapper-storagepools-create-refreservation .slider-pf .slider *").addClass("disabled"); - $("#slider-storagepools-create-refreservation").slider("disable"); - $("[id^=validationwrapper-storagepool-filesystems-create-quota-] .slider-pf .slider *").addClass("disabled"); - $("[id^=slider-storagepool-filesystems-create-quota-]").slider("disable"); - $("[id^=validationwrapper-storagepool-filesystem-configure-quota-] .slider-pf .slider *").addClass("disabled"); - $("[id^=slider-storagepool-filesystem-configure-quota-]").slider("disable"); - $("[id^=validationwrapper-storagepool-filesystem-configure-refreservation-] .slider-pf .slider *").addClass("disabled"); - $("[id^=slider-storagepool-filesystem-configure-refreservation-]").slider("disable"); - - //Remove primary color from unlock file system menu item - $("[id^=btn-storagepool-filesystem-unlock-] > strong").removeClass("text-ct-locked"); - $("[id^=btn-storagepool-filesystem-unlock-icon-]").removeClass("pficon-ct-locked"); -} - -function FnCockpitElementsUpdate() { - if (!zfsmanager.user.admin && !zfsmanager.user.zfs && !zfsmanager.user.smb ) { - FnCockpitElementsDisable(); - } else if (zfsmanager.user.smb && !zfsmanager.user.admin && !zfsmanager.user.zfs ) { - FnConsole.log[2]("FnCockpitElementsUpdate: " + zfsmanager.user.name ); - FnCockpitSmbDisable(); - } -} - -function FnCockpitManage() { - if (zfsmanager.user.admin) { - FnCockpitPackageSosReportDelete(); //SOS Report package will cause ZFS storage drives to appear offline when performing a diagnostic report - } -} - -function FnCockpitPackagePathGet(package = { sosreport: false }) { - let process = { - command: ["/bin/sh", "-c", `cockpit-bridge --packages | /bin/grep -m1 '/cockpit/` + (package.sosreport ? `sosreport` : `zfs`) + `$' || printf "false"`] //printf fix for Debian - }; - - FnConsole.log[2]("Cockpit, " + (package.sosreport ? "SOS Report" : "Cockpit ZFS Manager") + " Package Path, Get: In Progress"); - FnConsole.log[3](FnConsoleCommand({ command: process.command })); - - return cockpit.spawn(process.command, { err: "out" }) - .done(function (data) { - FnConsole.log[4](FnConsoleVerbose({ data: data, message: "Cockpit, " + (package.sosreport ? "SOS Report" : "Cockpit ZFS Manager") + " Package Path, Get:" })); - - let path = data.replace(/\s +/g, "\u22C5").replace(/\/$/, "").replace(/\n/, "").split("\u22C5")[2]; - - FnConsole.log[1]("Cockpit, " + (package.sosreport ? "SOS Report" : "Cockpit ZFS Manager") + " Package Path, Get: " + (path ? "Success" : "Failed")); - }) - .fail(function (message, data) { - FnConsole.warn("Cockpit, " + (package.sosreport ? "SOS Report" : "Cockpit ZFS Manager") + " Package Path, Get: Failed, Message: " + (data ? data : message)); - }); -} - -function FnCockpitPackageSosReportDelete() { - let process = { - command: ["/bin/sh", "-c"] - }; - - FnCockpitPackagePathGet({ sosreport: true }) - .done(function (data) { - let path = data.replace(/\s +/g, "\u22C5").replace(/\/$/, "").replace(/\n/, "").split("\u22C5")[2]; - - if (!path || /\/cockpit\/sosreport$/.test(path) == false) { - path = "/usr/share/cockpit/sosreport" - } - - process.command.push(`[ -e '` + path + `' ] && /bin/rm -rf ` + path + ` || printf "Skipped"`); - - FnConsole.log[2]("Cockpit, Package, SOS Report, Delete: In Progress"); - FnConsole.log[3](FnConsoleCommand({ command: process.command })); - - cockpit.spawn(process.command, { err: "out", superuser: "require" }) - .done(function (_data) { - FnConsole.log[4](FnConsoleVerbose({ data: _data, message: "Cockpit, Package, SOS Report, Delete:" })); - - if (_data == "Skipped") { - FnConsole.log[2]("Cockpit, Package, SOS Report, Delete: Skipped"); - } else { - FnConsole.log[1]("Cockpit, Package, SOS Report, Delete: Success"); - } - }) - .fail(function (_message, _data) { - FnConsole.warn("Cockpit, Package, SOS Report, Delete: Failed, Message: " + (_data ? _data : _message)); - }); - }); -} - -function FnCockpitPermissionsGet() { - FnConsole.log[2]("Cockpit, Permissions, Get: In Progress"); - - zfsmanager.cockpit.permission = cockpit.permission({ admin: true }); - zfsmanager.cockpit.zfspermission = cockpit.permission({ group: "zfsadmin" }); - zfsmanager.cockpit.smbpermission = cockpit.permission({ group: "smbadmin" }); - - $(zfsmanager.cockpit.smbpermission).on("changed", function () { - zfsmanager.user.admin = zfsmanager.cockpit.permission.allowed; - zfsmanager.user.zfs = zfsmanager.cockpit.zfspermission.allowed; - zfsmanager.user.smb = zfsmanager.cockpit.smbpermission.allowed; - FnConsole.log[2]("Cockpit, Permissions, Get: admin: " + zfsmanager.cockpit.permission.allowed ) - FnConsole.log[2]("Cockpit, Permissions, Get: zfs: " + zfsmanager.cockpit.zfspermission.allowed ) - FnConsole.log[2]("Cockpit, Permissions, Get: smb: " + zfsmanager.cockpit.smbpermission.allowed ) - - zfsmanager.user.name = (zfsmanager.cockpit.permission.user ? zfsmanager.cockpit.permission.user.name : ""); - - if (zfsmanager.user.admin || zfsmanager.user.zfs ) { - FnConsole.log[2]("Cockpit, Permissions, Get: Success"); - FnConsole.log[2]("Cockpit, Permissions, Get: Success, for admin user: " + zfsmanager.user.name ); - - zfsmanager.user.admin = true; - FnFirstStepsPrivileged(); - } else if (zfsmanager.user.smb) { - FnConsole.log[2]("Cockpit, Permissions, Get: Success"); - FnConsole.log[2]("Cockpit, Permissions, Get: Success, for smb user: " + zfsmanager.user.name ); - FnConsole.log[2]("FnCockpitElementsUpdate: " + zfsmanager.user.name ); - FnCockpitSmbDisable(); - } else { - FnConsole.warn("Cockpit, Permissions, Get: Warning, Message: " + zfsmanager.user.name + " does not have admin permissions"); - - FnCockpitElementsDisable(); - } - }); -} - -//#endregion - -//#region ZFS - -function FnZfsVersionCompare(version = { installed, threshold }) { - version.installed = version.installed.replace(/[^0-9.-]/g, "").replace(/\s+/g, "").replace(/-/g, ".").split("."); - version.threshold = version.threshold.replace(/\s+/g, "").replace(/-/g, ".").split("."); - - if (!version.installed[0]) { - return -1; - } - - let min = Math.min(version.installed.length, version.threshold.length); - - for (let i = 0; i < min; ++i) { - version.installed[i] = parseInt(version.installed[i], 10); - version.threshold[i] = parseInt(version.threshold[i], 10); - - if (version.installed[i] > version.threshold[i]) { - return 1; - } - if (version.installed[i] < version.threshold[i]) { - return -1; - } - } - - return version.installed.length == (version.threshold.length ? 0 : (version.installed.length < version.threshold.length ? -1 : 1)); -} - -function FnZfsVersionGet() { - let process = { - command: ["/bin/cat", "/sys/module/zfs/version"] - }; - let zfs = { - success: false, - threshold: "0.8" - }; - - FnConsole.log[2]("ZFS, Version, Get: In Progress"); - FnConsole.log[3](FnConsoleCommand({ command: process.command })); - - return cockpit.spawn(process.command, { err: "out" }) - .done(function (data, message) { - FnConsole.log[4](FnConsoleVerbose({ data: data, message: "ZFS, Version, Get:" })); - - if (data) { - zfsmanager.zfs.version = data.replace(/\s+/g, ""); - } - - if (!data || FnZfsVersionCompare({ installed: zfsmanager.zfs.version, threshold: zfs.threshold }) < 0) { - FnConsole.error("ZFS, Version, Get: Failed, Message: Version " + (zfsmanager.zfs.version ? zfsmanager.zfs.version : "0") + " < " + zfs.threshold); - } else { - zfs.success = true; - - FnConsole.log[1]("ZFS, Version, Get: Success, Version: " + (data ? data : message)); - } - }) - .fail(function (message, data) { - FnConsole.error("ZFS, Version, Get: Failed, Message: " + (data ? data : message)); - }) - .finally(function () { - if (!zfs.success) { - zfs.message = ` -
    - -
    -

    This package requires ZFS version ` + zfs.threshold + ` or later

    -

    If ZFS is installed, check the module is loaded into the kernel.

    -
    - -
    - `; - - $("#alerts-requirements").removeClass("hidden").html(zfs.message); - $("#container").addClass("hidden"); - } else { - if (!zfsmanager.configuration.samba.manage) { - $("#alerts-requirements").empty().addClass("hidden"); - $("#container").removeClass("hidden"); - } - } - }); -} - -function FnZfsVersionWarnings() { - zfsmanager.zfs.warnings.nvmevdev = (FnZfsVersionCompare({ installed: zfsmanager.zfs.version, threshold: "0.8.3" }) < 0 ? true : false); //GitHub Issue #9730 -} - -//#endregion - -//#region Storage Pools - -function FnStoragePoolsGet() { - let process = { - command: ["/sbin/zpool", "list", "-H", "-o", "name,guid,health,size,alloc,free,fragmentation,readonly,altroot,autotrim,version,feature@allocation_classes,feature@async_destroy,feature@bookmark_v2,feature@bookmarks,feature@device_removal,feature@edonr,feature@embedded_data,feature@empty_bpobj,feature@enabled_txg,feature@encryption,feature@extensible_dataset,feature@filesystem_limits,feature@hole_birth,feature@large_blocks,feature@large_dnode,feature@lz4_compress,feature@multi_vdev_crash_dump,feature@obsolete_counts,feature@project_quota,feature@resilver_defer,feature@sha512,feature@skein,feature@spacemap_histogram,feature@spacemap_v2,feature@userobj_accounting,feature@zpool_checkpoint", "-p"] - }; - let pools = { - empty: true - }; - - //Disable storage pool status auto refresh - zfsmanager.zfs.storagepool.refreshid.forEach((_value, _index) => { - clearInterval(_value); - }); - zfsmanager.zfs.storagepool.refreshid = []; - - $("#btn-storagepools-refresh").prop("disabled", true); - $("#table-storagepools > tbody").remove(); - $("[id^=modals-storagepool-]").remove(); - $("[id^=dynamics-storagepool-]").remove(); - $("#spinner-storagepools").removeClass("hidden"); - - FnConsole.log[2]("Storage Pools, Get: In Progress"); - FnConsole.log[3](FnConsoleCommand({ command: process.command })); - - FnStoragePoolsSystemReservedGet() - .finally(function () { - cockpit.spawn(process.command, { err: "out" }) - .done((data, message) => { - FnConsole.log[4](FnConsoleVerbose({ data: data, message: "Storage Pools, Get:" })); - - if (data) { - pools.empty = false; - - FnStoragePoolsGetCommand({ data: data, message: message }); - } - - FnConsole.log[1]("Storage Pools, Get: Success"); - }) - .fail((message, data) => { - FnConsole.warn("Storage Pools, Get: Failed, Message: " + (data ? data : message)); - }) - .finally(function () { - if ($("#table-storagepools > tbody").length == 0) { - pools.empty = true; - } - - if (pools.empty) { - $("#table-storagepools").append(`No storage pools found.`); - } - - setTimeout(function () { - $("#spinner-storagepools").addClass("hidden"); - $("#table-storagepools > tbody").removeClass("hidden"); - }, 200); - - $("#btn-storagepools-refresh").prop("disabled", false); - - FnCockpitElementsUpdate(); - }); - }); -} - -function FnStoragePoolsGetCommand(process = { data, message }) { - let pools = { - id: [] - }; - - pools.id = process.data.split(/\n/g).filter(v => { - if (!zfsmanager.configuration.zfs.storagepool.boot && zfsmanager.zfs.storagepool.boot && new RegExp("^" + zfsmanager.zfs.storagepool.boot + "\t").test(v)) { - //Do not display boot - } else if (!zfsmanager.configuration.zfs.storagepool.root && zfsmanager.zfs.storagepool.root && new RegExp("^" + zfsmanager.zfs.storagepool.root + "\t").test(v)) { - //Do not display root - } else { - return v; - } - }); - - pools.id.forEach((_value, _index) => { - let pool = { - properties: _value.split(/\t/g).filter(v => v), - actionsmenu: { - register: {} - } - }; - - //0=name, 1=guid, 2=health, 3=size, 4=alloc, 5=free, 6=fragmentation, 7=readonly, 8=altroot, 9=autotrim, 10=version, 11=feature@allocation_classes, 12=feature@async_destroy, 13=feature@bookmark_v2, 14=feature@bookmarks, 15=feature@device_removal, 16=feature@edonr, 17=feature@embedded_data, 18=feature@empty_bpobj, 19=feature@enabled_txg, 20=feature@encryption, 21=feature@extensible_dataset, 22=feature@filesystem_limits, 23=feature@hole_birth, 24=feature@large_blocks, 25=feature@large_dnode, 26=feature@lz4_compress, 27=feature@multi_vdev_crash_dump, 28=feature@obsolete_counts, 29=feature@project_quota, 30=feature@resilver_defer, 31=feature@sha512, 32=feature@skein, 33=feature@spacemap_histogram, 34=feature@spacemap_v2, 35=feature@userobj_accounting, 36=feature@zpool_checkpoint - - pool.activetab = "filesystems"; - pool.allocated = FnFormatBytes({ base2: true, decimals: 2, value: pool.properties[4] }); - pool.allocatedpercent = FnRound({ decimals: 2, value: (pool.properties[4] / pool.properties[3]) * 100 }); - pool.altroot = (pool.properties[8] && pool.properties[8] != "-" ? true : false); - pool.autotrim = (pool.properties[9].toLowerCase() == "on" ? true : false); - pool.boot = (zfsmanager.zfs.storagepool.boot && pool.properties[0] == zfsmanager.zfs.storagepool.boot ? true : false); - pool.feature = { - allocation_classes: (/active|enabled/gi.test(pool.properties[11]) ? true : false), - async_destroy: (/active|enabled/gi.test(pool.properties[12]) ? true : false), - bookmark_v2: (/active|enabled/gi.test(pool.properties[13]) ? true : false), - bookmarks: (/active|enabled/gi.test(pool.properties[14]) ? true : false), - device_removal: (/active|enabled/gi.test(pool.properties[15]) ? true : false), - edonr: (/active|enabled/gi.test(pool.properties[16]) ? true : false), - embedded_data: (/active|enabled/gi.test(pool.properties[17]) ? true : false), - empty_bpobj: (/active|enabled/gi.test(pool.properties[18]) ? true : false), - enabled_txg: (/active|enabled/gi.test(pool.properties[19]) ? true : false), - encryption: (/active|enabled/gi.test(pool.properties[20]) ? true : false), - extensible_dataset: (/active|enabled/gi.test(pool.properties[21]) ? true : false), - filesystem_limits: (/active|enabled/gi.test(pool.properties[22]) ? true : false), - hole_birth: (/active|enabled/gi.test(pool.properties[23]) ? true : false), - large_blocks: (/active|enabled/gi.test(pool.properties[24]) ? true : false), - large_dnode: (/active|enabled/gi.test(pool.properties[25]) ? true : false), - lz4_compress: (/active|enabled/gi.test(pool.properties[26]) ? true : false), - multi_vdev_crash_dump: (/active|enabled/gi.test(pool.properties[27]) ? true : false), - obsolete_counts: (/active|enabled/gi.test(pool.properties[28]) ? true : false), - project_quota: (/active|enabled/gi.test(pool.properties[29]) ? true : false), - resilver_defer: (/active|enabled/gi.test(pool.properties[30]) ? true : false), - sha512: (/active|enabled/gi.test(pool.properties[31]) ? true : false), - skein: (/active|enabled/gi.test(pool.properties[32]) ? true : false), - spacemap_histogram: (/active|enabled/gi.test(pool.properties[33]) ? true : false), - spacemap_v2: (/active|enabled/gi.test(pool.properties[34]) ? true : false), - userobj_accounting: (/active|enabled/gi.test(pool.properties[35]) ? true : false), - zpool_checkpoint: (/active|enabled/gi.test(pool.properties[36]) ? true : false) - }; - pool.fragmentation = (pool.properties[6] == "-" ? 0 : pool.properties[6]); - pool.free = FnFormatBytes({ base2: true, decimals: 2, value: pool.properties[5] }); - pool.freepercent = FnRound({ decimals: 2, value: (pool.properties[5] / pool.properties[3]) * 100 }); - pool.guid = pool.properties[1]; - pool.health = pool.properties[2]; - pool.healthicon = FnStoragePoolHealthIcon({ health: pool.properties[2] }); - pool.id = FnGenerateId({ at: false, colon: true, forwardslash: false, period: true, underscore: true, whitespace: true }, { name: pool.properties[0], attribute: true }); - pool.name = pool.properties[0]; - pool.readonly = ((pool.properties[7].toLowerCase() == "on" || pool.boot && zfsmanager.configuration.zfs.storagepool.bootlockdown) ? true : false); - pool.size = FnFormatBytes({ base2: true, decimals: 2, value: pool.properties[3] }); - pool.root = (zfsmanager.zfs.storagepool.root && pool.properties[0] == zfsmanager.zfs.storagepool.root ? true : false); - pool.upgrade = ($.isNumeric(pool.properties[8] && !pool.boot) ? true : false); - pool.version = pool.properties[10]; - - //Upgrade available if a requested feature flag returns false - if (!pool.boot) { - for (var x in pool.feature) { - if (!pool.feature[x] && !pool.upgrade) { - pool.upgrade = true; - } - } - } - - $("#modals-storagepool-" + pool.id).remove(); - $("#modals").append(`
    `); - - pool.output = ` - - - - Name:` + pool.name + (pool.readonly ? ` ` : (pool.altroot ? ` ` : ``)) + ` - - Health:
    ` + pool.health + `
    - - - Size:
    ` + pool.size + `
    - - - Allocated:
    ` + pool.allocated + `
    - - - Free:
    ` + pool.free + `
    - - - Fragmentation:
    ` + pool.fragmentation + ` %
    - - - Usage: -
    -
    - ` + pool.allocatedpercent + `% Allocated -
    -
    - ` + pool.freepercent + `% Free -
    -
    - - - Upgrade Available: - ` + (pool.upgrade ? `Yes` : `No`) + ` - - - `; - - //Actions menu - pool.actionsmenu.items = { - itemconfigure: [], - itemconfiguredivider: function () { - if (this.itemconfigure.length > 0 && (this.itemconfigurefeatures.length > 0 || this.item.length > 0)) { - this.itemconfigure.push(this.divider); - } - }, - itemconfigurefeatures: [], - itemconfigurefeaturesdivider: function () { - if (this.itemconfigurefeatures.length > 0 && this.item.length > 0) { - this.itemconfigurefeatures.push(this.divider); - } - }, - item: [], - divider: `` - }; - pool.actionsmenu.display = function () { - if ((this.items.itemconfigure.length + this.items.itemconfigurefeatures.length + this.items.item.length) > 0) { - this.items.itemconfiguredivider(); - this.items.itemconfigurefeaturesdivider(); - - return this.header + this.items.itemconfigure.join("\n") + this.items.itemconfigurefeatures.join("\n") + this.items.item.join("\n") + this.footer; - } else { - return ""; - } - }; - pool.actionsmenu.header = ` - - `; - - //Configure Storage Pool - pool.actionsmenu.items.itemconfigure.push(`
  • Configure Storage Pool
  • `); - - //Configure Storage Pool Features - pool.actionsmenu.items.itemconfigurefeatures.push(`
  • Configure Storage Pool Features
  • `); - - //Export Storage Pool - if (!pool.boot && !pool.root) { - pool.actionsmenu.items.item.push(`
  • Export Storage Pool
  • `); - - pool.actionsmenu.register.export = true; - } - - //Destroy Storage Pool - if (!pool.readonly && !pool.boot && !pool.root) { - pool.actionsmenu.items.item.push(`
  • Destroy Storage Pool
  • `); - - pool.actionsmenu.register.destroy = true; - } - - pool.output += `` + pool.actionsmenu.display() + ``; - - if (zfsmanager.configuration.zfs.storagepool.activetab == 2) { - pool.activetab = "snapshots"; - } else if (zfsmanager.configuration.zfs.storagepool.activetab == 3) { - pool.activetab = "status"; - } - - pool.output += ` - - - -
    -
    -
    - - - - - - \x3Cscript nonce="1t55lZ7tzuKTreHVNwE66Ox32Mc="> - //Set active tab - $("#tab-storagepool-` + pool.activetab + `-` + pool.id + `").tab("show"); - - $("#btn-storagepool-filesystems-refresh-` + pool.id + `").on("click", function () { - $("#btn-storagepool-filesystems-create-` + pool.id + `").prop("disabled", true); - $("#btn-storagepool-filesystems-refresh-` + pool.id + `").prop("disabled", true); - - $("[id^=btn-storagepool-filesystem-dropdown-` + pool.id + `]").addClass("disabled"); - $("#paneltitle-storagepool-filesystems-` + pool.id + `").addClass("hidden"); - $("#spinner-storagepool-filesystems-` + pool.id + `").removeClass("hidden"); - - FnStoragePoolRefresh({ name: "` + pool.name + `", id: "` + pool.id + `" }, { storagepool: true, filesystems: true, snapshots: false, status: false }); - }); - - $("#btn-storagepool-snapshots-refresh-` + pool.id + `").on("click", function () { - $("#btn-storagepool-snapshots-create-` + pool.id + `").prop("disabled", true); - $("#btn-storagepool-snapshots-refresh-` + pool.id + `").prop("disabled", true); - - $("[id^=btn-storagepool-snapshot-dropdown-` + pool.id + `]").addClass("disabled"); - $("#paneltitle-storagepool-snapshots-` + pool.id + `").addClass("hidden"); - $("#spinner-storagepool-snapshots-` + pool.id + `").removeClass("hidden"); - - FnStoragePoolRefresh({ name: "` + pool.name + `", id: "` + pool.id + `" }, { storagepool: true, filesystems: false, snapshots: true, status: false }); - }); - - $("#btn-storagepool-status-refresh-` + pool.id + `").on("click", function () { - FnStoragePoolRefreshAutoDisable({ name: "` + pool.name + `", id: "` + pool.id + `" }); - - $(this).text("Refresh").prop("disabled", true); - $("#btn-storagepool-status-refresh-auto-` + pool.id + `").prop("disabled", true).parent().removeClass("open");; - - $("[id^=btn-storagepool-status-dropdown-][id$=` + pool.id + `]").addClass("disabled"); - $("#paneltitle-storagepool-status-` + pool.id + `").addClass("hidden"); - $("#spinner-storagepool-status-` + pool.id + `").removeClass("hidden"); - $("#spinner-storagepool-status-0-` + pool.id + `").removeClass("hidden"); - - FnStoragePoolRefresh({ name: "` + pool.name + `", id: "` + pool.id + `" }, { storagepool: true, filesystems: false, snapshots: false, status: true }); - }); - - $("#dropdown-storagepool-status-refresh-` + pool.id + `").on("click", "li a", function () { - FnStoragePoolRefreshAutoDisable({ name: "` + pool.name + `", id: "` + pool.id + `" }); - $("#btn-storagepool-status-refresh-` + pool.id + `").click(); - - if ($(this).attr("data-pool-refresh-interval") > 0) { - let statusrefreshtimer` + _index + ` = setInterval(function () { - $("#btn-storagepool-status-refresh-` + pool.id + `").prop("disabled", true); - $("#btn-storagepool-status-refresh-auto-` + pool.id + `").prop("disabled", true).parent().removeClass("open"); - - $("[id^=btn-storagepool-status-dropdown-][id$=` + pool.id + `]").addClass("disabled"); - $("#paneltitle-storagepool-status-` + pool.id + `").addClass("hidden"); - $("#spinner-storagepool-status-` + pool.id + `").removeClass("hidden"); - $("#spinner-storagepool-status-0-` + pool.id + `").removeClass("hidden"); - - setTimeout(function() { - FnStoragePoolRefresh({ name: "` + pool.name + `", id: "` + pool.id + `" }, { storagepool: true, filesystems: false, snapshots: false, status: true }); - }, 200); - }, ($(this).attr("data-pool-refresh-interval") + "000")); - - zfsmanager.zfs.storagepool.refreshid.push(statusrefreshtimer` + _index + `); - - $("#tr-storagepool-` + pool.id + `").attr("data-pool-refresh-id", statusrefreshtimer` + _index + `); - $("#btn-storagepool-status-refresh-` + pool.id + `").text("Refresh: " + $(this).attr("data-pool-refresh-interval") + "s"); - - FnConsole.log[2]("Storage Pools, Refresh, Auto: Enabled, Pool: ` + pool.name + `"); - } - }); - \x3C/script> - - `; - - $("#table-storagepools").append(pool.output); - - $("#progressbar-storagepool-allocated-" + pool.id).css("width", pool.allocatedpercent + "%"); - $("#progressbar-storagepool-free-" + pool.id).css("width", pool.freepercent + "%"); - - //Register storage pool modals - FnModalStoragePoolConfigure({ name: pool.name, id: pool.id, boot: pool.boot, guid: pool.guid, readonly: false, root: pool.root }); - FnModalStoragePoolConfigureFeatures({ name: pool.name, id: pool.id, boot: pool.boot, readonly: false }); - if (pool.actionsmenu.register.destroy) { - FnModalStoragePoolDestroy({ name: pool.name, id: pool.id, altroot: pool.altroot }); - } - if (pool.actionsmenu.register.export) { - FnModalStoragePoolExport({ name: pool.name, id: pool.id, altroot: pool.altroot, readonly: pool.readonly }); - } - }); - - $("#btn-storagepools-refresh").prop("disabled", false); - - FnCockpitElementsUpdate(); -} - -function FnStoragePoolsImportableBlockDeviceGet(pools = { destroyed: false }) { - let process = { - command: [ "/bin/sh", ((zfsmanager.user.admin || !zfsmanager.user.name) ? "pkexec /sbin/zpool import" : ""), "-d", "/dev", (pools.destroyed ? " -D" : ""), "2> /dev/null | /bin/grep -E 'pool:\| id:\|state:' | tr '\\\n' ','" ] - }; - - FnConsole.log[2]("Storage Pools, Importable, Block Device, Get: In Progress"); - FnConsole.log[2](FnConsoleCommand({ command: process.command })); - - return cockpit.spawn(process.command, { err: "out" }) - .done(function () { - FnConsole.log[1]("Storage Pools, Importable, Block Device, Get: Success"); - }) - .fail(function (message, data) { - FnConsole.warn("Storage Pools, Importable, Block Device, Get: Failed, Message: " + (data ? data : message)); - }); -} - -function FnStoragePoolsImportableDiskGet(pools = { destroyed: false }) { - let process = { - command: [ "/bin/sh", ((zfsmanager.user.admin || !zfsmanager.user.name) ? "pkexec /sbin/zpool import" : ""), "-d", "/dev/disk/by-id", (pools.destroyed ? " -D" : ""), "2> /dev/null | /bin/grep -E 'pool:\| id:\|state:' | tr '\\\n' ','" ] - }; - - FnConsole.log[2]("Storage Pools, Importable, Disk / WWN, Get: In Progress"); - FnConsole.log[2](FnConsoleCommand({ command: process.command })); - - return cockpit.spawn(process.command, { err: "out"}) - .done(function () { - FnConsole.log[1]("Storage Pools, Importable, Disk / WWN, Get: Success"); - }) - .fail(function (message, data) { - FnConsole.warn("Storage Pools, Importable, Disk / WWN, Get: Failed, Message: " + (data ? data : message)); - }); -} - -function FnStoragePoolsImportableGet(pools = { destroyed: false }) { - let replacement = { - regexp: [ - { pattern: /^(?: )+pool\:/gi, replacement: "pool\:" }, - { pattern: /,(?: )+pool\:/gi, replacement: "\npool\:" }, - { pattern: /,$/g, replacement: "" }, - { pattern: /pool\: /gi, replacement: "" }, - { pattern: /id\: /gi, replacement: "" }, - { pattern: /state\: /gi, replacement: "" }, - { pattern: /,(?: )+/g, replacement: "," } - ] - }; - - pools.importable = { - blockdevice: [], - disk: [], - path: [], - vdev: [] - }; - - $("#listgroup-storagepools-import-storagepools").empty().append(`
  • `); - - FnConsole.log[2]("Storage Pools, Importable, Get: In Progress"); - - FnStoragePoolsImportableDiskGet({ destroyed: pools.destroyed }) - .done(function (data) { - FnConsole.log[4](FnConsoleVerbose({ data: data, message: "Storage Pools, Importable, Disk / WWN, Get:" })); - - if (/no pools available to import/gi.test(data) == false) { - pools.importable.disk = replacement.regexp.reduce((d, r) => d.replace(r.pattern, r.replacement), data).split(/\n/g).filter(v => v); - } - - FnStoragePoolsImportableHardwarePathGet({ destroyed: pools.destroyed }) - .done(function (_data) { - FnConsole.log[4](FnConsoleVerbose({ data: _data, message: "Storage Pools, Importable, Hardware Path, Get:" })); - - if (/no pools available to import/gi.test(_data) == false) { - pools.importable.path = replacement.regexp.reduce((d, r) => d.replace(r.pattern, r.replacement), _data).split(/\n/g).filter(v => v); - } - - FnStoragePoolsImportableVirtualDeviceMappingGet({ destroyed: pools.destroyed }) - .done(function (__data) { - FnConsole.log[4](FnConsoleVerbose({ data: __data, message: "Storage Pools, Importable, Virtual Device Mapping, Get:" })); - - if (/no pools available to import/gi.test(__data) == false) { - pools.importable.vdev = replacement.regexp.reduce((d, r) => d.replace(r.pattern, r.replacement), __data).split(/\n/g).filter(v => v); - } - - FnStoragePoolsImportableBlockDeviceGet({ destroyed: pools.destroyed }) - .done(function (___data) { - FnConsole.log[4](FnConsoleVerbose({ data: ___data, message: "Storage Pools, Importable, Block Device, Get:" })); - - if (/no pools available to import/gi.test(___data) == false) { - pools.importable.blockdevice = replacement.regexp.reduce((d, r) => d.replace(r.pattern, r.replacement), ___data).split(/\n/g).filter(v => v); - - pools.importable.blockdevice.sort().forEach((_value, _index) => { - let pool = { - healthstatus: "", - properties: [], - id: { - blockdevice: true, - disk: false, - path: false, - vdev: false, - }, - idtext: ["Block Device"] - }; - - pool.properties = _value.split(/,/g).filter(v => v); - pool.name = pool.properties[0].trim(); - pool.guid = pool.properties[1].trim(); - pool.health = pool.properties[2].trim(); - - pools.importable.disk.filter(v => { if (v.match(pool.name) && !pool.id.disk) { pool.id.disk = true; pool.idtext.push("Disk / WWN"); } }); - pools.importable.path.filter(v => { if (v.match(pool.name) && !pool.id.path) { pool.id.path = true; pool.idtext.push("Hardware Path"); } }); - pools.importable.vdev.filter(v => { if (v.match(pool.name) && !pool.id.vdev) { pool.id.vdev = true; pool.idtext.push("Virtual Device Mapping"); } }); - - - if (/ONLINE/g.test(pool.health) == false) { - pool.healthstatus = ` `; - - $("#helpblock-storagepools-import-storagepools-warning").html("One or more storage pools are in an unhealthy state." + pool.healthstatus); - } - - pool.output = ` - - `; - - $("#listgroup-storagepools-import-storagepools").append(pool.output); - }); - } - - setTimeout(function () { - $("#spinner-storagepools-import-storagepools").remove(); - $("#listgroup-storagepools-import-storagepools > li").removeClass("hidden"); - if ($("#helpblock-storagepools-import-storagepools-warning").text()) { - $("#helpblock-storagepools-import-storagepools-warning").removeClass("hidden"); - } - - if ($("#listgroup-storagepools-import-storagepools > li").length == 0) { - pools.output = ` -
  • - -
  • - `; - - $("#listgroup-storagepools-import-storagepools").append(pools.output); - } - }, 200); - - FnConsole.log[1]("Storage Pools, Importable, Get: Success"); - }) - .fail(function (___message, ___data) { - if (/no pools available to import/gi.test(___data) == false) { - FnConsole.warn("Storage Pools, Importable, Get: Failed, Message: " + (___data ? ___data : ___message)); - } - - FnStoragePoolsImportableGetFail({ destroyed: pools.destroyed }); - }); - }) - .fail(function (__message, __data) { - if (/no pools available to import/gi.test(__data) == false) { - FnConsole.warn("Storage Pools, Importable, Get: Failed, Message: " + (__data ? __data : __message)); - } - - FnStoragePoolsImportableGetFail({ destroyed: pools.destroyed }); - }); - }) - .fail(function (_message, _data) { - if (/no pools available to import/gi.test(_data) == false) { - FnConsole.warn("Storage Pools, Importable, Get: Failed, Message: " + (_data ? _data : _message)); - } - - FnStoragePoolsImportableGetFail({ destroyed: pools.destroyed }); - }); - }) - .fail(function (message, data) { - if (/no pools available to import/gi.test(data) == false) { - FnConsole.warn("Storage Pools, Importable, Get: Failed, Message: " + (data ? data : message)); - } - - FnStoragePoolsImportableGetFail({ destroyed: pools.destroyed }); - }); -} - -function FnStoragePoolsImportableGetFail(pools = { destroyed: false }) { - setTimeout(function () { - $("#spinner-storagepools-import-storagepools").remove(); - $("#listgroup-storagepools-import-storagepools > li").removeClass("hidden"); - - if ($("#listgroup-storagepools-import-storagepools > li").length == 0) { - pools.output = ` -
  • - -
  • - `; - - $("#listgroup-storagepools-import-storagepools").append(pools.output); - } - }, 200); -} - -function FnStoragePoolsImportableHardwarePathGet(pools = { destroyed: false }) { - let process = { - command: ["/bin/sh", ((zfsmanager.user.admin || !zfsmanager.user.name) ? "pkexec /sbin/zpool import" : ""), "-d", "/dev/disk/by-path", (pools.destroyed ? " -D" : ""), " 2> /dev/null | /bin/grep -E 'pool:\| id:\|state:' | tr '\\\n' ','" ] - }; - - FnConsole.log[2]("Storage Pools, Importable, Hardware Path, Get: In Progress"); - FnConsole.log[2](FnConsoleCommand({ command: process.command })); - - return cockpit.spawn(process.command, { err: "out" }) - .done(function () { - FnConsole.log[1]("Storage Pools, Importable, Hardware Path, Get: Success"); - }) - .fail(function (message, data) { - FnConsole.warn("Storage Pools, Importable, Hardware Path, Get: Failed, Message: " + (data ? data : message)); - }); -} - -function FnStoragePoolsImportableVirtualDeviceMappingGet(pools = { destroyed: false }) { - let process = { - command: ["/bin/sh", ((zfsmanager.user.admin || !zfsmanager.user.name) ? "pkexec /sbin/zpool import" : ""), "-d", "/dev/disk/by-vdev", (pools.destroyed ? " -D" : ""), "2> /dev/null | /bin/grep -E 'pool:\| id:\|state:' | tr '\\\n' ','"] - }; - - FnConsole.log[2]("Storage Pools, Importable, Virtual Device Mapping, Get: In Progress"); - FnConsole.log[2](FnConsoleCommand({ command: process.command })); - - return cockpit.spawn(process.command, { err: "out" }) - .done(function () { - FnConsole.log[1]("Storage Pools, Importable, Virtual Device Mapping, Get: Success"); - }) - .fail(function (message, data) { - FnConsole.warn("Storage Pools, Importable, Virtual Device Mapping, Get: Failed, Message: " + (data ? data : message)); - }); -} - -function FnStoragePoolsSystemReservedGet() { - let filesystems = { - id: [] - }; - let process = { - command: ["/sbin/zfs", "list", "-H", "-o", "name,mountpoint", "-d", "3"] - }; - - FnConsole.log[2]("Storage Pools, System Reserved, Get: In Progress"); - FnConsole.log[3](FnConsoleCommand({ command: process.command })); - - return cockpit.spawn(process.command, { err: "out" }) - .done((data) => { - FnConsole.log[4](FnConsoleVerbose({ data: data, message: "Storage Pools, System Reserved, Get:" })); - - filesystems.id = data.split(/\n/g).filter(v => v); - - filesystems.id.forEach((_value, _index) => { - let filesystem = { - properties: _value.split(/\t/g).filter(v => v) - }; - - filesystem.name = filesystem.properties[0]; - filesystem.mountpoint = filesystem.properties[1].trim(); - - if (filesystem.mountpoint == "/boot" && !zfsmanager.zfs.storagepool.boot) { - zfsmanager.zfs.storagepool.boot = filesystem.name.split("/")[0]; - } else if (filesystem.mountpoint == "/" && !zfsmanager.zfs.storagepool.root) { - zfsmanager.zfs.storagepool.root = filesystem.name.split("/")[0]; - } - }); - - FnConsole.log[1]("Storage Pools, System Reserved, Get: Success"); - }) - .fail((message, data) => { - FnConsole.warn("Storage Pools, System Reserved, Get: Failed, Message: " + (data ? data : message)); - }); -} - -function FnStoragePoolsTemporaryGet() { - let process = { - command: ["/sbin/zpool", "list", "-H", "-o", "name,readonly,altroot"] - }; - - FnConsole.log[2]("Storage Pools, Temporary, Get: In Progress"); - FnConsole.log[3](FnConsoleCommand({ command: process.command })); - - return cockpit.spawn(process.command, { err: "out" }) - .done(function () { - FnConsole.log[1]("Storage Pools, Temporary, Get: Success"); - }) - .fail(function (message, data) { - FnConsole.warn("Storage Pools, Temporary, Get: Failed, Message: " + (data ? data : message)); - }); -} - -//#endregion - -//#region Storage Pool - -function FnStoragePoolAlternativeRootGet(pool = { name, id }, modal = { name, id }) { - let process = { - command: ["/sbin/zpool", "list", "-H", "-o", "altroot", pool.name] - }; - - FnConsole.log[2]("Storage Pools, Alternative Root, Get: In Progress, Pool: " + pool.name); - FnConsole.log[3](FnConsoleCommand({ command: process.command })); - - return cockpit.spawn(process.command, { err: "out" }) - .done(function (data) { - FnConsole.log[4](FnConsoleVerbose({ data: data, message: "Storage Pools, Alternative Root, Get:" })); - - data = data.replace(/\n+/g, ""); - - $("#input-" + modal.name + "-mountpoint-" + modal.id).attr("data-field-altroot", data); - - FnConsole.log[1]("Storage Pools, Alternative Root, Get: Success, Pool: " + pool.name); - }) - .fail(function (message, data) { - FnConsole.warn("Storage Pools, Alternative Root, Get: Failed, Pool: " + pool.name + ", Message: " + (data ? data : message)); - }); -} - -function FnStoragePoolClear(pool = { name, id }, modal = { name, id }) { - let process = { - command: ["/sbin/zpool", "clear", pool.name] - }; - - FnConsole.log[2]("Storage Pools, Clear Errors: In Progress, Pool: " + pool.name); - FnConsole.log[3](FnConsoleCommand({ command: process.command })); - - $("#spinner-" + modal.name + "-" + modal.id + " span").text("Clearing storage pool errors..."); - - return cockpit.spawn(process.command, { err: "out", superuser: "require" }) - .done(function () { - FnDisplayAlert({ status: "success", title: "Storage Pool errors successfully cleared", description: pool.name, breakword: false }, { name: "storagepool-clear", id: pool.id, timeout: 4 }); - - FnConsole.log[1]("Storage Pools, Clear Errors: Success, Pool: " + pool.name); - }) - .fail(function (message, data) { - FnDisplayAlert({ status: "danger", title: "Storage Pool errors could not be cleared", description: pool.name, breakword: false }, { name: "storagepool-clear", id: pool.id, timeout: 4 }); - - FnConsole.warn("Storage Pools, Clear Errors: Failed, Pool: " + pool.name + ", Message: " + (data ? data : message)); - }) - .finally(function () { - $("#modal-" + modal.name + "-" + modal.id).modal("hide"); - - setTimeout(function () { - FnStoragePoolRefresh({ name: pool.name, id: pool.id }, { storagepool: true, filesystems: false, snapshots: false, status: true }); - }, 200); - }); -} - -function FnStoragePoolConfigurationFeaturesDisabledGet(pool = { name, id }, modal = { name, id }) { - let process = { - command: ["/sbin/zpool", "get", "feature@allocation_classes,feature@async_destroy,feature@bookmark_v2,feature@bookmarks,feature@device_removal,feature@edonr,feature@embedded_data,feature@empty_bpobj,feature@enabled_txg,feature@encryption,feature@extensible_dataset,feature@filesystem_limits,feature@hole_birth,feature@large_blocks,feature@large_dnode,feature@lz4_compress,feature@multi_vdev_crash_dump,feature@obsolete_counts,feature@project_quota,feature@resilver_defer,feature@sha512,feature@skein,feature@spacemap_histogram,feature@spacemap_v2,feature@userobj_accounting,feature@zpool_checkpoint", "-H", "-o", "property,value", pool.name] - }; - - FnConsole.log[2]("Storage Pools, Configuration, Features, Disabled, Get: In Progress, Pool: " + pool.name); - FnConsole.log[3](FnConsoleCommand({ command: process.command })); - - return cockpit.spawn(process.command, { err: "out" }) - .done(function (data) { - FnConsole.log[4](FnConsoleVerbose({ data: data, message: "Storage Pools, Configuration, Features, Disabled, Get:" })); - - pool.configuration = data.replace(/\t+/g, "\u22C5").split(/\n/g).filter(v => v); - pool.disabled = []; - - pool.configuration.forEach((_value, _index) => { - _value = _value.split("\u22C5"); - - pool.properties = { - property: _value[0].toLowerCase(), - value: _value[1].toLowerCase() - }; - - switch (pool.properties.property) { - case "feature@allocation_classes": - if (/disabled/gi.test(pool.properties.value)) { - pool.disabled.push("Allocation Classes"); - } - break; - case "feature@async_destroy": - if (/disabled/gi.test(pool.properties.value)) { - pool.disabled.push("Asynchronous Destroy"); - } - break; - case "feature@bookmark_v2": - if (/disabled/gi.test(pool.properties.value)) { - pool.disabled.push("Bookmarks Version 2"); - } - break; - case "feature@bookmarks": - if (/disabled/gi.test(pool.properties.value)) { - pool.disabled.push("Bookmarks"); - } - break; - case "feature@device_removal": - if (/disabled/gi.test(pool.properties.value)) { - pool.disabled.push("Device Removal"); - } - break; - case "feature@edonr": - if (/disabled/gi.test(pool.properties.value)) { - pool.disabled.push("Edon-R"); - } - break; - case "feature@embedded_data": - if (/disabled/gi.test(pool.properties.value)) { - pool.disabled.push("Embedded Data"); - } - break; - case "feature@empty_bpobj": - if (/disabled/gi.test(pool.properties.value)) { - pool.disabled.push("Empty Block Pointer Objects"); - } - break; - case "feature@enabled_txg": - if (/disabled/gi.test(pool.properties.value)) { - pool.disabled.push("Transaction Group Accounting"); - } - break; - case "feature@encryption": - if (/disabled/gi.test(pool.properties.value)) { - pool.disabled.push("Encryption"); - } - break; - case "feature@extensible_dataset": - if (/disabled/gi.test(pool.properties.value)) { - pool.disabled.push("Extensible Dataset"); - } - break; - case "feature@filesystem_limits": - if (/disabled/gi.test(pool.properties.value)) { - pool.disabled.push("File System Limits"); - } - break; - case "feature@hole_birth": - if (/disabled/gi.test(pool.properties.value)) { - pool.disabled.push("Hole Birth"); - } - break; - case "feature@large_blocks": - if (/disabled/gi.test(pool.properties.value)) { - pool.disabled.push("Large Blocks"); - } - break; - case "feature@large_dnode": - if (/disabled/gi.test(pool.properties.value)) { - pool.disabled.push("Large DNode"); - } - break; - case "feature@lz4_compress": - if (/disabled/gi.test(pool.properties.value)) { - pool.disabled.push("LZ4 Compression"); - } - break; - case "feature@multi_vdev_crash_dump": - if (/disabled/gi.test(pool.properties.value)) { - pool.disabled.push("Multi Virtual Device Crash Dump"); - } - break; - case "feature@obsolete_counts": - if (/disabled/gi.test(pool.properties.value)) { - pool.disabled.push("Obsolete Counts"); - } - break; - case "feature@project_quota": - if (/disabled/gi.test(pool.properties.value)) { - pool.disabled.push("Project Quota"); - } - break; - case "feature@resilver_defer": - if (/disabled/gi.test(pool.properties.value)) { - pool.disabled.push("Resilver Defer"); - } - break; - case "feature@sha512": - if (/disabled/gi.test(pool.properties.value)) { - pool.disabled.push("SHA-512"); - } - break; - case "feature@skein": - if (/disabled/gi.test(pool.properties.value)) { - pool.disabled.push("Skein"); - } - break; - case "feature@spacemap_histogram": - if (/disabled/gi.test(pool.properties.value)) { - pool.disabled.push("Space Map Histogram"); - } - break; - case "feature@spacemap_v2": - if (/disabled/gi.test(pool.properties.value)) { - pool.disabled.push("Space Map Version 2"); - } - break; - case "feature@userobj_accounting": - if (/disabled/gi.test(pool.properties.value)) { - pool.disabled.push("User Object Accounting"); - } - break; - case "feature@zpool_checkpoint": - if (/disabled/gi.test(pool.properties.value)) { - pool.disabled.push("Checkpoint"); - } - break; - } - }); - - $("#ul-" + modal.name + "-features-" + modal.id).append(`
  • ` + pool.disabled.sort().join(`
  • \n
  • `) + `
  • `); - - FnConsole.log[1]("Storage Pools, Configuration, Features, Disabled, Get: Success, Pool: " + pool.name); - - }) - .fail(function (message, data) { - FnConsole.warn("Storage Pools, Configuration, Features, Disabled, Get: In Progress, Pool: " + pool.name + " , Message: " + (data ? data : message)); - }); -} - -function FnStoragePoolConfigurationFeaturesGet(pool = { name, id, boot: false }, modal = { name, id }) { - let process = { - command: ["/sbin/zpool", "get", "readonly,feature@allocation_classes,feature@async_destroy,feature@bookmark_v2,feature@bookmarks,feature@device_removal,feature@edonr,feature@embedded_data,feature@empty_bpobj,feature@enabled_txg,feature@encryption,feature@extensible_dataset,feature@filesystem_limits,feature@hole_birth,feature@large_blocks,feature@large_dnode,feature@lz4_compress,feature@multi_vdev_crash_dump,feature@obsolete_counts,feature@project_quota,feature@resilver_defer,feature@sha512,feature@skein,feature@spacemap_histogram,feature@spacemap_v2,feature@userobj_accounting,feature@zpool_checkpoint", "-H", "-o", "property,value", pool.name] - }; - - pool.readonly = false; - - FnConsole.log[2]("Storage Pools, Configuration, Features, Get: In Progress, Pool: " + pool.name); - FnConsole.log[3](FnConsoleCommand({ command: process.command })); - - return cockpit.spawn(process.command, { err: "out" }) - .done(function (data) { - FnConsole.log[4](FnConsoleVerbose({ data: data, message: "Storage Pools, Configuration, Features, Get:" })); - - pool.configuration = data.replace(/\t+/g, "\u22C5").split(/\n/g).filter(v => v); - - pool.configuration.forEach((_value, _index) => { - _value = _value.split("\u22C5"); - - pool.properties = { - property: _value[0].toLowerCase(), - value: _value[1].toLowerCase() - }; - - switch (pool.properties.property) { - case "feature@allocation_classes": - if (/active|enabled/gi.test(pool.properties.value) && !$("#switch-" + modal.name + "-allocation_classes-" + modal.id + " input").prop("checked")) { - $("#switch-" + modal.name + "-allocation_classes-" + modal.id + " input").click(); - } - - $("#switch-" + modal.name + "-allocation_classes-" + modal.id).attr("data-field-value", pool.properties.value); - - if (pool.readonly || /active|enabled/gi.test(pool.properties.value)) { - $("#switch-" + modal.name + "-allocation_classes-" + modal.id + " input").prop("disabled", true); - } - break; - case "feature@async_destroy": - if (/active|enabled/gi.test(pool.properties.value) && !$("#switch-" + modal.name + "-async_destroy-" + modal.id + " input").prop("checked")) { - $("#switch-" + modal.name + "-async_destroy-" + modal.id + " input").click(); - } - - $("#switch-" + modal.name + "-async_destroy-" + modal.id).attr("data-field-value", pool.properties.value); - - if (pool.readonly || /active|enabled/gi.test(pool.properties.value)) { - $("#switch-" + modal.name + "-async_destroy-" + modal.id + " input").prop("disabled", true); - } - break; - case "feature@bookmark_v2": - if (/active|enabled/gi.test(pool.properties.value) && !$("#switch-" + modal.name + "-bookmark_v2-" + modal.id + " input").prop("checked")) { - $("#switch-" + modal.name + "-bookmark_v2-" + modal.id + " input").click(); - } - - $("#switch-" + modal.name + "-bookmark_v2-" + modal.id).attr("data-field-value", pool.properties.value); - - if (pool.readonly || /active|enabled/gi.test(pool.properties.value)) { - $("#switch-" + modal.name + "-bookmark_v2-" + modal.id + " input").prop("disabled", true); - } - break; - case "feature@bookmarks": - if (/active|enabled/gi.test(pool.properties.value) && !$("#switch-" + modal.name + "-bookmarks-" + modal.id + " input").prop("checked")) { - $("#switch-" + modal.name + "-bookmarks-" + modal.id + " input").click(); - } - - $("#switch-" + modal.name + "-bookmarks-" + modal.id).attr("data-field-value", pool.properties.value); - - if (pool.readonly || /active|enabled/gi.test(pool.properties.value)) { - $("#switch-" + modal.name + "-bookmarks-" + modal.id + " input").prop("disabled", true); - } - break; - case "feature@device_removal": - if (/active|enabled/gi.test(pool.properties.value) && !$("#switch-" + modal.name + "-device_removal-" + modal.id + " input").prop("checked")) { - $("#switch-" + modal.name + "-device_removal-" + modal.id + " input").click(); - } - - $("#switch-" + modal.name + "-device_removal-" + modal.id).attr("data-field-value", pool.properties.value); - - if (pool.readonly || /active|enabled/gi.test(pool.properties.value)) { - $("#switch-" + modal.name + "-device_removal-" + modal.id + " input").prop("disabled", true); - } - break; - case "feature@edonr": - if (/active|enabled/gi.test(pool.properties.value) && !$("#switch-" + modal.name + "-edonr-" + modal.id + " input").prop("checked")) { - $("#switch-" + modal.name + "-edonr-" + modal.id + " input").click(); - } - - $("#switch-" + modal.name + "-edonr-" + modal.id).attr("data-field-value", pool.properties.value); - - if (pool.readonly || /active|enabled/gi.test(pool.properties.value)) { - $("#switch-" + modal.name + "-edonr-" + modal.id + " input").prop("disabled", true); - } - break; - case "feature@embedded_data": - if (/active|enabled/gi.test(pool.properties.value) && !$("#switch-" + modal.name + "-embedded_data-" + modal.id + " input").prop("checked")) { - $("#switch-" + modal.name + "-embedded_data-" + modal.id + " input").click(); - } - - $("#switch-" + modal.name + "-embedded_data-" + modal.id).attr("data-field-value", pool.properties.value); - - if (pool.readonly || /active|enabled/gi.test(pool.properties.value)) { - $("#switch-" + modal.name + "-embedded_data-" + modal.id + " input").prop("disabled", true); - } - break; - case "feature@empty_bpobj": - if (/active|enabled/gi.test(pool.properties.value) && !$("#switch-" + modal.name + "-empty_bpobj-" + modal.id + " input").prop("checked")) { - $("#switch-" + modal.name + "-empty_bpobj-" + modal.id + " input").click(); - } - - $("#switch-" + modal.name + "-empty_bpobj-" + modal.id).attr("data-field-value", pool.properties.value); - - if (pool.readonly || /active|enabled/gi.test(pool.properties.value)) { - $("#switch-" + modal.name + "-empty_bpobj-" + modal.id + " input").prop("disabled", true); - } - break; - case "feature@enabled_txg": - if (/active|enabled/gi.test(pool.properties.value) && !$("#switch-" + modal.name + "-enabled_txg-" + modal.id + " input").prop("checked")) { - $("#switch-" + modal.name + "-enabled_txg-" + modal.id + " input").click(); - } - - $("#switch-" + modal.name + "-enabled_txg-" + modal.id).attr("data-field-value", pool.properties.value); - - if (pool.readonly || /active|enabled/gi.test(pool.properties.value)) { - $("#switch-" + modal.name + "-enabled_txg-" + modal.id + " input").prop("disabled", true); - } - break; - case "feature@encryption": - if (/active|enabled/gi.test(pool.properties.value) && !$("#switch-" + modal.name + "-encryption-" + modal.id + " input").prop("checked")) { - $("#switch-" + modal.name + "-encryption-" + modal.id + " input").click(); - } - - $("#switch-" + modal.name + "-encryption-" + modal.id).attr("data-field-value", pool.properties.value); - - if (pool.readonly || /active|enabled/gi.test(pool.properties.value)) { - $("#switch-" + modal.name + "-encryption-" + modal.id + " input").prop("disabled", true); - } - break; - case "feature@extensible_dataset": - if (/active|enabled/gi.test(pool.properties.value) && !$("#switch-" + modal.name + "-extensible_dataset-" + modal.id + " input").prop("checked")) { - $("#switch-" + modal.name + "-extensible_dataset-" + modal.id + " input").click(); - } - - $("#switch-" + modal.name + "-extensible_dataset-" + modal.id).attr("data-field-value", pool.properties.value); - - if (pool.readonly || /active|enabled/gi.test(pool.properties.value)) { - $("#switch-" + modal.name + "-extensible_dataset-" + modal.id + " input").prop("disabled", true); - } - break; - case "feature@filesystem_limits": - if (/active|enabled/gi.test(pool.properties.value) && !$("#switch-" + modal.name + "-filesystem_limits-" + modal.id + " input").prop("checked")) { - $("#switch-" + modal.name + "-filesystem_limits-" + modal.id + " input").click(); - } - - $("#switch-" + modal.name + "-filesystem_limits-" + modal.id).attr("data-field-value", pool.properties.value); - - if (pool.readonly || /active|enabled/gi.test(pool.properties.value)) { - $("#switch-" + modal.name + "-filesystem_limits-" + modal.id + " input").prop("disabled", true); - } - break; - case "feature@hole_birth": - if (/active|enabled/gi.test(pool.properties.value) && !$("#switch-" + modal.name + "-hole_birth-" + modal.id + " input").prop("checked")) { - $("#switch-" + modal.name + "-hole_birth-" + modal.id + " input").click(); - } - - $("#switch-" + modal.name + "-hole_birth-" + modal.id).attr("data-field-value", pool.properties.value); - - if (pool.readonly || /active|enabled/gi.test(pool.properties.value)) { - $("#switch-" + modal.name + "-hole_birth-" + modal.id + " input").prop("disabled", true); - } - break; - case "feature@large_blocks": - if (/active|enabled/gi.test(pool.properties.value) && !$("#switch-" + modal.name + "-large_blocks-" + modal.id + " input").prop("checked")) { - $("#switch-" + modal.name + "-large_blocks-" + modal.id + " input").click(); - } - - $("#switch-" + modal.name + "-large_blocks-" + modal.id).attr("data-field-value", pool.properties.value); - - if (pool.readonly || /active|enabled/gi.test(pool.properties.value)) { - $("#switch-" + modal.name + "-large_blocks-" + modal.id + " input").prop("disabled", true); - } - break; - case "feature@large_dnode": - if (/active|enabled/gi.test(pool.properties.value) && !$("#switch-" + modal.name + "-large_dnode-" + modal.id + " input").prop("checked")) { - $("#switch-" + modal.name + "-large_dnode-" + modal.id + " input").click(); - } - - $("#switch-" + modal.name + "-large_dnode-" + modal.id).attr("data-field-value", pool.properties.value); - - if (pool.readonly || /active|enabled/gi.test(pool.properties.value)) { - $("#switch-" + modal.name + "-large_dnode-" + modal.id + " input").prop("disabled", true); - } - break; - case "feature@lz4_compress": - if (/active|enabled/gi.test(pool.properties.value) && !$("#switch-" + modal.name + "-lz4_compress-" + modal.id + " input").prop("checked")) { - $("#switch-" + modal.name + "-lz4_compress-" + modal.id + " input").click(); - } - - $("#switch-" + modal.name + "-lz4_compress-" + modal.id).attr("data-field-value", pool.properties.value); - - if (pool.readonly || /active|enabled/gi.test(pool.properties.value)) { - $("#switch-" + modal.name + "-lz4_compress-" + modal.id + " input").prop("disabled", true); - } - break; - case "feature@multi_vdev_crash_dump": - if (/active|enabled/gi.test(pool.properties.value) && !$("#switch-" + modal.name + "-multi_vdev_crash_dump-" + modal.id + " input").prop("checked")) { - $("#switch-" + modal.name + "-multi_vdev_crash_dump-" + modal.id + " input").click(); - } - - $("#switch-" + modal.name + "-multi_vdev_crash_dump-" + modal.id).attr("data-field-value", pool.properties.value); - - if (pool.readonly || /active|enabled/gi.test(pool.properties.value)) { - $("#switch-" + modal.name + "-multi_vdev_crash_dump-" + modal.id + " input").prop("disabled", true); - } - break; - case "feature@obsolete_counts": - if (/active|enabled/gi.test(pool.properties.value) && !$("#switch-" + modal.name + "-obsolete_counts-" + modal.id + " input").prop("checked")) { - $("#switch-" + modal.name + "-obsolete_counts-" + modal.id + " input").click(); - } - - $("#switch-" + modal.name + "-obsolete_counts-" + modal.id).attr("data-field-value", pool.properties.value); - - if (pool.readonly || /active|enabled/gi.test(pool.properties.value)) { - $("#switch-" + modal.name + "-obsolete_counts-" + modal.id + " input").prop("disabled", true); - } - break; - case "feature@project_quota": - if (/active|enabled/gi.test(pool.properties.value) && !$("#switch-" + modal.name + "-project_quota-" + modal.id + " input").prop("checked")) { - $("#switch-" + modal.name + "-project_quota-" + modal.id + " input").click(); - } - - $("#switch-" + modal.name + "-project_quota-" + modal.id).attr("data-field-value", pool.properties.value); - - if (pool.readonly || /active|enabled/gi.test(pool.properties.value)) { - $("#switch-" + modal.name + "-project_quota-" + modal.id + " input").prop("disabled", true); - } - break; - case "feature@resilver_defer": - if (/active|enabled/gi.test(pool.properties.value) && !$("#switch-" + modal.name + "-resilver_defer-" + modal.id + " input").prop("checked")) { - $("#switch-" + modal.name + "-resilver_defer-" + modal.id + " input").click(); - } - - $("#switch-" + modal.name + "-resilver_defer-" + modal.id).attr("data-field-value", pool.properties.value); - - if (pool.readonly || /active|enabled/gi.test(pool.properties.value)) { - $("#switch-" + modal.name + "-resilver_defer-" + modal.id + " input").prop("disabled", true); - } - break; - case "feature@sha512": - if (/active|enabled/gi.test(pool.properties.value) && !$("#switch-" + modal.name + "-sha512-" + modal.id + " input").prop("checked")) { - $("#switch-" + modal.name + "-sha512-" + modal.id + " input").click(); - } - - $("#switch-" + modal.name + "-sha512-" + modal.id).attr("data-field-value", pool.properties.value); - - if (pool.readonly || /active|enabled/gi.test(pool.properties.value)) { - $("#switch-" + modal.name + "-sha512-" + modal.id + " input").prop("disabled", true); - } - break; - case "feature@skein": - if (/active|enabled/gi.test(pool.properties.value) && !$("#switch-" + modal.name + "-skein-" + modal.id + " input").prop("checked")) { - $("#switch-" + modal.name + "-skein-" + modal.id + " input").click(); - } - - $("#switch-" + modal.name + "-skein-" + modal.id).attr("data-field-value", pool.properties.value); - - if (pool.readonly || /active|enabled/gi.test(pool.properties.value)) { - $("#switch-" + modal.name + "-skein-" + modal.id + " input").prop("disabled", true); - } - break; - case "feature@spacemap_histogram": - if (/active|enabled/gi.test(pool.properties.value) && !$("#switch-" + modal.name + "-spacemap_histogram-" + modal.id + " input").prop("checked")) { - $("#switch-" + modal.name + "-spacemap_histogram-" + modal.id + " input").click(); - } - - $("#switch-" + modal.name + "-spacemap_histogram-" + modal.id).attr("data-field-value", pool.properties.value); - - if (pool.readonly || /active|enabled/gi.test(pool.properties.value)) { - $("#switch-" + modal.name + "-spacemap_histogram-" + modal.id + " input").prop("disabled", true); - } - break; - case "feature@spacemap_v2": - if (/active|enabled/gi.test(pool.properties.value) && !$("#switch-" + modal.name + "-spacemap_v2-" + modal.id + " input").prop("checked")) { - $("#switch-" + modal.name + "-spacemap_v2-" + modal.id + " input").click(); - } - - $("#switch-" + modal.name + "-spacemap_v2-" + modal.id).attr("data-field-value", pool.properties.value); - - if (pool.readonly || /active|enabled/gi.test(pool.properties.value)) { - $("#switch-" + modal.name + "-spacemap_v2-" + modal.id + " input").prop("disabled", true); - } - break; - case "feature@userobj_accounting": - if (/active|enabled/gi.test(pool.properties.value) && !$("#switch-" + modal.name + "-userobj_accounting-" + modal.id + " input").prop("checked")) { - $("#switch-" + modal.name + "-userobj_accounting-" + modal.id + " input").click(); - } - - $("#switch-" + modal.name + "-userobj_accounting-" + modal.id).attr("data-field-value", pool.properties.value); - - if (pool.readonly || /active|enabled/gi.test(pool.properties.value)) { - $("#switch-" + modal.name + "-userobj_accounting-" + modal.id + " input").prop("disabled", true); - } - break; - case "feature@zpool_checkpoint": - if (/active|enabled/gi.test(pool.properties.value) && !$("#switch-" + modal.name + "-zpool_checkpoint-" + modal.id + " input").prop("checked")) { - $("#switch-" + modal.name + "-zpool_checkpoint-" + modal.id + " input").click(); - } - - $("#switch-" + modal.name + "-zpool_checkpoint-" + modal.id).attr("data-field-value", pool.properties.value); - - if (pool.readonly || /active|enabled/gi.test(pool.properties.value)) { - $("#switch-" + modal.name + "-zpool_checkpoint-" + modal.id + " input").prop("disabled", true); - } - break; - case "readonly": //Default is off - if (pool.properties.value == "on" || pool.boot && zfsmanager.configuration.zfs.storagepool.bootlockdown || !zfsmanager.user.admin) { - pool.readonly = true; - } - break; - } - }); - - if (pool.readonly) { - $("#btn-" + modal.name + "-apply-" + modal.id).prop("disabled", true); - } - - FnConsole.log[1]("Storage Pools, Configuration, Features, Get: Success, Pool: " + pool.name); - }) - .fail(function (message, data) { - FnConsole.warn("Storage Pools, Configuration, Features, Get: Failed, Pool: " + pool.name + " , Message: " + (data ? data : message)); - }); -} - -function FnStoragePoolConfigurationGet(pool = { name, id, boot: false, root: false }, modal = { name, id }) { - let process = { - command: ["/sbin/zpool", "get", "readonly,altroot,ashift,autoexpand,autoreplace,autotrim,bootfs,cachefile,comment,delegation,failmode,guid,listsnapshots,multihost,version", "-H", "-o", "property,value", pool.name] - }; - - pool.readonly = false; - - FnConsole.log[2]("Storage Pools, Configuration, Get: In Progress, Pool: " + pool.name); - FnConsole.log[3](FnConsoleCommand({ command: process.command })); - - return cockpit.spawn(process.command, { err: "out" }) - .done(function (data) { - FnConsole.log[4](FnConsoleVerbose({ data: data, message: "Storage Pools, Configuration, Get:" })); - - pool.configuration = data.replace(/\t+/g, "\u22C5").split(/\n/g).filter(v => v); - - pool.configuration.forEach((_value, _index) => { - _value = _value.split("\u22C5"); - - pool.properties = { - property: _value[0].toLowerCase(), - value: _value[1].toLowerCase(), - valueraw: _value[1], - }; - - switch (pool.properties.property) { - case "altroot": //Default is empty (-) - if (pool.properties.valueraw && pool.properties.valueraw == "-") { - pool.properties.valueraw = ""; - } - - if (pool.properties.valueraw) { - $("#controllabel-" + modal.name + "-altroot-" + modal.id).removeClass("hidden"); - $("#div-" + modal.name + "-altroot-" + modal.id).removeClass("hidden").text(pool.properties.valueraw); - } - break; - case "ashift": //Default is 0 - pool.property = { - value: "Auto Detect", - }; - - switch (pool.properties.value) { - case "0": - pool.property.value = "Auto Detect"; - break; - case "9": - pool.property.value = "512 B"; - break; - case "12": - pool.property.value = "4 KiB"; - break; - case "13": - pool.property.value = "8 KiB"; - break; - case "14": - pool.property.value = "16 KiB"; - break; - case "15": - pool.property.value = "32 KiB"; - break; - case "16": - pool.property.value = "64 KiB"; - break; - default: - pool.property.value = "Auto Detect"; - break; - } - - $("#btnspan-" + modal.name + "-ashift-" + modal.id).text(pool.property.value).attr("data-field-value", pool.properties.value); - $("#dropdown-" + modal.name + "-ashift-" + modal.id + " li").siblings().removeClass("active"); - $("#dropdown-" + modal.name + "-ashift-" + modal.id + " li[value='" + pool.properties.valueraw + "']").addClass("active"); - - if (pool.readonly) { - $("#div-" + modal.name + "-ashift-dropdown-" + modal.id + " button").prop("disabled", true); - } - break; - case "autoexpand": //Default is off - if (pool.properties.value == "on" && !$("#switch-" + modal.name + "-autoexpand-" + modal.id + " input").prop("checked")) { - $("#switch-" + modal.name + "-autoexpand-" + modal.id + " input").click(); - } - - $("#switch-" + modal.name + "-autoexpand-" + modal.id).attr("data-field-value", pool.properties.value); - - if (pool.readonly) { - $("#switch-" + modal.name + "-autoexpand-" + modal.id + " input").prop("disabled", true); - } - break; - case "autoreplace": //Default is off - if (pool.properties.value == "on" && !$("#switch-" + modal.name + "-autoreplace-" + modal.id + " input").prop("checked")) { - $("#switch-" + modal.name + "-autoreplace-" + modal.id + " input").click(); - } - - $("#switch-" + modal.name + "-autoreplace-" + modal.id).attr("data-field-value", pool.properties.value); - - if (pool.readonly) { - $("#switch-" + modal.name + "-autoreplace-" + modal.id + " input").prop("disabled", true); - } - break; - case "autotrim": //Default is off - if (pool.properties.value == "on" && !$("#switch-" + modal.name + "-autotrim-" + modal.id + " input").prop("checked")) { - $("#switch-" + modal.name + "-autotrim-" + modal.id + " input").click(); - } - - $("#switch-" + modal.name + "-autotrim-" + modal.id).attr("data-field-value", pool.properties.value); - - if (pool.readonly) { - $("#switch-" + modal.name + "-autotrim-" + modal.id + " input").prop("disabled", true); - } - break; - case "comment": //Default is empty (-) - if (pool.properties.valueraw && pool.properties.valueraw == "-") { - pool.properties.valueraw = ""; - } - - $("#input-" + modal.name + "-comment-" + modal.id).val(pool.properties.valueraw); - $("#input-" + modal.name + "-comment-" + modal.id).attr("data-field-value", pool.properties.valueraw); - - if (pool.readonly) { - $("#input-" + modal.name + "-comment-" + modal.id).prop("disabled", true); - } - - break; - case "delegation": //Default is on - if (pool.properties.value == "off" && $("#switch-" + modal.name + "-delegation-" + modal.id + " input").prop("checked")) { - $("#switch-" + modal.name + "-delegation-" + modal.id + " input").click(); - } - - $("#switch-" + modal.name + "-delegation-" + modal.id).attr("data-field-value", pool.properties.value); - - if (pool.readonly) { - $("#switch-" + modal.name + "-delegation-" + modal.id + " input").prop("disabled", true); - } - break; - case "failmode": //Default is wait - pool.property = { - value: pool.properties.value.charAt(0).toUpperCase() + pool.properties.value.slice(1), - }; - - $("#btnspan-" + modal.name + "-failmode-" + modal.id).text(pool.property.value).attr("data-field-value", pool.properties.value); - $("#dropdown-" + modal.name + "-failmode-" + modal.id + " li").siblings().removeClass("active"); - $("#dropdown-" + modal.name + "-failmode-" + modal.id + " li[value='" + pool.properties.valueraw + "']").addClass("active"); - - if (pool.readonly) { - $("#div-" + modal.name + "-failmode-dropdown-" + modal.id + " button").prop("disabled", true); - } - break; - case "guid": - $("#div-" + modal.name + "-guid-" + modal.id).html(pool.properties.value); - break; - case "listsnapshots": //Default is off - if (pool.properties.value == "on" && !$("#switch-" + modal.name + "-listsnapshots-" + modal.id + " input").prop("checked")) { - $("#switch-" + modal.name + "-listsnapshots-" + modal.id + " input").click(); - } - - $("#switch-" + modal.name + "-listsnapshots-" + modal.id).attr("data-field-value", pool.properties.value); - - if (pool.readonly) { - $("#switch-" + modal.name + "-listsnapshots-" + modal.id + " input").prop("disabled", true); - } - break; - case "multihost": //Default is off - if (pool.properties.value == "on" && !$("#switch-" + modal.name + "-multihost-" + modal.id + " input").prop("checked")) { - $("#switch-" + modal.name + "-multihost-" + modal.id + " input").click(); - } - - $("#switch-" + modal.name + "-multihost-" + modal.id).attr("data-field-value", pool.properties.value); - - if (pool.readonly || pool.boot || pool.root) { - $("#switch-" + modal.name + "-multihost-" + modal.id + " input").prop("disabled", true); - } - break; - case "readonly": //Default is off - if (pool.properties.value == "on" || pool.boot && zfsmanager.configuration.zfs.storagepool.bootlockdown || !zfsmanager.user.admin) { - pool.readonly = true; - } - - $("#div-" + modal.name + "-readonly-" + modal.id).html((pool.properties.value == "on" ? "Yes" : "No")); - break; - } - }); - - if (pool.readonly) { - $("#btn-" + modal.name + "-apply-" + modal.id).prop("disabled", true); - } - - FnConsole.log[1]("Storage Pools, Configuration, Get: Success, Pool: " + pool.name); - }) - .fail(function (message, data) { - FnConsole.warn("Storage Pools, Configuration, Get: Failed, Pool: " + pool.name + " , Message: " + (data ? data : message)); - }); -} - -function FnStoragePoolConfigure(pool = { name, id, ashift, autoexpand, autoreplace, autotrim, comment, delegation, failmode, listsnapshots, multihost, readonly: false }, system = { hostid }, modal = { id }) { - pool.properties = { - new: [] - }; - - if (pool.ashift) { - pool.properties.new.push("ashift=" + pool.ashift); - } - if (pool.autoexpand) { - pool.properties.new.push("autoexpand=" + pool.autoexpand); - } - if (pool.autoreplace) { - pool.properties.new.push("autoreplace=" + pool.autoreplace); - } - if (pool.autotrim) { - pool.properties.new.push("autotrim=" + pool.autotrim); - } - if (pool.comment) { - if (pool.comment == "$empty") { - pool.comment = ""; - } - - pool.properties.new.push("comment=" + pool.comment); - } - if (pool.delegation) { - pool.properties.new.push("delegation=" + pool.delegation); - } - if (pool.failmode) { - pool.properties.new.push("failmode=" + pool.failmode); - } - if (pool.listsnapshots) { - pool.properties.new.push("listsnapshots=" + pool.listsnapshots); - } - if (pool.multihost) { - pool.properties.new.push("multihost=" + pool.multihost); - } - - if (system.hostid) { - FnSystemHostIdSet({ hostid: (system.hostid == "random" ? null : "\$\(hostid\)") }) - .finally(function () { - if (pool.properties.new.length > 0 && !pool.readonly) { - FnConsole.log[2]("Storage Pools, Configure: In Progress, Pool: " + pool.name); - - $("#spinner-storagepool-configure-" + pool.id + " span").text("Configuring storage pool..."); - - FnStoragePoolConfigureCommand({ name: pool.name, id: pool.id, properties: { new: pool.properties.new } }, { id: modal.id }); - } else { - modal.id.modal("hide"); - } - }); - } else { - if (pool.properties.new.length > 0 && !pool.readonly) { - FnConsole.log[2]("Storage Pools, Configure: In Progress, Pool: " + pool.name); - - $("#spinner-storagepool-configure-" + pool.id + " span").text("Configuring storage pool..."); - - FnStoragePoolConfigureCommand({ name: pool.name, id: pool.id, properties: { new: pool.properties.new } }, { id: modal.id }); - } else { - modal.id.modal("hide"); - } - } -} - -function FnStoragePoolConfigureCommand(pool = { name, id, properties: { new: [] } }, modal = { id }) { - let promise = Promise.resolve(); - - pool.properties.errorcount = 0; - - pool.properties.new.forEach((_value, _index) => { - promise = promise.then(_ => new Promise(resolve => - setTimeout(function () { - let process = { - command: ["/sbin/zpool", "set", _value, pool.name] - }; - - FnConsole.log[2]("Storage Pools, Configure: In Progress, Pool: " + pool.name); - FnConsole.log[3](FnConsoleCommand({ command: process.command })); - - cockpit.spawn(process.command, { err: "out", superuser: "require" }) - .done(function () { - if (_index == (pool.properties.new.length - 1)) { - if (pool.properties.errorcount == 0) { - FnDisplayAlert({ status: "success", title: "Storge Pool successfully configured", description: pool.name, breakword: false }, { name: "storagepool-configure", id: pool.id, timeout: 4 }); - - FnConsole.log[1]("Storage Pools, Configure: Success, Pool: " + pool.name); - } else { - FnStoragePoolConfigureFail({ name: pool.name, id: pool.id }); - } - - modal.id.modal("hide"); - - setTimeout(function () { - FnStoragePoolRefresh({ name: pool.name, id: pool.id }, { storagepool: true, filesystems: true, snapshots: false, status: false }); - }, 200); - } - }) - .fail(function (message, data) { - pool.properties.errorcount++; - - FnConsole.warn("Storage Pools, Property, Set: Failed, Pool: " + pool.name + ", Message: " + (data ? data : message)); - - if (_index == (pool.properties.new.length - 1)) { - FnStoragePoolConfigureFail({ name: pool.name, id: pool.id }); - - modal.id.modal("hide"); - } - }); - - resolve(); - }, 500) - )); - }); -} - -function FnStoragePoolConfigureFail(pool = { name, id }) { - FnDisplayAlert({ status: "danger", title: "Storge Pool could not be configured", description: pool.name, breakword: false }, { name: "storagepool-configure", id: pool.id, timeout: 4 }); - - FnConsole.warn("Storage Pools, Configure: Failed, Pool: " + pool.name); -} - -function FnStoragePoolConfigureFeatures(pool = { name, id, feature: { allocation_classes, async_destroy, bookmark_v2, bookmarks, device_removal, edonr, embedded_data, empty_bpobj, enabled_txg, encryption, extensible_dataset, filesystem_limits, hole_birth, large_blocks, large_dnode, lz4_compress, multi_vdev_crash_dump, obsolete_counts, project_quota, resilver_defer, sha512, skein, spacemap_histogram, spacemap_v2, userobj_accounting, zpool_checkpoint }, readonly: false }, modal = { id }) { - pool.features = { - new: [] - }; - - if (pool.feature.allocation_classes) { - pool.features.new.push("feature@allocation_classes=" + pool.feature.allocation_classes); - } - if (pool.feature.async_destroy) { - pool.features.new.push("feature@async_destroy=" + pool.feature.async_destroy); - } - if (pool.feature.bookmark_v2) { - pool.features.new.push("feature@bookmark_v2=" + pool.feature.bookmark_v2); - } - if (pool.feature.bookmarks) { - pool.features.new.push("feature@bookmarks=" + pool.feature.bookmarks); - } - if (pool.feature.device_removal) { - pool.features.new.push("feature@device_removal=" + pool.feature.device_removal); - } - if (pool.feature.edonr) { - pool.features.new.push("feature@edonr=" + pool.feature.edonr); - } - if (pool.feature.embedded_data) { - pool.features.new.push("feature@embedded_data=" + pool.feature.embedded_data); - } - if (pool.feature.empty_bpobj) { - pool.features.new.push("feature@empty_bpobj=" + pool.feature.empty_bpobj); - } - if (pool.feature.enabled_txg) { - pool.features.new.push("feature@enabled_txg=" + pool.feature.enabled_txg); - } - if (pool.feature.encryption) { - pool.features.new.push("feature@encryption=" + pool.feature.encryption); - } - if (pool.feature.extensible_dataset) { - pool.features.new.push("feature@extensible_dataset=" + pool.feature.extensible_dataset); - } - if (pool.feature.filesystem_limits) { - pool.features.new.push("feature@filesystem_limits=" + pool.feature.filesystem_limits); - } - if (pool.feature.hole_birth) { - pool.features.new.push("feature@hole_birth=" + pool.feature.hole_birth); - } - if (pool.feature.large_blocks) { - pool.features.new.push("feature@large_blocks=" + pool.feature.large_blocks); - } - if (pool.feature.large_dnode) { - pool.features.new.push("feature@large_dnode=" + pool.feature.large_dnode); - } - if (pool.feature.lz4_compress) { - pool.features.new.push("feature@lz4_compress=" + pool.feature.lz4_compress); - } - if (pool.feature.multi_vdev_crash_dump) { - pool.features.new.push("feature@multi_vdev_crash_dump=" + pool.feature.multi_vdev_crash_dump); - } - if (pool.feature.obsolete_counts) { - pool.features.new.push("feature@obsolete_counts=" + pool.feature.obsolete_counts); - } - if (pool.feature.project_quota) { - pool.features.new.push("feature@project_quota=" + pool.feature.project_quota); - } - if (pool.feature.resilver_defer) { - pool.features.new.push("feature@resilver_defer=" + pool.feature.resilver_defer); - } - if (pool.feature.sha512) { - pool.features.new.push("feature@sha512=" + pool.feature.sha512); - } - if (pool.feature.skein) { - pool.features.new.push("feature@skein=" + pool.feature.skein); - } - if (pool.feature.spacemap_histogram) { - pool.features.new.push("feature@spacemap_histogram=" + pool.feature.spacemap_histogram); - } - if (pool.feature.spacemap_v2) { - pool.features.new.push("feature@spacemap_v2=" + pool.feature.spacemap_v2); - } - if (pool.feature.userobj_accounting) { - pool.features.new.push("feature@userobj_accounting=" + pool.feature.userobj_accounting); - } - if (pool.feature.zpool_checkpoint) { - pool.features.new.push("feature@zpool_checkpoint=" + pool.feature.zpool_checkpoint); - } - - if (pool.features.new.length > 0 && !pool.readonly) { - FnConsole.log[2]("Storage Pools, Configure, Features: In Progress, Pool: " + pool.name); - - $("#spinner-storagepool-configure-features-" + pool.id + " span").text("Configuring storage pool features..."); - - FnStoragePoolConfigureFeaturesCommand({ name: pool.name, id: pool.id, features: { new: pool.features.new } }, { id: modal.id }); - } else { - modal.id.modal("hide"); - } -} - -function FnStoragePoolConfigureFeaturesCommand(pool = { name, id, features: { new: [] } }, modal = { id }) { - let promise = Promise.resolve(); - - pool.features.errorcount = 0; - - pool.features.new.forEach((_value, _index) => { - promise = promise.then(_ => new Promise(resolve => - setTimeout(function () { - let process = { - command: ["/sbin/zpool", "set", _value, pool.name] - }; - - FnConsole.log[2]("Storage Pools, Configure, Features: In Progress, Pool: " + pool.name); - FnConsole.log[3](FnConsoleCommand({ command: process.command })); - - cockpit.spawn(process.command, { err: "out", superuser: "require" }) - .done(function () { - if (_index == (pool.features.new.length - 1)) { - if (pool.features.errorcount == 0) { - FnDisplayAlert({ status: "success", title: "Storge Pool features successfully configured", description: pool.name, breakword: false }, { name: "storagepool-configure-features", id: pool.id, timeout: 4 }); - - FnConsole.log[1]("Storage Pools, Configure, Features: Success, Pool: " + pool.name); - } else { - FnStoragePoolConfigureFeaturesFail({ name: pool.name, id: pool.id }); - } - - modal.id.modal("hide"); - - setTimeout(function () { - FnStoragePoolRefresh({ name: pool.name, id: pool.id }, { storagepool: true, filesystems: true, snapshots: true, status: true }); - }, 200); - } - }) - .fail(function (message, data) { - pool.features.errorcount++; - - FnConsole.warn("Storage Pools, Feature, Set: Failed, Pool: " + pool.name + ", Message: " + (data ? data : message)); - - if (_index == (pool.features.new.length - 1)) { - FnStoragePoolConfigureFeaturesFail({ name: pool.name, id: pool.id }); - - modal.id.modal("hide"); - } - }); - - resolve(); - }, 500) - )); - }); -} - -function FnStoragePoolConfigureFeaturesFail(pool = { name, id }) { - FnDisplayAlert({ status: "danger", title: "Storge Pool features could not be configured", description: pool.name, breakword: false }, { name: "storagepool-configure-features", id: pool.id, timeout: 4 }); - - FnConsole.warn("Storage Pools, Configure, Features: Failed, Pool: " + pool.name); -} - -function FnStoragePoolCreate(pool = { name, ashift, autoexpand, autoreplace, autotrim, force, virtualdevice }, filesystem = { compression, dedup, recordsize, refreservationpercent, selinux }, disks = { id: [] }) { - let process = { - command: [((zfsmanager.user.admin || !zfsmanager.user.name) ? "pkexec" : ""), "/sbin/zpool", "create", "-o", "ashift=" + pool.ashift, "-o", "autoexpand=" + pool.autoexpand, "-o", "autoreplace=" + pool.autoreplace, "-o", "autotrim=" + pool.autotrim, "-O", "aclinherit=passthrough", "-O", "acltype=posixacl", "-O", "casesensitivity=sensitive", "-O", "compression=" + filesystem.compression, "-O", "normalization=formD", "-O", "recordsize=" + filesystem.recordsize, "-O", "sharenfs=off", "-O", "sharesmb=off", "-O", "utf8only=on", "-O", "xattr=sa", pool.name] - }; - let modal = { - hide: true - }; - - if (filesystem.selinux) { - process.command.splice((process.command.length - 1), 0, "-O"); - process.command.splice((process.command.length - 1), 0, "context=system_u:object_r:samba_share_t:s0"); - process.command.splice((process.command.length - 1), 0, "-O"); - process.command.splice((process.command.length - 1), 0, "fscontext=system_u:object_r:samba_share_t:s0"); - process.command.splice((process.command.length - 1), 0, "-O"); - process.command.splice((process.command.length - 1), 0, "defcontext=system_u:object_r:samba_share_t:s0"); - process.command.splice((process.command.length - 1), 0, "-O"); - process.command.splice((process.command.length - 1), 0, "rootcontext=system_u:object_r:samba_share_t:s0"); - } - if (filesystem.dedup) { - process.command.splice((process.command.length - 1), 0, "-O"); - process.command.splice((process.command.length - 1), 0, "dedup=" + filesystem.dedup); - } - if (pool.force) { - process.command.splice(3, 0, "-f"); - } - if (pool.virtualdevice) { - process.command.push(pool.virtualdevice); - } - - disks.id.forEach(_value => _value && process.command.push(_value)); - - pool.id = FnGenerateId({ at: false, colon: true, forwardslash: false, period: true, underscore: true, whitespace: true }, { name: pool.name, attribute: true }); - - FnConsole.log[1]("Storage Pools, Create: In Progress, Pool: " + pool.name); - FnConsole.log[2](FnConsoleCommand({ command: process.command })); - - $("#spinner-storagepools-create span").text("Creating storage pool..."); - - return cockpit.spawn(process.command, { err: "out" }) - .done(function () { - FnDisplayAlert({ status: "success", title: "Storage Pool successfully created", description: pool.name, breakword: false }, { name: "storagepool-create", id: pool.id, timeout: 4 }); - - FnConsole.log[1]("Storage Pools, Create: Success, Pool: " + pool.name); - - if (filesystem.refreservationpercent > 0) { - FnStoragePoolSizeGet({ name: pool.name, id: null }) - .done(function (_data) { - FnConsole.log[4](FnConsoleVerbose({ data: _data, message: "Storage Pools, Size, Get:" })); - - if (_data) { - _data = _data.replace(/\n+/g, ""); - - filesystem.refreservation = ((_data / 100) * filesystem.refreservationpercent); - - FnStoragePoolRefreservationSet({ name: pool.name, id: null }, { refreservation: filesystem.refreservation }); - } - }); - } - }) - .fail(function (message, data) { - if (/pool already exists/gi.test(data)) { - modal.hide = false; - - $("#validationwrapper-storagepools-create-name").addClass("has-error"); - $("#helpblock-storagepools-create-name").addClass("has-error").removeClass("hidden").text("Name already exists."); - $("#input-storagepools-create-name").focus(); - } else if (/contains devices of different sizes/gi.test(data)) { - modal.hide = false; - - $("#validationwrapper-storagepools-create-disks").addClass("has-error"); - $("#helpblock-storagepools-create-disks").addClass("has-error").removeClass("hidden").text("Disks are of different sizes. Forcefully create storage pool to override."); - } else { - FnDisplayAlert({ status: "danger", title: "Storage Pool could not be created", description: pool.name, breakword: false }, { name: "storagepool-create", id: pool.id, timeout: 4 }); - } - - FnConsole.warn("Storage Pools, Create: Failed, Pool: " + pool.name + ", Message: " + (data ? data : message)); - - if (!modal.hide) { - $("#spinner-storagepools-create").addClass("hidden"); - $("#spinner-storagepools-create span").text(""); - $("#btn-storagepools-create-apply").prop("disabled", false); - } - }) - .finally(function () { - if (modal.hide) { - $("#modal-storagepools-create").modal("hide"); - - setTimeout(function () { - FnStoragePoolsGet(); - }, 200); - } - }); -} - -function FnStoragePoolDestroy(pool = { name, id, altroot: false, force: false, labelclear: false }, samba = { restart: false }) { - let disks = { - attached: [] - }; - - pool.attached = []; - pool.attachedconfig = []; - - if (pool.labelclear) { - FnDisksStoragePoolsAttachedGet({ name: pool.name, id: pool.id }, { id: { blockdevice: true } }) - .done(function (data) { - FnConsole.log[4](FnConsoleVerbose({ data: data, message: "Disks, Storage Pools, Attached, Get:" })); - - pool.attached = data.replace(/\n\t+/g, "[TAB1]").split(/\n/g).filter(v => v); - - pool.attached.forEach((_value, _index) => { - if (/\[TAB1\]NAME/g.test(_value)) { //Config header row - _value = _value.split("upath").slice(1).join("."); //Remove config header row (and any previous text if exists) - - if (new RegExp("^\\[TAB1\\]" + pool.name).test(_value)) { //Confirm config rows - _value.split("[TAB1]").filter(v => v && pool.attachedconfig.push(v)); - } - } - }); - - pool.attachedconfig.forEach((_value, _index) => { - let config = { - disk: { - upath: "" - }, - tier: { - level: (_value.match(/^\s*/g)[0].length / 2) - } - }; - - _value = _value.replace(/ +/g, "\u22C5").replace(/^\u22C5/, "").split("\u22C5").filter(v => v); - - if (/^\/dev\/nvme|^\/dev\/sd/gi.test(_value[5])) { //upath - config.disk.upath = _value[5]; - } else if (!$.isNumeric(_value[0]) && _value[5] != "was") { //upath appears after error messages and before trim messages - for (let i = 5; i < _value.length; i++) { - if (/^\/dev\/nvme|^\/dev\/sd/gi.test(_value[i])) { - config.disk.upath = _value[i]; - } - } - } - - if (config.tier.level > 0) { - if (/^\/dev\/nvme|^\/dev\/sd/gi.test(config.disk.upath)) { //Block Device via upath - disks.attached.push(config.disk.upath.replace(/^\/dev\//gi, "")); - } else if (/^\/dev\/nvme|^\/dev\/sd/gi.test(_value[0])) { //Block Device - if (/^\/dev\/nvme\d+n\d+p\d+$/gi.test(_value[0])) { - disks.attached.push(_value[0].replace(/^\/dev\//gi, "").replace(/p\d+$/, "")); - } else if (/^\/dev\/sd.*\d+$/gi.test(_value[0])) { - disks.attached.push(_value[0].replace(/^\/dev\//gi, "").replace(/\d+$/, "")); - } else { - disks.attached.push(_value[0]); - } - } else if (/^nvme-nvme/gi.test(_value[0]) || /^wwn-/gi.test(_value[0])) { //WWN - if (/^nvme-nvme.*-part\d+$/gi.test(_value[0])) { - disks.attached.push(_value[0].replace(/-part\d+$/, "")); - } else if (/^wwn-.*-part\d+$/gi.test(_value[0])) { - disks.attached.push(_value[0].replace(/-part\d+$/, "")); - } else { - disks.attached.push(_value[0]); - } - } - } - }); - - disks.attached.sort(); - }); - } - - if (samba.restart) { - FnSambaStop() - .finally(function () { - if (zfsmanager.configuration.samba.manage) { - $("#spinner-storagepool-destroy-" + pool.id + " span").text("Retrieving Samba shares..."); - - FnSambaSharesGet({ name: pool.name, id: pool.id }, { name: null, clones: [] }) - .done(function (data) { - FnConsole.log[4](FnConsoleVerbose({ data: data, message: "Samba, Shares, Get:" })); - - let filesystems = { - id: data.split(/\n/g).filter(v => v && /\ton$/i.test(v)) - }; - - $("#spinner-storagepool-destroy-" + pool.id + " span").text("Destroying storage pool..."); - - if (filesystems.id.length > 0) { - FnStoragePoolDestroyCommand({ name: pool.name, id: pool.id, force: pool.force }) - .done(function () { - $("#spinner-storagepool-destroy-" + pool.id + " span").text("Destroying Samba shares..."); - - FnSambaSharesDestroy({ name: pool.name, id: pool.id, altroot: pool.altroot, readonly: false }, { id: filesystems.id }, { restart: samba.restart }, { silent: false }) - .finally(function () { - if (pool.labelclear) { - $("#spinner-storagepool-destroy-" + pool.id + " span").text("Clearing disk labels..."); - - FnStoragePoolDestroyLabelClear({ name: pool.name, id: pool.id }, { id: disks.attached }) - .finally(function () { - $("#modal-storagepool-destroy-" + pool.id).modal("hide"); - - setTimeout(function () { - FnStoragePoolsGet(); - }, 200); - }); - } else { - $("#modal-storagepool-destroy-" + pool.id).modal("hide"); - - setTimeout(function () { - FnStoragePoolsGet(); - }, 200); - } - }) - }); - } else { - FnStoragePoolDestroyCommand({ name: pool.name, id: pool.id, force: pool.force }) - .done(function () { - if (pool.labelclear) { - $("#spinner-storagepool-destroy-" + pool.id + " span").text("Clearing disk labels..."); - - FnStoragePoolDestroyLabelClear({ name: pool.name, id: pool.id }, { id: disks.attached }) - .finally(function () { - $("#modal-storagepool-destroy-" + pool.id).modal("hide"); - - setTimeout(function () { - FnStoragePoolsGet(); - }, 200); - }); - } else { - $("#modal-storagepool-destroy-" + pool.id).modal("hide"); - - setTimeout(function () { - FnStoragePoolsGet(); - }, 200); - } - }) - .finally(function () { - FnSambaStart(); - }); - } - }) - .fail(function (message, data) { - FnStoragePoolDestroyFail({ name: pool.name, id: pool.id }, { data: data, message: message }); - FnSambaStart(); - }); - } else { - FnStoragePoolDestroyCommand({ name: pool.name, id: pool.id, force: pool.force }) - .done(function () { - if (pool.labelclear) { - $("#spinner-storagepool-destroy-" + pool.id + " span").text("Clearing disk labels..."); - - FnStoragePoolDestroyLabelClear({ name: pool.name, id: pool.id }, { id: disks.attached }) - .finally(function () { - $("#modal-storagepool-destroy-" + pool.id).modal("hide"); - - setTimeout(function () { - FnStoragePoolsGet(); - }, 200); - }); - } else { - $("#modal-storagepool-destroy-" + pool.id).modal("hide"); - - setTimeout(function () { - FnStoragePoolsGet(); - }, 200); - } - }) - .finally(function () { - FnSambaStart(); - }); - } - }); - } else { - if (zfsmanager.configuration.samba.manage) { - $("#spinner-storagepool-destroy-" + pool.id + " span").text("Retrieving Samba shares..."); - - FnSambaSharesGet({ name: pool.name, id: pool.id }, { name: null, clones: [] }) - .done(function (data) { - FnConsole.log[4](FnConsoleVerbose({ data: data, message: "Samba, Shares, Get:" })); - - let filesystems = { - id: data.split(/\n/g).filter(v => v && /\ton$/i.test(v)) - }; - - $("#spinner-storagepool-destroy-" + pool.id + " span").text("Destroying storage pool..."); - - if (filesystems.id.length > 0) { - FnStoragePoolDestroyCommand({ name: pool.name, id: pool.id, force: pool.force }) - .done(function () { - $("#spinner-storagepool-destroy-" + pool.id + " span").text("Destroying Samba shares..."); - - FnSambaSharesDestroy({ name: pool.name, id: pool.id, altroot: pool.altroot, readonly: false }, { id: filesystems.id }, { restart: samba.restart }, { silent: false }) - .finally(function () { - if (pool.labelclear) { - $("#spinner-storagepool-destroy-" + pool.id + " span").text("Clearing disk labels..."); - - FnStoragePoolDestroyLabelClear({ name: pool.name, id: pool.id }, { id: disks.attached }) - .finally(function () { - $("#modal-storagepool-destroy-" + pool.id).modal("hide"); - - setTimeout(function () { - FnStoragePoolsGet(); - }, 200); - }); - } else { - $("#modal-storagepool-destroy-" + pool.id).modal("hide"); - - setTimeout(function () { - FnStoragePoolsGet(); - }, 200); - } - }) - }); - } else { - FnStoragePoolDestroyCommand({ name: pool.name, id: pool.id, force: pool.force }) - .done(function () { - if (pool.labelclear) { - $("#spinner-storagepool-destroy-" + pool.id + " span").text("Clearing disk labels..."); - - FnStoragePoolDestroyLabelClear({ name: pool.name, id: pool.id }, { id: disks.attached }) - .finally(function () { - $("#modal-storagepool-destroy-" + pool.id).modal("hide"); - - setTimeout(function () { - FnStoragePoolsGet(); - }, 200); - }); - } else { - $("#modal-storagepool-destroy-" + pool.id).modal("hide"); - - setTimeout(function () { - FnStoragePoolsGet(); - }, 200); - } - }); - } - }) - .fail(function (message, data) { - FnStoragePoolDestroyFail({ name: pool.name, id: pool.id }, { data: data, message: message }); - }); - } else { - FnStoragePoolDestroyCommand({ name: pool.name, id: pool.id, force: pool.force }) - .done(function () { - if (pool.labelclear) { - $("#spinner-storagepool-destroy-" + pool.id + " span").text("Clearing disk labels..."); - - FnStoragePoolDestroyLabelClear({ name: pool.name, id: pool.id }, { id: disks.attached }) - .finally(function () { - $("#modal-storagepool-destroy-" + pool.id).modal("hide"); - - setTimeout(function () { - FnStoragePoolsGet(); - }, 200); - }); - } else { - $("#modal-storagepool-destroy-" + pool.id).modal("hide"); - - setTimeout(function () { - FnStoragePoolsGet(); - }, 200); - } - }); - } - } -} - -function FnStoragePoolDestroyCommand(pool = { name, id, force: false }) { - let process = { - command: [((zfsmanager.user.admin || !zfsmanager.user.name) ? "pkexec" : ""), "/sbin/zpool", "destroy", pool.name] - }; - - if (pool.force) { - process.command.splice(3, 0, "-f"); - } - - FnConsole.log[1]("Storage Pools, Destroy: In Progress, Pool: " + pool.name); - FnConsole.log[2](FnConsoleCommand({ command: process.command })); - - return cockpit.spawn(process.command, { err: "out" }) - .done(function () { - FnDisplayAlert({ status: "success", title: "Storage Pool successfully destroyed", description: pool.name, breakword: false }, { name: "storagepool-destroy", id: pool.id, timeout: 4 }); - - FnConsole.log[1]("Storage Pools, Destroy: Success, Pool: " + pool.name); - }) - .fail(function (message, data) { - FnStoragePoolDestroyFail({ name: pool.name, id: pool.id }, { data: data, message: message }); - }); -} - -function FnStoragePoolDestroyFail(pool = { name, id }, process = { data, message }) { - FnDisplayAlert({ status: "danger", title: "Storage Pool could not be destroyed", description: pool.name, breakword: false }, { name: "storagepool-destroy", id: pool.id, timeout: 4 }); - - FnConsole.warn("Storage Pools, Destroy: Failed, Pool: " + pool.name + ", Message: " + (process.data ? process.data : process.message)); - - $("#modal-storagepool-destroy-" + pool.id).modal("hide"); - - setTimeout(function () { - FnStoragePoolsGet(); - }, 200); -} - -function FnStoragePoolDestroyLabelClear(pool = { name, id }, disks = { id: [] }) { - let process = { - promise: cockpit.defer() - }; - let promise = Promise.resolve(); - - disks.clear = { - error: 0 - }; - - FnConsole.log[2]("Storage Pools, Disk Labels, Clear: In Progress"); - - if (disks.id.length > 0) { - disks.id.forEach((_value, _index) => { - promise = promise.then(_ => new Promise(resolve => - setTimeout(function () { - FnStoragePoolDiskLabelClear({ name: pool.name, id: pool.id }, { id: _value, inactive: true }, { silent: true }) - .fail(function () { - disks.clear.error++; - }); - - if (_index == (disks.id.length - 1)) { - setTimeout(function () { - if (disks.clear.error == 0) { - FnDisplayAlert({ status: "success", title: "Storage Pool disk labels successfully cleared", description: pool.name, breakword: false }, { name: "storagepool-destroy-labelclear", id: pool.id, timeout: 4 }); - - FnConsole.log[1]("Storage Pools, Disk Labels, Clear: Success"); - } else { - FnDisplayAlert({ status: "danger", title: "Storage Pool disk labels could not be cleared", description: pool.name, breakword: false }, { name: "storagepool-destroy-labelclear", id: pool.id, timeout: 4 }); - - FnConsole.warn("Storage Pools, Disk Labels, Clear: Failed"); - } - - process.promise.resolve(); - }, 2000); - } - - resolve(); - }, 2000) - )); - }); - } else { - process.promise.resolve(); - } - - return process.promise.promise(); -} - -function FnStoragePoolDiskAttach(pool = { name, id, force: false }, virtualdevice = { id, disk: true }, disk = { idnew: [] }, modal = { name, id }) { - virtualdevice.mirror = { - start: null, - end: null - }; - - $("#spinner-" + modal.name + "-" + modal.id + " span").text("Attaching disk..."); - - if (!virtualdevice.disk && /^mirror-/.test(virtualdevice.id)) { - disk.id = ""; - - FnDisksStoragePoolsAttachedGet({ name: pool.name, id: pool.id }, { id: { blockdevice: false } }) - .done(function (data) { - FnConsole.log[4](FnConsoleVerbose({ data: data, message: "Disks, Storage Pools, Attached, Get:" })); - - pool.attached = data.replace(/\n\t+/g, "[TAB1]").split(/\n/g).filter(v => v); - pool.attachedconfig = []; - - pool.attached.forEach((_value, _index) => { - if (/\[TAB1\]NAME/g.test(_value)) { //Config header row - _value = _value.split("upath").slice(1).join("."); //Remove config header row (and any previous text if exists) - - if (new RegExp("^\\[TAB1\\]" + pool.name).test(_value)) { //Confirm config rows - _value.split("[TAB1]").filter(v => v && pool.attachedconfig.push(v)); - } - } - }); - - pool.attachedconfig.forEach((_value, _index) => { //Find disks in Mirror virtual device and get hierarchy information - let config = { - tier: { - level: (_value.match(/^\s*/g)[0].length / 2) - } - }; - - _value = _value.replace(/ +/g, "\u22C5").replace(/^\u22C5/, "").split("\u22C5").filter(v => v); - - virtualdevice.mirror.regexp = new RegExp(virtualdevice.id, "g"); - - if (config.tier.level == 1 && virtualdevice.mirror.regexp.test(_value[0])) { - if (!virtualdevice.mirror.start) { - virtualdevice.mirror.start = _index; - } - } - - if (virtualdevice.mirror.start && _index > virtualdevice.mirror.start) { - if (config.tier.level == 1) { - if (!virtualdevice.mirror.end) { - virtualdevice.mirror.end = _index; - } - } - } - }); - - if (!virtualdevice.mirror.end) { - virtualdevice.mirror.end = pool.attachedconfig.length; - } - - pool.attachedconfig.forEach((_value, _index) => { //Find first healthy disk in the mirror virtual device - let config = { - disk: { - upath: "" - }, - tier: { - level: (_value.match(/^\s*/g)[0].length / 2) - } - }; - - _value = _value.replace(/ +/g, "\u22C5").replace(/^\u22C5/, "").split("\u22C5").filter(v => v); - - if (/^\/dev\/nvme|^\/dev\/sd/gi.test(_value[5])) { //upath - config.disk.upath = _value[5]; - } else if (!$.isNumeric(_value[0]) && _value[5] != "was") { //upath appears after error messages and before trim messages - for (let i = 5; i < _value.length; i++) { - if (/^\/dev\/nvme|^\/dev\/sd/gi.test(_value[i])) { - config.disk.upath = _value[i]; - } - } - } - - if (config.tier.level == 2 && _index > virtualdevice.mirror.start && _index < virtualdevice.mirror.end && _value[1] == "ONLINE") { - if (/^\/dev\/nvme|^\/dev\/sd/gi.test(config.disk.upath) || /^\/dev\/nvme|^\/dev\/sd/gi.test(_value[0])) { //Block Device - if (/^\/dev\/nvme\d+n\d+p\d+$/gi.test(_value[0])) { - if (!disk.id) { - disk.id = _value[0].replace(/p\d+$/, ""); - } - } else if (/^\/dev\/sd.*\d+$/gi.test(_value[0])) { - if (!disk.id) { - disk.id = _value[0].replace(/\d+$/, ""); - } - } else { - if (!disk.id) { - disk.id = _value[0].replace(/-part\d+$/, ""); - } - } - } else if (/^nvme-nvme/gi.test(_value[0]) || /^wwn-/gi.test(_value[0])) { //WWN - if (!disk.id) { - disk.id = _value[0].replace(/-part\d+$/, ""); - } - } - } - }); - - if (!disk.id || /^mirror-/g.test(disk.id)) { - FnStoragePoolDiskAttachFail({ name: pool.name, id: pool.id }, { id: virtualdevice.id, disk: virtualdevice.disk }, { idnew: disk.idnew }, { name: modal.name, id: modal.id }, { data: null, message: "There are no healthy disks to attach to." }); - } else { - FnStoragePoolDiskAttachCommand({ name: pool.name, id: pool.id, force: pool.force }, { id: virtualdevice.id, disk: virtualdevice.disk }, { id: disk.id, idnew: disk.idnew }, { name: modal.name, id: modal.id }); - } - }) - .fail(function (message, data) { - FnStoragePoolDiskAttachFail({ name: pool.name, id: pool.id }, { id: virtualdevice.id, disk: virtualdevice.disk }, { idnew: disk.idnew }, { name: modal.name, id: modal.id }, { data: data, message: message }); - }); - } else { - FnStoragePoolDiskAttachCommand({ name: pool.name, id: pool.id, force: pool.force }, { id: virtualdevice.id, disk: virtualdevice.disk }, { id: virtualdevice.id, idnew: disk.idnew }, { name: modal.name, id: modal.id }); - } -} - -function FnStoragePoolDiskAttachCommand(pool = { name, id, force: false }, virtualdevice = { id, disk: true }, disk = { id, idnew }, modal = { name, id }) { - let process = { - command: ["/sbin/zpool", "attach", pool.name, disk.id, disk.idnew] - }; - - if (pool.force) { - process.command.splice(3, 0, "-f"); - } - - FnConsole.log[1]("Storage Pools, Disk, Attach: In Progress, Pool: " + pool.name + ", " + (!virtualdevice.disk ? "Virtual Device: " + virtualdevice.id + ", " : "") + "Disk: " + disk.idnew); - FnConsole.log[3](FnConsoleCommand({ command: process.command })); - - return cockpit.spawn(process.command, { err: "out", superuser: "require" }) - .done(function () { - FnDisplayAlert({ status: "success", title: "Disk attached successfully to Storage Pool", description: pool.name, breakword: false }, { name: "storagepool-disk-attach", id: pool.id, timeout: 4 }); - - FnConsole.log[1]("Storage Pools, Disk, Attach: Success, Pool: " + pool.name + ", " + (!virtualdevice.disk ? "Virtual Device: " + virtualdevice.id + ", " : "") + "Disk: " + disk.idnew); - }) - .fail(function (message, data) { - FnDisplayAlert({ status: "danger", title: "Disk could not be attached to Storage Pool", description: pool.name, breakword: false }, { name: "storagepool-disk-attach", id: pool.id, timeout: 4 }); - - FnConsole.warn("Storage Pools, Disk, Attach: Failed, Pool: " + pool.name + ", " + (!virtualdevice.disk ? "Virtual Device: " + virtualdevice.id + ", " : "") + "Disk: " + disk.idnew + ", Message: " + (data ? data : message)); - }) - .finally(function () { - $("#modal-" + modal.name + "-" + modal.id).modal("hide"); - - setTimeout(function () { - FnStoragePoolRefresh({ name: pool.name, id: pool.id }, { storagepool: true, filesystems: false, snapshots: false, status: true }); - }, 200); - });; -} - -function FnStoragePoolDiskAttachFail(pool = { name, id }, virtualdevice = { id, disk: true }, disk = { idnew }, modal = { name, id }, process = { data, message }) { - FnDisplayAlert({ status: "danger", title: "Disk could not be attached to Storage Pool", description: pool.name, breakword: false }, { name: "storagepool-disk-attach", id: pool.id, timeout: 4 }); - - FnConsole.warn("Storage Pools, Disk, Attach: Failed, Pool: " + pool.name + ", " + (!virtualdevice.disk ? "Virtual Device: " + virtualdevice.id + ", " : "") + "Disk: " + disk.idnew + ", Message: " + (process.data ? process.data : process.message)); - - if (modal.id) { - $("#modal-" + modal.name + "-" + modal.id).modal("hide"); - - setTimeout(function () { - FnStoragePoolRefresh({ name: pool.name, id: pool.id }, { storagepool: true, filesystems: false, snapshots: false, status: true }); - }, 200); - } -} - -function FnStoragePoolDiskClear(pool = { name, id }, disk = { id }, modal = { name, id }) { - let process = { - command: ["/sbin/zpool", "clear", pool.name, disk.id] - }; - - FnConsole.log[2]("Storage Pools, Disk, Clear Errors: In Progress, Pool: " + pool.name + ", Disk: " + disk.id); - FnConsole.log[3](FnConsoleCommand({ command: process.command })); - - $("#spinner-" + modal.name + "-" + modal.id + " span").text("Clearing disk errors..."); - - return cockpit.spawn(process.command, { err: "out", superuser: "require" }) - .done(function () { - FnDisplayAlert({ status: "success", title: "Disk errors successfully cleared", description: disk.id, breakword: false }, { name: "storagepool-disk-clear", id: pool.id, timeout: 4 }); - - FnConsole.log[1]("Storage Pools, Disk, Clear Errors: Success, Pool: " + pool.name + ", Disk: " + disk.id); - }) - .fail(function (message, data) { - FnDisplayAlert({ status: "danger", title: "Disk errors could not be cleared", description: disk.id, breakword: false }, { name: "storagepool-disk-clear", id: pool.id, timeout: 4 }); - - FnConsole.warn("Storage Pools, Disk, Clear Errors: Failed, Pool: " + pool.name + ", Disk: " + disk.id + ", Message: " + (data ? data : message)); - }) - .finally(function () { - $("#modal-" + modal.name + "-" + modal.id).modal("hide"); - - setTimeout(function () { - FnStoragePoolRefresh({ name: pool.name, id: pool.id }, { storagepool: true, filesystems: false, snapshots: false, status: true }); - }, 200); - }); -} - -function FnStoragePoolDiskDetach(pool = { name, id }, disk = { id, labelclear: false }, modal = { name, id }) { - let process = { - command: ["/sbin/zpool", "detach", pool.name, disk.id] - }; - - modal.hide = true; - - FnConsole.log[1]("Storage Pools, Disk, Detach: In Progress, Pool: " + pool.name + ", Disk: " + disk.id); - FnConsole.log[3](FnConsoleCommand({ command: process.command })); - - $("#spinner-" + modal.name + "-" + modal.id + " span").text("Detaching disk..."); - - return cockpit.spawn(process.command, { err: "out", superuser: "require" }) - .done(function () { - FnDisplayAlert({ status: "success", title: "Disk detached successfully from Storage Pool", description: pool.name, breakword: false }, { name: "storagepool-disk-detach", id: pool.id, timeout: 4 }); - - FnConsole.log[1]("Storage Pools, Disk, Detach: Success, Pool: " + pool.name + ", Disk: " + disk.id); - - if (disk.labelclear) { - modal.hide = false; - - $("#spinner-" + modal.name + "-" + modal.id + " span").text("Clearing disk label..."); - - setTimeout(function () { - FnStoragePoolDiskLabelClear({ name: pool.name, id: pool.id }, { id: disk.id, inactive: false }, { silent: false }) - .finally(function () { - $("#modal-" + modal.name + "-" + modal.id).modal("hide"); - - setTimeout(function () { - FnStoragePoolRefresh({ name: pool.name, id: pool.id }, { storagepool: true, filesystems: false, snapshots: false, status: true }); - }, 200); - }) - }, 2000); - } - }) - .fail(function (message, data) { - FnDisplayAlert({ status: "danger", title: "Disk could not be detached from Storage Pool", description: pool.name, breakword: false }, { name: "storagepool-disk-detach", id: pool.id, timeout: 4 }); - - FnConsole.warn("Storage Pools, Disk, Detach: Failed, Pool: " + pool.name + ", Disk: " + disk.id + ", Message: " + (data ? data : message)); - }) - .finally(function () { - if (modal.hide) { - $("#modal-" + modal.name + "-" + modal.id).modal("hide"); - - setTimeout(function () { - FnStoragePoolRefresh({ name: pool.name, id: pool.id }, { storagepool: true, filesystems: false, snapshots: false, status: true }); - }, 200); - } - });; -} - -function FnStoragePoolDiskLabelClear(pool = { name, id }, disk = { id, inactive: false }, display = { silent: false }) { - let process = { - command: [((zfsmanager.user.admin || !zfsmanager.user.name) ? "pkexec" : ""), "/sbin/zpool", "labelclear", disk.id] - }; - - if (disk.inactive) { - process.command.splice(3, 0, "-f"); - } - - FnConsole.log[2]("Storage Pools, Disk Label, Clear: In Progress, Disk: " + disk.id); - FnConsole.log[2](FnConsoleCommand({ command: process.command })); - - return cockpit.spawn(process.command, { err: "out" }) - .done(function () { - if (!display.silent) { - FnDisplayAlert({ status: "success", title: "Disk label successfully cleared", description: disk.id, breakword: false }, { name: "storagepool-disk-labelclear", id: pool.id, timeout: 4 }); - } - - FnConsole.log[1]("Storage Pools, Disk Label, Clear: Success, Disk: " + disk.id); - - setTimeout(function () { - FnDisksBlkidGet(); - }, 200); - }) - .fail(function (message, data) { - if (!display.silent) { - FnDisplayAlert({ status: "danger", title: "Disk label could not be cleared", description: disk.id, breakword: false }, { name: "storagepool-disk-labelclear", id: pool.id, timeout: 4 }); - } - - FnConsole.warn("Storage Pools, Disk Label, Clear: Failed, Disk: " + disk.id + ", Message: " + (data ? data : message)); - }); -} - -function FnStoragePoolDiskOffline(pool = { name, id }, disk = { id, force: false, temporary: false }, modal = { name, id }) { - let process = { - command: [((zfsmanager.user.admin || !zfsmanager.user.name) ? "pkexec" : ""), "/sbin/zpool", "offline", pool.name, disk.id] - }; - - if (disk.force) { - process.command.splice(3, 0, "-f"); - } - if (disk.temporary) { - process.command.splice(3, 0, "-t"); - } - - FnConsole.log[1]("Storage Pools, Disk, Offline: In Progress, Pool: " + pool.name + ", Disk: " + disk.id); - FnConsole.log[3](FnConsoleCommand({ command: process.command })); - - $("#spinner-" + modal.name + "-" + modal.id + " span").text("Setting disk offline..."); - - return cockpit.spawn(process.command, { err: "out" }) - .done(function () { - FnDisplayAlert({ status: "success", title: "Disk successfully set offline", description: disk.id, breakword: false }, { name: "storagepool-disk-offline", id: pool.id, timeout: 4 }); - - FnConsole.log[1]("Storage Pools, Disk, Offline: Success, Pool: " + pool.name + ", Disk: " + disk.id); - }) - .fail(function (message, data) { - FnDisplayAlert({ status: "danger", title: "Disk could not be set offline", description: disk.id, breakword: false }, { name: "storagepool-disk-offline", id: pool.id, timeout: 4 }); - - FnConsole.warn("Storage Pools, Disk, Offline: Failed, Pool: " + pool.name + ", Disk: " + disk.id + ", Message: " + (data ? data : message)); - }) - .finally(function () { - $("#modal-" + modal.name + "-" + modal.id).modal("hide"); - - setTimeout(function () { - FnStoragePoolRefresh({ name: pool.name, id: pool.id }, { storagepool: true, filesystems: false, snapshots: false, status: true }); - }, 200); - });; -} - -function FnStoragePoolDiskOnline(pool = { name, id, scrub: false }, disk = { id, expand: false }, modal = { name, id }) { - let process = { - command: ["/sbin/zpool", "online", pool.name, disk.id] - }; - - if (disk.expand) { - process.command.splice(2, 0, "-e"); - } - - FnConsole.log[1]("Storage Pools, Disk, Online: In Progress, Pool: " + pool.name + ", Disk: " + disk.id); - FnConsole.log[3](FnConsoleCommand({ command: process.command })); - - $("#spinner-" + modal.name + "-" + modal.id + " span").text("Setting disk online..."); - - return cockpit.spawn(process.command, { err: "out", superuser: "require" }) - .done(function (data, message) { - FnConsole.log[4](FnConsoleVerbose({ data: data, message: "Storage Pools, Disk, Online:" })); - - if (/^warning:/gi.test(data)) { - FnDisplayAlert({ status: "warning", title: "Disk set online but remains in faulted state", description: disk.id, breakword: false }, { name: "storagepool-disk-online", id: pool.id, timeout: 4 }); - - FnConsole.warn("Storage Pools, Disk, Online: Warning, Pool: " + pool.name + ", Message: " + (data ? data.replace(/^warning: /gi, "") : message)); - } else { - FnDisplayAlert({ status: "success", title: "Disk successfully set online", description: disk.id, breakword: false }, { name: "storagepool-disk-online", id: pool.id, timeout: 4 }); - - FnConsole.log[1]("Storage Pools, Disk, Online: Success, Pool: " + pool.name + ", Disk: " + disk.id); - } - - if (pool.scrub) { - FnStoragePoolScrubStart({ name: pool.name, id: pool.id }, { resume: false }, { refresh: false }); - } - }) - .fail(function (message, data) { - FnDisplayAlert({ status: "danger", title: "Disk could not be set online", description: disk.id, breakword: false }, { name: "storagepool-disk-online", id: pool.id, timeout: 4 }); - - FnConsole.warn("Storage Pools, Disk, Online: Failed, Pool: " + pool.name + ", Disk: " + disk.id + ", Message: " + (data ? data : message)); - }) - .finally(function () { - $("#modal-" + modal.name + "-" + modal.id).modal("hide"); - - setTimeout(function () { - FnStoragePoolRefresh({ name: pool.name, id: pool.id }, { storagepool: true, filesystems: false, snapshots: false, status: true }); - }, 200); - });; -} - -function FnStoragePoolDiskReplace(pool = { name, id, force: false }, disk = { id, idnew }, modal = { name, id }) { - let process = { - command: [((zfsmanager.user.admin || !zfsmanager.user.name) ? "pkexec" : ""), "/sbin/zpool", "replace", pool.name, disk.id, disk.idnew] - }; - - if (pool.force) { - process.command.splice(3, 0, "-f"); - } - - FnConsole.log[1]("Storage Pools, Disk, Replace: In Progress, Pool: " + pool.name + ", Disk: " + disk.id); - FnConsole.log[3](FnConsoleCommand({ command: process.command })); - - $("#spinner-" + modal.name + "-" + modal.id + " span").text("Replacing disk..."); - - return cockpit.spawn(process.command, { err: "out" }) - .done(function () { - FnDisplayAlert({ status: "success", title: "Disk replaced successfully on Storage Pool", description: pool.name, breakword: false }, { name: "storagepool-disk-replace", id: pool.id, timeout: 4 }); - - FnConsole.log[1]("Storage Pools, Disk, Replace: Success, Pool: " + pool.name + ", Disk: " + disk.id); - }) - .fail(function (message, data) { - FnDisplayAlert({ status: "danger", title: "Disk could not be replaced on Storage Pool", description: pool.name, breakword: false }, { name: "storagepool-disk-replace", id: pool.id, timeout: 4 }); - - FnConsole.warn("Storage Pools, Disk, Replace: Failed, Pool: " + pool.name + ", Disk: " + disk.id + ", Message: " + (data ? data : message)); - }) - .finally(function () { - $("#modal-" + modal.name + "-" + modal.id).modal("hide"); - - setTimeout(function () { - FnStoragePoolRefresh({ name: pool.name, id: pool.id }, { storagepool: true, filesystems: false, snapshots: false, status: true }); - }, 200); - });; -} - -function FnStoragePoolExport(pool = { name, id, altroot: false, force: false, readonly: false }, samba = { restart: false }) { - if (samba.restart) { - FnSambaStop() - .finally(function () { - if (zfsmanager.configuration.samba.manage) { - $("#spinner-storagepool-export-" + pool.id + " span").text("Retrieving Samba shares..."); - - FnSambaSharesGet({ name: pool.name, id: pool.id }, { name: null, clones: [] }) - .done(function (data) { - FnConsole.log[4](FnConsoleVerbose({ data: data, message: "Samba, Shares, Get:" })); - - let filesystems = { - id: data.split(/\n/g).filter(v => v && /\ton$/i.test(v)) - }; - - $("#spinner-storagepool-export-" + pool.id + " span").text("Exporting storage pool..."); - - if (filesystems.id.length > 0) { - FnStoragePoolExportCommand({ name: pool.name, id: pool.id, force: pool.force }, { refresh: false }) - .done(function () { - $("#spinner-storagepool-export-" + pool.id + " span").text("Destroying Samba shares..."); - - FnSambaSharesDestroy({ name: pool.name, id: pool.id, altroot: pool.altroot, readonly: pool.readonly }, { id: filesystems.id }, { restart: samba.restart }, { silent: false }) - .finally(function () { - $("#modal-storagepool-export-" + pool.id).modal("hide"); - - setTimeout(function () { - FnStoragePoolsGet(); - }, 200); - }); - }); - } else { - FnStoragePoolExportCommand({ name: pool.name, id: pool.id, force: pool.force }, { refresh: true }) - .finally(function () { - FnSambaStart(); - }); - } - }) - .fail(function (message, data) { - FnStoragePoolExportFail({ name: pool.name, id: pool.id }, { data: data, message: message }, { refresh: true }); - FnSambaStart(); - }); - } else { - FnStoragePoolExportCommand({ name: pool.name, id: pool.id, force: pool.force }, { refresh: true }) - .finally(function () { - FnSambaStart(); - }); - } - }); - } else { - if (zfsmanager.configuration.samba.manage) { - $("#spinner-storagepool-export-" + pool.id + " span").text("Retrieving Samba shares..."); - - FnSambaSharesGet({ name: pool.name, id: pool.id }, { name: null, clones: [] }) - .done(function (data) { - FnConsole.log[4](FnConsoleVerbose({ data: data, message: "Samba, Shares, Get:" })); - - let filesystems = { - id: data.split(/\n/g).filter(v => v && /\ton$/i.test(v)) - }; - - $("#spinner-storagepool-export-" + pool.id + " span").text("Exporting storage pool..."); - - if (filesystems.id.length > 0) { - FnStoragePoolExportCommand({ name: pool.name, id: pool.id, force: pool.force }, { refresh: false }) - .done(function () { - $("#spinner-storagepool-export-" + pool.id + " span").text("Destroying Samba shares..."); - - FnSambaSharesDestroy({ name: pool.name, id: pool.id, altroot: pool.altroot, readonly: pool.readonly }, { id: filesystems.id }, { restart: samba.restart }, { silent: false }) - .finally(function () { - $("#modal-storagepool-export-" + pool.id).modal("hide"); - - setTimeout(function () { - FnStoragePoolsGet(); - }, 200); - }); - }); - } else { - FnStoragePoolExportCommand({ name: pool.name, id: pool.id, force: pool.force }, { refresh: true }); - } - }) - .fail(function (message, data) { - FnStoragePoolExportFail({ name: pool.name, id: pool.id }, { data: data, message: message }, { refresh: true }); - }); - } else { - FnStoragePoolExportCommand({ name: pool.name, id: pool.id, force: pool.force }, { refresh: true }); - } - } -} - -function FnStoragePoolExportCommand(pool = { name, id, force: false }, display = { refresh: true }) { - let process = { - command: [((zfsmanager.user.admin || !zfsmanager.user.name) ? "pkexec" : ""), "/sbin/zpool", "export", pool.name] - }; - - if (pool.force) { - process.command.splice(3, 0, "-f"); - } - - FnConsole.log[1]("Storage Pools, Export: In Progress, Pool: " + pool.name); - FnConsole.log[3](FnConsoleCommand({ command: process.command })); - - return cockpit.spawn(process.command, { err: "out" }) - .done(function () { - FnDisplayAlert({ status: "success", title: "Storage Pool successfully exported", description: pool.name, breakword: false }, { name: "storagepool-export", id: pool.id, timeout: 4 }); - - FnConsole.log[1]("Storage Pools, Export: Success, Pool: " + pool.name); - }) - .fail(function (message, data) { - FnStoragePoolExportFail({ name: pool.name, id: pool.id }, { data: data, message: message }, { refresh: false }); - - display.refresh = true; - }) - .finally(function () { - if (display.refresh) { - $("#modal-storagepool-export-" + pool.id).modal("hide"); - - setTimeout(function () { - FnStoragePoolsGet(); - }, 200); - } - }); -} - -function FnStoragePoolExportFail(pool = { name, id }, process = { data, message }, display = { refresh: true }) { - FnDisplayAlert({ status: "danger", title: "Storage Pool could not be exported", description: pool.name, breakword: false }, { name: "storagepool-export", id: pool.id, timeout: 4 }); - - FnConsole.warn("Storage Pools, Export: Failed, Pool: " + pool.name + ", Message: " + (process.data ? process.data : process.message)); - - if (display.refresh) { - $("#modal-storagepool-export-" + pool.id).modal("hide"); - - setTimeout(function () { - FnStoragePoolsGet(); - }, 200); - } -} - -function FnStoragePoolHealthIcon(pool = { health }) { - switch (pool.health.toLowerCase()) { - case "online": - pool.healthicon = "pficon pficon-ok list-view-pf-icon-sm"; - break; - case "offline": - pool.healthicon = "fa pficon-info list-view-pf-icon-sm"; - break; - case "split": - pool.healthicon = "fa pficon-info list-view-pf-icon-sm"; - break; - case "degraded": - pool.healthicon = "pficon pficon-warning-triangle-o list-view-pf-icon-sm"; - break; - case "unknown": - pool.healthicon = "pficon pficon-warning-triangle-o list-view-pf-icon-sm"; - break; - case "removed": - pool.healthicon = "pficon pficon-error-circle-o list-view-pf-icon-sm"; - break; - case "faulted": - pool.healthicon = "pficon pficon-error-circle-o list-view-pf-icon-sm"; - break; - case "unavail": - pool.healthicon = "pficon pficon-error-circle-o list-view-pf-icon-sm"; - break; - case "avail": - pool.healthicon = "pficon pficon-ok list-view-pf-icon-sm"; - break; - case "inuse": - pool.healthicon = "pficon pficon-ok list-view-pf-icon-sm"; - break; - case "fail": - pool.healthicon = "pficon pficon-error-circle-o list-view-pf-icon-sm"; - break; - case "destroyed": - pool.healthicon = "pficon pficon-error-circle-o list-view-pf-icon-sm"; - break; - default: - pool.healthicon = "fa pficon-info list-view-pf-icon-sm"; - break; - } - - return pool.healthicon; -} - -function FnStoragePoolImport(pool = { name, altroot, destroyed: false, force: false, guid, ignoremissinglog: false, namenew, readonly: false, recoverymode: false }, filesystem = { mount: true, selinux: true }, disks = { id: { blockdevice: true, disk: false, path: false, vdev: false }, identifier }) { - let process = { - command: [((zfsmanager.user.admin || !zfsmanager.user.name) ? "pkexec" : ""), "/sbin/zpool", "import", pool.guid] - }; - let modal = { - hide: true - }; - - disks.devpath = "/dev"; - disks.fallback = false; - disks.identifiertext = "Block Device"; - - if (pool.namenew) { - pool.name = pool.namenew; - } - - process.command.push(pool.name); - - pool.id = FnGenerateId({ at: false, colon: true, forwardslash: false, period: true, underscore: true, whitespace: true }, { name: pool.name, attribute: true }); - pool.imported = false; - - if (!filesystem.mount) { - process.command.splice(3, 0, "-N"); - } - - if (pool.altroot) { - process.command.splice(3, 0, "-o"); - process.command.splice(4, 0, "altroot=" + pool.altroot); - } - if (pool.destroyed) { - process.command.splice(3, 0, "-D"); - } - if (pool.force) { - process.command.splice(3, 0, "-f"); - } - if (pool.recoverymode) { - process.command.splice(3, 0, "-F"); - } - if (pool.ignoremissinglog) { - process.command.splice(3, 0, "-m"); - } - if (pool.readonly) { - process.command.splice(3, 0, "-o"); - process.command.splice(4, 0, "readonly=on"); - } - - process.command.splice(2, 0, "-d"); - - switch (disks.identifier) { //Fallback to block device to prevent import error when selected identifier is not available - case "disk": - if (disks.id.disk) { - disks.devpath = "/dev/disk/by-id"; - } else { - disks.fallback = true; - } - disks.identifiertext = "Disk / WWN"; - break; - case "path": - if (disks.id.path) { - disks.devpath = "/dev/disk/by-path"; - } else { - disks.fallback = true; - } - disks.identifiertext = "Hardware Path"; - break; - case "vdev": - if (disks.id.vdev) { - disks.devpath = "/dev/disk/by-vdev"; - } else { - disks.fallback = true; - } - disks.identifiertext = "Virtual Device Mapping"; - break; - } - - process.command.splice(3, 0, disks.devpath); - - FnConsole.log[1]("Storage Pools, Import: In Progress, Pool: " + pool.name); - FnConsole.log[3](FnConsoleCommand({ command: process.command })); - - $("#spinner-storagepools-import span").text("Importing storage pool..."); - - return cockpit.spawn(process.command, { err: "out", superuser: "require" }) - .done(function () { - pool.imported = true; - - if (disks.fallback) { - FnDisplayAlert({ status: "warning", title: "Storage Pool imported with errors", description: pool.name, breakword: false }, { name: "storagepools-import", id: pool.id, timeout: 4 }); - - FnConsole.warn("Storage Pools, Import: Warning, Pool: " + pool.name + ", Message: " + disks.identifiertext + " disks identifier was not available during import. Block Device disks identifier was used."); - } else { - FnDisplayAlert({ status: "success", title: "Storage Pool successfully imported", description: pool.name, breakword: false }, { name: "storagepools-import", id: pool.id, timeout: 4 }); - - FnConsole.log[1]("Storage Pools, Import: Success, Pool: " + pool.name); - } - }) - .fail(function (message, data) { - if (/cannot mount.*directory is not empty|smb add share failed|cannot share/gi.test(data)) { //Storage pool has successfully imported, however a file system error is generated - pool.imported = true; - - FnDisplayAlert({ status: "warning", title: "Storage Pool imported with errors", description: pool.name, breakword: false }, { name: "storagepools-import", id: pool.id, timeout: 4 }); - - FnConsole.warn("Storage Pools, Import: Warning, Pool: " + pool.name + ", Message: " + (data ? data : message)); - } else if (/cannot import.*pool already exists/gi.test(data)) { - modal.hide = false; - - if (!$("#switch-storagepools-import-rename input").prop("checked")) { - $("#switch-storagepools-import-rename input").click(); - } - $("#validationwrapper-storagepools-import-storagepools").addClass("has-error"); - $("#helpblock-storagepools-import-storagepools").removeClass("hidden").text("Storage pool name already exists. New name is needed."); - $("#input-storagepools-import-namenew").focus(); - } else { - FnDisplayAlert({ status: "danger", title: "Storage Pool could not be imported", description: pool.name, breakword: false }, { name: "storagepools-import", id: pool.id, timeout: 4 }); - } - - if (!modal.hide) { - $("#spinner-storagepools-import").addClass("hidden"); - $("#spinner-storagepools-import span").text(""); - $("#btn-storagepools-import-apply").prop("disabled", false); - } - - if (!pool.imported) { - FnConsole.warn("Storage Pools, Import: Failed, Pool: " + pool.name + ", Message: " + (data ? data : message)); - } - }) - .finally(function () { - if (pool.imported) { - if (filesystem.selinux && !pool.readonly) { - $("#spinner-storagepools-import span").text("Configuring SELinux contexts for Samba..."); - - FnStoragePoolSelinuxContextsSambaSet({ name: pool.name, id: pool.id }) - .finally(function () { - if (zfsmanager.configuration.samba.manage) { - if (!pool.readonly) { - $("#spinner-storagepools-import span").text("Disabling Samba share inheritance..."); - - FnFileSystemShareSmbInheritedDisable({ name: pool.name, id: pool.id, altroot: (pool.altroot ? true : false) }, { name: null }, { disable: false }) - .finally(function () { - $("#spinner-storagepools-import span").text("Creating Samba shares..."); - - FnSambaSharesEnable({ name: pool.name, id: pool.id, altroot: (pool.altroot ? true : false), readonly: pool.readonly }, { name: null, force: true }, { restart: false }, { refresh: false, silent: false }) - .finally(function () { - if (modal.hide) { - $("#modal-storagepools-import").modal("hide"); - - setTimeout(function () { - FnStoragePoolsGet(); - }, 200); - } - }); - }); - } else { - $("#spinner-storagepools-import span").text("Creating Samba shares..."); - - FnSambaSharesEnable({ name: pool.name, id: pool.id, altroot: (pool.altroot ? true : false), readonly: pool.readonly }, { name: null, force: true }, { restart: false }, { refresh: false, silent: false }) - .finally(function () { - if (modal.hide) { - $("#modal-storagepools-import").modal("hide"); - - setTimeout(function () { - FnStoragePoolsGet(); - }, 200); - } - }); - } - } else { - if (modal.hide) { - $("#modal-storagepools-import").modal("hide"); - - setTimeout(function () { - FnStoragePoolsGet(); - }, 200); - } - } - }); - } else { - if (zfsmanager.configuration.samba.manage) { - if (!pool.readonly) { - $("#spinner-storagepools-import span").text("Disabling Samba share inheritance..."); - - FnFileSystemShareSmbInheritedDisable({ name: pool.name, id: pool.id, altroot: (pool.altroot ? true : false) }, { name: null }, { disable: false }) - .finally(function () { - $("#spinner-storagepools-import span").text("Creating Samba shares..."); - - FnSambaSharesEnable({ name: pool.name, id: pool.id, altroot: (pool.altroot ? true : false), readonly: pool.readonly }, { name: null, force: true }, { restart: false }, { refresh: false, silent: false }) - .finally(function () { - if (modal.hide) { - $("#modal-storagepools-import").modal("hide"); - - setTimeout(function () { - FnStoragePoolsGet(); - }, 200); - } - }); - }); - } else { - $("#spinner-storagepools-import span").text("Creating Samba shares..."); - - FnSambaSharesEnable({ name: pool.name, id: pool.id, altroot: (pool.altroot ? true : false), readonly: pool.readonly }, { name: null, force: true }, { restart: false }, { refresh: false, silent: false }) - .finally(function () { - if (modal.hide) { - $("#modal-storagepools-import").modal("hide"); - - setTimeout(function () { - FnStoragePoolsGet(); - }, 200); - } - }); - } - } else { - if (modal.hide) { - $("#modal-storagepools-import").modal("hide"); - - setTimeout(function () { - FnStoragePoolsGet(); - }, 200); - } - } - } - } else { - if (modal.hide) { - $("#modal-storagepools-import").modal("hide"); - - setTimeout(function () { - FnStoragePoolsGet(); - }, 200); - } - } - }); -} - -function FnStoragePoolRefreservationSet(pool = { name, id }, filesystem = { refreservation }) { - let process = { - command: [((zfsmanager.user.admin || !zfsmanager.user.name) ? "pkexec" : ""), "/sbin/zfs", "set", "refreservation=" + filesystem.refreservation, pool.name] - }; - - FnConsole.log[2]("Storage Pools, Refreservation, Set: In Progress"); - FnConsole.log[3](FnConsoleCommand({ command: process.command })); - - return cockpit.spawn(process.command, { err: "out" }) - .done(function () { - FnConsole.log[2]("Storage Pools, Refreservation, Set: Success, Pool: " + pool.name); - }) - .fail(function (message, data) { - FnConsole.warn("Storage Pools, Refreservation, Set: Failed, Pool: " + pool.name + ", Message: " + (data ? data : message)); - }); -} - -function FnStoragePoolRefresh(pool = { name, id }, refresh = { storagepool: true, filesystems: false, snapshots: false, status: false }) { - if (zfsmanager.configuration.zfs.storagepool.refreshall || refresh.storagepool) { - FnStoragePoolRefreshCommand({ name: pool.name, id: pool.id }); - } - - setTimeout(function () { - if (zfsmanager.configuration.zfs.storagepool.refreshall) { - FnStoragePoolRefreshAutoDisable({ name: pool.name, id: pool.id }); - } - - if (zfsmanager.configuration.zfs.storagepool.refreshall || refresh.filesystems) { - $("#btn-storagepool-filesystems-create-" + pool.id).prop("disabled", true); - $("#btn-storagepool-filesystems-refresh-" + pool.id).prop("disabled", true); - $("[id^=btn-storagepool-filesystem-dropdown-" + pool.id + "]").addClass("disabled"); - $("#paneltitle-storagepool-filesystems-" + pool.id).addClass("hidden"); - $("#spinner-storagepool-filesystems-" + pool.id).removeClass("hidden"); - - FnFileSystemsGet({ name: pool.name, id: pool.id }); - } - - if (zfsmanager.configuration.zfs.storagepool.refreshall || refresh.snapshots) { - $("#btn-storagepool-snapshots-create-" + pool.id).prop("disabled", true); - $("#btn-storagepool-snapshots-refresh-" + pool.id).prop("disabled", true); - $("[id^=btn-storagepool-snapshot-dropdown-" + pool.id + "]").addClass("disabled"); - $("#paneltitle-storagepool-snapshots-" + pool.id).addClass("hidden"); - $("#spinner-storagepool-snapshots-" + pool.id).removeClass("hidden"); - - FnSnapshotsGet({ name: pool.name, id: pool.id }); - } - - if (zfsmanager.configuration.zfs.storagepool.refreshall || refresh.status) { - $("#btn-storagepool-status-refresh-" + pool.id).prop("disabled", true); - $("[id^=btn-storagepool-status-dropdown-][id$=" + pool.id + "]").addClass("disabled"); - $("#paneltitle-storagepool-status-" + pool.id).addClass("hidden"); - $("#spinner-storagepool-status-" + pool.id).removeClass("hidden"); - $("#spinner-storagepool-status-0-" + pool.id).removeClass("hidden"); - - FnStatusGet({ name: pool.name, id: pool.id }); - } - }, 200); -} - -function FnStoragePoolRefreshAutoDisable(pool = { name, id }) { - if ($("#tr-storagepool-" + pool.id).attr("data-pool-refresh-id") != "") { - FnConsole.log[2]("Storage Pools, Refresh, Auto: Disabled, Pool: " + pool.name); - } - - clearInterval($("#tr-storagepool-" + pool.id).attr("data-pool-refresh-id")); - - $("#tr-storagepool-" + pool.id).attr("data-pool-refresh-id", ""); - $("#btn-storagepool-status-refresh-" + pool.id).text("Refresh"); -} - -function FnStoragePoolRefreshCommand(pool = { name, id }) { - let process = { - command: ["/sbin/zpool", "list", "-H", "-o", "guid,health,size,alloc,free,fragmentation,autotrim,version,feature@allocation_classes,feature@async_destroy,feature@bookmark_v2,feature@bookmarks,feature@device_removal,feature@edonr,feature@embedded_data,feature@empty_bpobj,feature@enabled_txg,feature@encryption,feature@extensible_dataset,feature@filesystem_limits,feature@hole_birth,feature@large_blocks,feature@large_dnode,feature@lz4_compress,feature@multi_vdev_crash_dump,feature@obsolete_counts,feature@project_quota,feature@resilver_defer,feature@sha512,feature@skein,feature@spacemap_histogram,feature@spacemap_v2,feature@userobj_accounting,feature@zpool_checkpoint", "-p", pool.name] - }; - - FnConsole.log[2]("Storage Pools, Refresh: In Progress, Pool: " + pool.name); - FnConsole.log[3](FnConsoleCommand({ command: process.command })); - - return cockpit.spawn(process.command, { err: "out" }) - .done(function (data) { - FnConsole.log[4](FnConsoleVerbose({ data: data, message: "Storage Pools, Refresh:" })); - - pool.properties = data.trim().split(/\t/g).filter(v => v); - - //0=guid, 1=health, 2=size, 3=alloc, 4=free, 5=fragmentation, 6=autotrim, 7=version, 8=feature@allocation_classes, 9=feature@async_destroy, 10=feature@bookmark_v2, 11=feature@bookmarks, 12=feature@device_removal, 13=feature@edonr, 14=feature@embedded_data, 15=feature@empty_bpobj, 16=feature@enabled_txg, 17=feature@encryption, 18=feature@extensible_dataset, 19=feature@filesystem_limits, 20=feature@hole_birth, 21=feature@large_blocks, 22=feature@large_dnode, 23=feature@lz4_compress, 24=feature@multi_vdev_crash_dump, 25=feature@obsolete_counts, 26=feature@project_quota, 27=feature@resilver_defer, 28=feature@sha512, 29=feature@skein, 30=feature@spacemap_histogram, 31=feature@spacemap_v2, 32=feature@userobj_accounting, 33=feature@zpool_checkpoint - - pool.allocated = FnFormatBytes({ base2: true, decimals: 2, value: pool.properties[3] }); - pool.allocatedpercent = FnRound({ decimals: 2, value: (pool.properties[3] / pool.properties[2]) * 100 }); - pool.autotrim = (pool.properties[6].toLowerCase() == "on" ? true : false); - pool.boot = (zfsmanager.zfs.storagepool.boot && pool.name == zfsmanager.zfs.storagepool.boot ? true : false); - pool.feature = { - allocation_classes: (/active|enabled/gi.test(pool.properties[8]) ? true : false), - async_destroy: (/active|enabled/gi.test(pool.properties[9]) ? true : false), - bookmark_v2: (/active|enabled/gi.test(pool.properties[10]) ? true : false), - bookmarks: (/active|enabled/gi.test(pool.properties[11]) ? true : false), - device_removal: (/active|enabled/gi.test(pool.properties[12]) ? true : false), - edonr: (/active|enabled/gi.test(pool.properties[13]) ? true : false), - embedded_data: (/active|enabled/gi.test(pool.properties[14]) ? true : false), - empty_bpobj: (/active|enabled/gi.test(pool.properties[15]) ? true : false), - enabled_txg: (/active|enabled/gi.test(pool.properties[16]) ? true : false), - encryption: (/active|enabled/gi.test(pool.properties[17]) ? true : false), - extensible_dataset: (/active|enabled/gi.test(pool.properties[18]) ? true : false), - filesystem_limits: (/active|enabled/gi.test(pool.properties[19]) ? true : false), - hole_birth: (/active|enabled/gi.test(pool.properties[20]) ? true : false), - large_blocks: (/active|enabled/gi.test(pool.properties[21]) ? true : false), - large_dnode: (/active|enabled/gi.test(pool.properties[22]) ? true : false), - lz4_compress: (/active|enabled/gi.test(pool.properties[23]) ? true : false), - multi_vdev_crash_dump: (/active|enabled/gi.test(pool.properties[24]) ? true : false), - obsolete_counts: (/active|enabled/gi.test(pool.properties[25]) ? true : false), - project_quota: (/active|enabled/gi.test(pool.properties[26]) ? true : false), - resilver_defer: (/active|enabled/gi.test(pool.properties[27]) ? true : false), - sha512: (/active|enabled/gi.test(pool.properties[28]) ? true : false), - skein: (/active|enabled/gi.test(pool.properties[29]) ? true : false), - spacemap_histogram: (/active|enabled/gi.test(pool.properties[30]) ? true : false), - spacemap_v2: (/active|enabled/gi.test(pool.properties[31]) ? true : false), - userobj_accounting: (/active|enabled/gi.test(pool.properties[32]) ? true : false), - zpool_checkpoint: (/active|enabled/gi.test(pool.properties[33]) ? true : false) - }; - pool.fragmentation = (pool.properties[5] == "-" ? 0 : pool.properties[5]); - pool.free = FnFormatBytes({ base2: true, decimals: 2, value: pool.properties[4] }); - pool.freepercent = FnRound({ decimals: 2, value: (pool.properties[4] / pool.properties[2]) * 100 }); - pool.guid = pool.properties[0]; - pool.health = pool.properties[1]; - pool.healthicon = FnStoragePoolHealthIcon({ health: pool.health }); - pool.root = (zfsmanager.zfs.storagepool.root && pool.name == zfsmanager.zfs.storagepool.root ? true : false); - pool.size = FnFormatBytes({ base2: true, decimals: 2, value: pool.properties[2] }); - pool.upgrade = ($.isNumeric(pool.properties[6] && !pool.boot) ? true : false); - pool.version = pool.properties[7]; - - //Upgrade available if a requested feature flag returns false - if (!pool.boot) { - for (var x in pool.feature) { - if (!pool.feature[x] && !pool.upgrade) { - pool.upgrade = true; - } - } - } - - if (pool.upgrade) { - $("#span-storagepool-upgrade-" + pool.id).removeClass("hidden"); - } else { - $("#span-storagepool-upgrade-" + pool.id).addClass("hidden"); - } - - $("#div-storagepool-health-" + pool.id).empty().html(` ` + pool.health); - $("#div-storagepool-size-" + pool.id).text(pool.size); - $("#div-storagepool-allocated-" + pool.id).text(pool.allocated); - $("#div-storagepool-free-" + pool.id).text(pool.free); - $("#div-storagepool-fragmentation-" + pool.id).text(pool.fragmentation + " %"); - - $("#progressbar-storagepool-allocated-" + pool.id).attr("aria-valuenow", pool.allocatedpercent); - $("#progressbar-storagepool-allocated-" + pool.id).attr("title", pool.allocatedpercent + "% Allocated"); - $("#progressbar-storagepool-allocated-" + pool.id).attr("data-original-title", pool.allocatedpercent + "% Allocated"); - $("#progressbar-storagepool-allocated-" + pool.id).css("width", pool.allocatedpercent + "%"); - $("#progressbar-storagepool-allocated-" + pool.id + " .sr-only").text(pool.allocatedpercent + "% Allocated"); - - $("#progressbar-storagepool-free-" + pool.id).attr("aria-valuenow", pool.freepercent); - $("#progressbar-storagepool-free-" + pool.id).attr("title", pool.freepercent + "% Free"); - $("#progressbar-storagepool-free-" + pool.id).attr("data-original-title", pool.freepercent + "% Free"); - $("#progressbar-storagepool-free-" + pool.id).css("width", pool.freepercent + "%"); - $("#progressbar-storagepool-free-" + pool.id + " .sr-only").text(pool.freepercent + "% Free"); - - $("#tr-storagepool-" + pool.id).attr("data-pool-autotrim", pool.autotrim); - $("#tr-storagepool-" + pool.id).attr("data-pool-feature-allocation_classes", pool.feature.allocation_classes); - $("#tr-storagepool-" + pool.id).attr("data-pool-feature-device_removal", pool.feature.device_removal); - $("#tr-storagepool-" + pool.id).attr("data-pool-feature-edonr", pool.feature.edonr); - $("#tr-storagepool-" + pool.id).attr("data-pool-feature-encryption", pool.feature.encryption); - $("#tr-storagepool-" + pool.id).attr("data-pool-feature-large_blocks", pool.feature.large_blocks); - $("#tr-storagepool-" + pool.id).attr("data-pool-feature-lz4_compress", pool.feature.lz4_compress); - $("#tr-storagepool-" + pool.id).attr("data-pool-feature-resilver_defer", pool.feature.resilver_defer); - $("#tr-storagepool-" + pool.id).attr("data-pool-feature-sha512", pool.feature.sha512); - $("#tr-storagepool-" + pool.id).attr("data-pool-feature-skein", pool.feature.skein); - $("#tr-storagepool-" + pool.id).attr("data-pool-guid", pool.guid); - $("#tr-storagepool-" + pool.id).attr("data-pool-version", pool.version); - - FnConsole.log[1]("Storage Pools, Refresh: Success, Pool: " + pool.name); - }) - .fail(function (message, data) { - FnConsole.warn("Storage Pools, Refresh: Failed, Pool: " + pool.name + ", Message: " + (data ? data : message)); - }); -} - -function FnStoragePoolRegenerateGuid(pool = { name, id }, modal = { name, id }) { - let process = { - command: ["/sbin/zpool", "reguid", pool.name] - }; - - FnConsole.log[2]("Storage Pools, Regenerate GUID: In Progress, Pool: " + pool.name); - FnConsole.log[3](FnConsoleCommand({ command: process.command })); - - $("#spinner-" + modal.name + "-" + modal.id + " span").text("Regenerating storage pool GUID..."); - - return cockpit.spawn(process.command, { err: "out", superuser: "require" }) - .done(function () { - FnDisplayAlert({ status: "success", title: "Storage Pool GUID successfully regenerated", description: pool.name, breakword: false }, { name: "storagepool-regenerateguid", id: pool.id, timeout: 4 }); - - FnConsole.log[1]("Storage Pools, Regenerate GUID: Success, Pool: " + pool.name); - }) - .fail(function (message, data) { - FnDisplayAlert({ status: "danger", title: "Storage Pool GUID could not be regenerated", description: pool.name, breakword: false }, { name: "storagepool-regenerateguid", id: pool.id, timeout: 4 }); - - FnConsole.warn("Storage Pools, Regenerate GUID: Failed, Pool: " + pool.name + ", Message: " + (data ? data : message)); - }) - .finally(function () { - $("#modal-" + modal.name + "-" + modal.id).modal("hide"); - - setTimeout(function () { - FnStoragePoolRefresh({ name: pool.name, id: pool.id }, { storagepool: true, filesystems: false, snapshots: false, status: true }); - }, 200); - });; -} - -function FnStoragePoolResilver(pool = { name, id }, modal = { name, id }) { - let process = { - command: ["/sbin/zpool", "resilver", pool.name] - }; - - FnConsole.log[1]("Storage Pools, Resilver, Start: In Progress, Pool: " + pool.name); - FnConsole.log[3](FnConsoleCommand({ command: process.command })); - - $("#spinner-" + modal.name + "-" + modal.id + " span").text("Starting storage pool resilver..."); - - return cockpit.spawn(process.command, { err: "out", superuser: "require" }) - .done(function () { - FnDisplayAlert({ status: "success", title: "Storage Pool resilver successfully started", description: pool.name, breakword: false }, { name: "storagepool-resilver", id: pool.id, timeout: 4 }); - - FnConsole.log[1]("Storage Pools, Resilver, Start: Success, Pool: " + pool.name); - }) - .fail(function (message, data) { - FnDisplayAlert({ status: "danger", title: "Storage Pool resilver could not be started", description: pool.name, breakword: false }, { name: "storagepool-resilver", id: pool.id, timeout: 4 }); - - FnConsole.warn("Storage Pools, Resilver, Start: Failed, Pool: " + pool.name + ", Message: " + (data ? data : message)); - }) - .finally(function () { - $("#modal-" + modal.name + "-" + modal.id).modal("hide"); - - setTimeout(function () { - FnStoragePoolRefresh({ name: pool.name, id: pool.id }, { storagepool: true, filesystems: false, snapshots: false, status: true }); - }, 200); - }); -} - -function FnStoragePoolScrubPause(pool = { name, id }, display = { refresh: true }) { - let process = { - command: ["/sbin/zpool", "scrub", "-p", pool.name] - }; - - FnConsole.log[2]("Storage Pools, Scrub, Pause: In Progress, Pool: " + pool.name); - FnConsole.log[3](FnConsoleCommand({ command: process.command })); - - return cockpit.spawn(process.command, { err: "out", superuser: "require" }) - .done(function () { - FnDisplayAlert({ status: "success", title: "Storage Pool scrub successfully paused", description: pool.name, breakword: false }, { name: "storagepool-scrub-pause", id: pool.id, timeout: 4 }); - - FnConsole.log[1]("Storage Pools, Scrub, Pause: Success, Pool: " + pool.name); - }) - .fail(function (message, data) { - FnDisplayAlert({ status: "danger", title: "Storage Pool scrub could not be paused", description: pool.name, breakword: false }, { name: "storagepool-scrub-pause", id: pool.id, timeout: 4 }); - - FnConsole.warn("Storage Pools, Scrub, Pause: Failed, Pool: " + pool.name + ", Message: " + (data ? data : message)); - }) - .finally(function () { - if (display.refresh) { - setTimeout(function () { - FnStoragePoolRefresh({ name: pool.name, id: pool.id }, { storagepool: true, filesystems: false, snapshots: false, status: true }); - }, 200); - } - });; -} - -function FnStoragePoolScrubStart(pool = { name, id }, scrub = { resume: false }, display = { refresh: true }) { - let process = { - command: ["/sbin/zpool", "scrub", pool.name] - }; - - FnConsole.log[2]("Storage Pools, Scrub, " + (scrub.resume ? "Resume" : "Start") + ": In Progress, Pool: " + pool.name); - FnConsole.log[3](FnConsoleCommand({ command: process.command })); - - return cockpit.spawn(process.command, { err: "out", superuser: "require" }) - .done(function () { - FnDisplayAlert({ status: "success", title: "Storage Pool scrub successfully " + (scrub.resume ? "resumed" : "started"), description: pool.name, breakword: false }, { name: "storagepool-scrub-start", id: pool.id, timeout: 4 }); - - FnConsole.log[1]("Storage Pools, Scrub, " + (scrub.resume ? "Resume" : "Start") + ": Success, Pool: " + pool.name); - }) - .fail(function (message, data) { - if (/currently scrubbing/gi.test(data)) { //Start scrub will fail if the storage pool has already initiated scrub - FnDisplayAlert({ status: "success", title: "Storage Pool scrub successfully " + (scrub.resume ? "resumed" : "started"), description: pool.name, breakword: false }, { name: "storagepool-scrub-start", id: pool.id, timeout: 4 }); - - FnConsole.log[1]("Storage Pools, Scrub, " + (scrub.resume ? "Resume" : "Start") + ": Success, Pool: " + pool.name); - } else { - if (/currently resilvering/gi.test(data)) { //Start scrub will fail if the storage pool has initiated resilver - FnDisplayAlert({ status: "warning", title: "Storage Pool scrub could not be " + (scrub.resume ? "resumed" : "started") + ". Resilver in progress", description: pool.name, breakword: false }, { name: "storagepool-scrub-start", id: pool.id, timeout: 4 }); - } else { - FnDisplayAlert({ status: "danger", title: "Storage Pool scrub could not be " + (scrub.resume ? "resumed" : "started"), description: pool.name, breakword: false }, { name: "storagepool-scrub-start", id: pool.id, timeout: 4 }); - } - - FnConsole.warn("Storage Pools, Scrub, " + (scrub.resume ? "Resume" : "Start") + ": Failed, Pool: " + pool.name + ", Message: " + (data ? data : message)); - } - }) - .finally(function () { - if (display.refresh) { - setTimeout(function () { - FnStoragePoolRefresh({ name: pool.name, id: pool.id }, { storagepool: true, filesystems: false, snapshots: false, status: true }); - }, 200); - } - }); -} - -function FnStoragePoolScrubStop(pool = { name, id }, display = { refresh: true }) { - let process = { - command: ["/sbin/zpool", "scrub", "-s", pool.name] - }; - - FnConsole.log[2]("Storage Pools, Scrub, Stop: In Progress, Pool: " + pool.name); - FnConsole.log[3](FnConsoleCommand({ command: process.command })); - - return cockpit.spawn(process.command, { err: "out", superuser: "require" }) - .done(function () { - FnDisplayAlert({ status: "success", title: "Storage Pool scrub successfully stopped", description: pool.name, breakword: false }, { name: "storagepool-scrub-stop", id: pool.id, timeout: 4 }); - - FnConsole.log[1]("Storage Pools, Scrub, Stop: Success, Pool: " + pool.name); - }) - .fail(function (message, data) { - FnDisplayAlert({ status: "danger", title: "Storage Pool scrub could not be stopped", description: pool.name, breakword: false }, { name: "storagepool-scrub-stop", id: pool.id, timeout: 4 }); - - FnConsole.warn("Storage Pools, Scrub, Stop: Failed, Pool: " + pool.name + ", Message: " + (data ? data : message)); - }) - .finally(function () { - if (display.refresh) { - setTimeout(function () { - FnStoragePoolRefresh({ name: pool.name, id: pool.id }, { storagepool: true, filesystems: false, snapshots: false, status: true }); - }, 200); - } - });; -} - -function FnStoragePoolSelinuxContextsSambaSet(pool = { name, id }, display = { silent: false }) { - let process = { - command: ["/sbin/zfs", "list", "-H", "-o", "name", "-r", "-t", "filesystem", pool.name], - promise: cockpit.defer() - }; - - FnConsole.log[3](FnConsoleCommand({ command: process.command })); - - cockpit.spawn(process.command, { err: "out" }) - .done(function (data) { - FnConsole.log[4](FnConsoleVerbose({ data: data, message: "Storage Pools, SELinux Contexts, Samba, Set:" })); - - let filesystems = data.split(/\n/g).filter(v => v); - let promise = Promise.resolve(); - - if (filesystems.length > 0) { - filesystems.forEach((_value, _index) => { - promise = promise.then(_ => new Promise(resolve => - setTimeout(function () { - FnFileSystemSelinuxContextsSambaSet({ name: pool.name, id: pool.id }, { name: _value }) - .finally(function () { - if (_index == (filesystems.length - 1)) { - if (!display.silent) { - FnDisplayAlert({ status: "success", title: "SELinux contexts for Samba successfully configured", description: pool.name, breakword: false }, { name: "selinux-enable", id: pool.id, timeout: 4 }); - } - - process.promise.resolve(); - } - }); - - resolve(); - }, 500) - )); - }); - } else { - if (!display.silent) { - FnDisplayAlert({ status: "success", title: "SELinux contexts for Samba successfully configured", description: pool.name, breakword: false }, { name: "selinux-enable", id: pool.id, timeout: 4 }); - } - - process.promise.resolve(); - } - }) - .fail(function (message, data) { - if (!display.silent) { - FnDisplayAlert({ status: "danger", title: "SELinux contexts for Samba could not be configured", description: pool.name, breakword: false }, { name: "selinux-enable", id: pool.id, timeout: 4 }); - } - - FnConsole.warn("Storage Pools, SELinux Contexts, Samba, Set: Failed, Pool: " + pool.name + ", Message: " + (data ? data : message)); - - process.promise.resolve(); - }); - - return process.promise.promise(); -} - -function FnStoragePoolSizeGet(pool = { name, id }) { - let process = { - command: ["/sbin/zpool", "get", "size", "-H", "-o", "value", "-p", pool.name] - }; - - FnConsole.log[2]("Storage Pools, Size, Get: In Progress, Pool: " + pool.name); - FnConsole.log[3](FnConsoleCommand({ command: process.command })); - - return cockpit.spawn(process.command, { err: "out" }) - .done(function () { - FnConsole.log[2]("Storage Pools, Size, Get: Success, Pool: " + pool.name); - }) - .fail(function (message, data) { - FnConsole.warn("Storage Pools, Size. Get: Failed, Pool: " + pool.name + ", Message: " + (data ? data : message)); - }); -} - -function FnStoragePoolSpinnerHide(pool = { name, id }) { - if ($("#tr-storagepool-" + pool.id).attr("data-pool-refresh-filesystems") == "true" && $("#tr-storagepool-" + pool.id).attr("data-pool-refresh-snapshots") == "true" && $("#tr-storagepool-" + pool.id).attr("data-pool-refresh-status") == "true") { - setTimeout(function () { - $("#spinner-storagepool-" + pool.id).addClass("hidden"); - $("#listingcthead-storagepool-" + pool.id).removeClass("hidden"); - $("#listingctbody-storagepool-" + pool.id).removeClass("hidden"); - }, 200); - } -} - -function FnStoragePoolTrimCancel(pool = { name, id }, disk = { id }) { - let process = { - command: ["/sbin/zpool", "trim", "-c", pool.name] - }; - - if (disk.id) { - process.command.push(disk.id); - } - - FnConsole.log[2]("Storage Pools, " + (disk.id ? "Disk, " : "") + "TRIM, Cancel: In Progress, Pool: " + pool.name + (disk.id ? ", Disk: " + disk.id : "")); - FnConsole.log[3](FnConsoleCommand({ command: process.command })); - - return cockpit.spawn(process.command, { err: "out", superuser: "require" }) - .done(function () { - FnDisplayAlert({ status: "success", title: (disk.id ? "Disk" : "Storage Pool") + " TRIM successfully cancelled", description: (disk.id ? disk.id : pool.name), breakword: false }, { name: "storagepool-" + (disk.id ? "disk-" : "") + "trim-cancel", id: pool.id, timeout: 4 }); - - FnConsole.log[1]("Storage Pools, " + (disk.id ? "Disk, " : "") + "TRIM, Cancel: Success, Pool: " + pool.name + (disk.id ? ", Disk: " + disk.id : "")); - }) - .fail(function (message, data) { - FnDisplayAlert({ status: "danger", title: (disk.id ? "Disk" : "Storage Pool") + " TRIM could not be cancelled", description: (disk.id ? disk.id : pool.name), breakword: false }, { name: "storagepool-" + (disk.id ? "disk-" : "") + "trim-cancel", id: pool.id, timeout: 4 }); - - FnConsole.warn("Storage Pools, " + (disk.id ? "Disk, " : "") + "TRIM, Cancel: Failed, Pool: " + pool.name + (disk.id ? ", Disk: " + disk.id : "") + ", Message: " + (data ? data : message)); - }) - .finally(function () { - setTimeout(function () { - FnStoragePoolRefresh({ name: pool.name, id: pool.id }, { storagepool: true, filesystems: false, snapshots: false, status: true }); - }, 200); - }); -} - -function FnStoragePoolTrimStart(pool = { name, id }, disk = { id }, trim = { resume: false, secure: false }, modal = { name, id }) { - let process = { - command: ["/sbin/zpool", "trim", pool.name] - }; - - if (trim.secure) { - process.command.splice(2, 0, "-d"); - } - if (disk.id) { - process.command.push(disk.id); - } - - FnConsole.log[2]("Storage Pools, " + (disk.id ? "Disk, " : "") + "TRIM, " + (trim.resume ? "Resume" : "Start") + ": In Progress, Pool: " + pool.name + (disk.id ? ", Disk: " + disk.id : "")); - FnConsole.log[3](FnConsoleCommand({ command: process.command })); - - if (!trim.resume) { - $("#spinner-" + modal.name + "-" + modal.id + " span").text("Starting " + (disk.id ? "disk" : "storage pool") + " TRIM..."); - } - - return cockpit.spawn(process.command, { err: "out", superuser: "require" }) - .done(function () { - FnDisplayAlert({ status: "success", title: (disk.id ? "Disk" : "Storage Pool") + " TRIM successfully " + (trim.resume ? "resumed" : "started"), description: (disk.id ? disk.id : pool.name), breakword: false }, { name: "storagepool-" + (disk.id ? "disk-" : "") + "trim-start", id: pool.id, timeout: 4 }); - - FnConsole.log[1]("Storage Pools, " + (disk.id ? "Disk, " : "") + "TRIM, " + (trim.resume ? "Resume" : "Start") + ": Success, Pool: " + pool.name + (disk.id ? ", Disk: " + disk.id : "")); - }) - .fail(function (message, data) { - FnDisplayAlert({ status: "danger", title: (disk.id ? "Disk" : "Storage Pool") + " TRIM could not be " + (trim.resume ? "resumed" : "started"), description: (disk.id ? disk.id : pool.name), breakword: false }, { name: "storagepool-" + (disk.id ? "disk-" : "") + "trim-start", id: pool.id, timeout: 4 }); - - FnConsole.warn("Storage Pools, " + (disk.id ? "Disk, " : "") + "TRIM, " + (trim.resume ? "Resume" : "Start") + ": Failed, Pool: " + pool.name + (disk.id ? ", Disk: " + disk.id : "") + ", Message: " + (data ? data : message)); - }) - .finally(function () { - if (modal.name && modal.id) { - $("#modal-" + modal.name + "-" + modal.id).modal("hide"); - } - - setTimeout(function () { - FnStoragePoolRefresh({ name: pool.name, id: pool.id }, { storagepool: true, filesystems: false, snapshots: false, status: true }); - }, 200); - }); -} - -function FnStoragePoolTrimSuspend(pool = { name, id }, disk = { id }) { - let process = { - command: ["/sbin/zpool", "trim", "-s", pool.name] - }; - - if (disk.id) { - process.command.push(disk.id); - } - - FnConsole.log[2]("Storage Pools, " + (disk.id ? "Disk, " : "") + "TRIM, Suspend: In Progress, Pool: " + pool.name + (disk.id ? ", Disk: " + disk.id : "")); - FnConsole.log[3](FnConsoleCommand({ command: process.command })); - - return cockpit.spawn(process.command, { err: "out", superuser: "require" }) - .done(function () { - FnDisplayAlert({ status: "success", title: (disk.id ? "Disk" : "Storage Pool") + " TRIM successfully suspended", description: (disk.id ? disk.id : pool.name), breakword: false }, { name: "storagepool-" + (disk.id ? "disk-" : "") + "trim-suspend", id: pool.id, timeout: 4 }); - - FnConsole.log[1]("Storage Pools, " + (disk.id ? "Disk, " : "") + "TRIM, Suspend: Success, Pool: " + pool.name + (disk.id ? ", Disk: " + disk.id : "")); - }) - .fail(function (message, data) { - FnDisplayAlert({ status: "danger", title: (disk.id ? "Disk" : "Storage Pool") + " TRIM could not be suspended", description: (disk.id ? disk.id : pool.name), breakword: false }, { name: "storagepool-" + (disk.id ? "disk-" : "") + "trim-suspend", id: pool.id, timeout: 4 }); - - FnConsole.warn("Storage Pools, " + (disk.id ? "Disk, " : "") + "TRIM, Suspend: Failed, Pool: " + pool.name + (disk.id ? ", Disk: " + disk.id : "") + ", Message: " + (data ? data : message)); - }) - .finally(function () { - setTimeout(function () { - FnStoragePoolRefresh({ name: pool.name, id: pool.id }, { storagepool: true, filesystems: false, snapshots: false, status: true }); - }, 200); - }); -} - -function FnStoragePoolUpgrade(pool = { name, id }, modal = { name, id }) { - let process = { - command: ["/sbin/zpool", "upgrade", pool.name] - }; - - FnConsole.log[1]("Storage Pools, Upgrade: In Progress, Pool: " + pool.name); - FnConsole.log[3](FnConsoleCommand({ command: process.command })); - - $("#spinner-" + modal.name + "-" + modal.id + " span").text("Upgrading storage pool..."); - - return cockpit.spawn(process.command, { err: "out", superuser: "require" }) - .done(function (data, message) { - FnConsole.log[4](FnConsoleVerbose({ data: data, message: "Storage Pools, Upgrade:" })); - - if (/Successfully upgraded|Enabled the following features/gi.test(data)) { - FnDisplayAlert({ status: "success", title: "Storage Pool successfully upgraded", description: pool.name, breakword: false }, { name: "storagepool-upgrade", id: pool.id, timeout: 4 }); - - FnConsole.log[1]("Storage Pools, Upgrade: Success, Pool: " + pool.name); - } else { - FnStoragePoolUpgradeFail({ name: pool.name, id: pool.id }, { data: data, message: message }); - } - }) - .fail(function (message, data) { - FnStoragePoolUpgradeFail({ name: pool.name, id: pool.id }, { data: data, message: message }); - }) - .finally(function () { - $("#modal-" + modal.name + "-" + modal.id).modal("hide"); - - setTimeout(function () { - FnStoragePoolRefresh({ name: pool.name, id: pool.id }, { storagepool: true, filesystems: true , snapshots: true, status: true }); - }, 200); - });; -} - -function FnStoragePoolUpgradeFail(pool = { name, id }, process = { data, message }) { - FnDisplayAlert({ status: "danger", title: "Storage Pool could not be upgraded", description: pool.name, breakword: false }, { name: "storagepool-upgrade", id: pool.id, timeout: 4 }); - - FnConsole.warn("Storage Pools, Upgrade: Failed, Pool: " + pool.name + ", Message: " + (process.data ? process.data : process.message)); -} - -function FnStoragePoolVirtualDeviceAdd(pool = { name, id, force: false, virtualdevice }, disks = { id: [] }, modal = { name, id }) { - let process = { - command: [((zfsmanager.user.admin || !zfsmanager.user.name) ? "pkexec" : ""), "/sbin/zpool", "add", pool.name] - }; - - modal.hide = true; - - if (pool.force) { - process.command.splice(3, 0, "-f"); - } - if (pool.virtualdevice) { - if (pool.virtualdevice == "dedup mirror") { - process.command.push("dedup"); - process.command.push("mirror"); - } else if (pool.virtualdevice == "log mirror") { - process.command.push("log"); - process.command.push("mirror"); - } else if (pool.virtualdevice == "special mirror") { - process.command.push("special"); - process.command.push("mirror"); - } else { - process.command.push(pool.virtualdevice); - } - } - - disks.id.forEach(_value => _value && process.command.push(_value)); - - FnConsole.log[1]("Storage Pools, Virtual Device, Add: In Progress, Pool: " + pool.name); - FnConsole.log[3](FnConsoleCommand({ command: process.command })); - - $("#spinner-" + modal.name + "-" + modal.id + " span").text("Adding virtual device..."); - - return cockpit.spawn(process.command, { err: "out", superuser: "require" }) - .done(function () { - FnDisplayAlert({ status: "success", title: "Virtual Device successfully added to Storage Pool", description: pool.name, breakword: false }, { name: "storagepool-virtualdevice-add", id: pool.id, timeout: 4 }); - - FnConsole.log[1]("Storage Pools, Virtual Device, Add: Success, Pool: " + pool.name); - }) - .fail(function (message, data) { - if (/contains devices of different sizes/gi.test(data)) { - modal.hide = false; - - $("#validationwrapper-" + modal.name + "-disks-" + modal.id).addClass("has-error"); - $("#helpblock-" + modal.name + "-disks-" + modal.id).addClass("has-error").removeClass("hidden").text("Disks are of different sizes. Forcefully add virtual device to override."); - } else if (/mismatched replication level/gi.test(data)) { - modal.hide = false; - - $("#validationwrapper-" + modal.name + "-disks-" + modal.id).addClass("has-error"); - $("#helpblock-" + modal.name + "-disks-" + modal.id).addClass("has-error").removeClass("hidden").text("Mismatched replication level. Forcefully add virtual device to override."); - } - - if (!modal.hide) { - $("#spinner-" + modal.name + "-" + modal.id).addClass("hidden"); - $("#btn-" + modal.name + "-apply-" + modal.id).prop("disabled", false); - - $("[id^=btn-storagepool-status-dropdown-][id$=" + pool.id + "]").removeClass("disabled"); - $("#spinner-storagepool-status-" + modal.id).addClass("hidden"); - } - - if (modal.hide) { - FnDisplayAlert({ status: "danger", title: "Virtual Device could not be added to Storage Pool", description: pool.name, breakword: false }, { name: "storagepool-virtualdevice-add", id: pool.id, timeout: 4 }); - } - - FnConsole.warn("Storage Pools, Virtual Device, Add: Failed, Pool: " + pool.name + ", Message: " + (data ? data : message)); - }) - .finally(function () { - if (modal.hide) { - $("#modal-" + modal.name + "-" + modal.id).modal("hide"); - - setTimeout(function () { - FnStoragePoolRefresh({ name: pool.name, id: pool.id }, { storagepool: true, filesystems: true, snapshots: true, status: true }); - }, 200); - } - }); -} - -function FnStoragePoolVirtualDeviceClear(pool = { name, id }, virtualdevice = { id }, modal = { name, id }) { - let process = { - command: ["/sbin/zpool", "clear", pool.name, virtualdevice.id] - }; - - FnConsole.log[2]("Storage Pools, Virtual Device, Clear Errors: In Progress, Pool: " + pool.name + ", Virtual Device: " + virtualdevice.id); - FnConsole.log[3](FnConsoleCommand({ command: process.command })); - - $("#spinner-" + modal.name + "-" + modal.id + " span").text("Clearing virtual device errors..."); - - return cockpit.spawn(process.command, { err: "out", superuser: "require" }) - .done(function () { - FnDisplayAlert({ status: "success", title: "Virtual Device errors successfully cleared", description: virtualdevice.id, breakword: false }, { name: "storagepool-virtualdevice-clear", id: pool.id, timeout: 4 }); - - FnConsole.log[1]("Storage Pools, Virtual Device, Clear Errors: Success, Pool: " + pool.name + ", Virtual Device: " + virtualdevice.id); - }) - .fail(function (message, data) { - FnDisplayAlert({ status: "danger", title: "Virtual Device errors could not be cleared", description: virtualdevice.id, breakword: false }, { name: "storagepool-virtualdevice-clear", id: pool.id, timeout: 4 }); - - FnConsole.warn("Storage Pools, Virtual Device, Clear Errors: Failed, Pool: " + pool.name + ", Virtual Device: " + virtualdevice.id + ", Message: " + (data ? data : message)); - }) - .finally(function () { - $("#modal-" + modal.name + "-" + modal.id).modal("hide"); - - setTimeout(function () { - FnStoragePoolRefresh({ name: pool.name, id: pool.id }, { storagepool: true, filesystems: false, snapshots: false, status: true }); - }, 200); - }); -} - -function FnStoragePoolVirtualDeviceRemove(pool = { name, id }, virtualdevice = { id, labelclear: false }, modal = { name, id }) { - let process = { - command: ["/sbin/zpool", "remove", pool.name, virtualdevice.id] - }; - - modal.hide = true; - - FnConsole.log[1]("Storage Pools, Virtual Device, Remove: In Progress, Pool: " + pool.name + ", Virtual Device: " + virtualdevice.id); - FnConsole.log[3](FnConsoleCommand({ command: process.command })); - - $("#spinner-" + modal.name + "-" + modal.id + " span").text("Removing virtual device..."); - - return cockpit.spawn(process.command, { err: "out", superuser: "require" }) - .done(function () { - FnDisplayAlert({ status: "success", title: "Virtual Device successfully removed from Storage Pool", description: pool.name, breakword: false }, { name: "storagepool-virtualdevice-remove", id: pool.id, timeout: 4 }); - - FnConsole.log[1]("Storage Pools, Virtual Device, Remove: Success, Pool: " + pool.name + ", Virtual Device: " + virtualdevice.id); - - if (virtualdevice.labelclear) { - modal.hide = false; - - $("#spinner-" + modal.name + "-" + modal.id + " span").text("Clearing disk label..."); - - setTimeout(function () { - FnStoragePoolDiskLabelClear({ name: pool.name, id: pool.id }, { id: virtualdevice.id, inactive: true }, { silent: false }) - .finally(function () { - $("#modal-" + modal.name + "-" + modal.id).modal("hide"); - - setTimeout(function () { - FnStoragePoolRefresh({ name: pool.name, id: pool.id }, { storagepool: true, filesystems: true, snapshots: true, status: true }); - }, 200); - }); - }, 2000); - } - }) - .fail(function (message, data) { - FnDisplayAlert({ status: "danger", title: "Virtual Device could not be removed from Storage Pool", description: pool.name, breakword: false }, { name: "storagepool-virtualdevice-remove", id: pool.id, timeout: 4 }); - - FnConsole.warn("Storage Pools, Virtual Device, Remove: Failed, Pool: " + pool.name + ", Virtual Device: " + virtualdevice.id + ", Message: " + (data ? data : message)); - }) - .finally(function () { - if (modal.hide) { - $("#modal-" + modal.name + "-" + modal.id).modal("hide"); - - setTimeout(function () { - FnStoragePoolRefresh({ name: pool.name, id: pool.id }, { storagepool: true, filesystems: true, snapshots: true, status: true }); - }, 200); - } - }); -} - -//#endregion - -//#region File Systems - -function FnFileSystemsGet(pool = { name, id }) { - let process = { - command: ["/sbin/zfs", "list", "-H", "-o", "readonly,name,avail,used,usedsnap,usedrefreserv,recordsize,compression,dedup,sharenfs,sharesmb,mountpoint,mounted,origin,encryption,encryptionroot,keyformat,keystatus", "-r", "-p", pool.name] - }; - let filesystems = { - empty: true - }; - - pool.altroot = (($("#tr-storagepool-" + pool.id).attr("data-pool-altroot") == "true") ? true : false); - pool.boot = (($("#tr-storagepool-" + pool.id).attr("data-pool-boot") == "true") ? true : false); - pool.readonly = (($("#tr-storagepool-" + pool.id).attr("data-pool-readonly") == "true") ? true : false); - pool.feature = { - allocation_classes: (($("#tr-storagepool-" + pool.id).attr("data-pool-feature-allocation_classes") == "true") ? true : false), - edonr: (($("#tr-storagepool-" + pool.id).attr("data-pool-feature-edonr") == "true") ? true : false), - encryption: (($("#tr-storagepool-" + pool.id).attr("data-pool-feature-encryption") == "true") ? true : false), - large_blocks: (($("#tr-storagepool-" + pool.id).attr("data-pool-feature-large_blocks") == "true") ? true : false), - large_dnode: (($("#tr-storagepool-" + pool.id).attr("data-pool-feature-large_dnode") == "true") ? true : false), - lz4_compress: (($("#tr-storagepool-" + pool.id).attr("data-pool-feature-lz4_compress") == "true") ? true : false), - sha512: (($("#tr-storagepool-" + pool.id).attr("data-pool-feature-sha512") == "true") ? true : false), - skein: (($("#tr-storagepool-" + pool.id).attr("data-pool-feature-skein") == "true") ? true : false) - }; - - FnConsole.log[2]("File Systems, Get: In Progress, Pool: " + pool.name); - FnConsole.log[3](FnConsoleCommand({ command: process.command })); - - return cockpit.spawn(process.command, { err: "out" }) - .done(function (data, message) { - FnConsole.log[4](FnConsoleVerbose({ data: data, message: "File Systems, Get:" })); - - if (data) { - filesystems.empty = false; - - FnStoragePoolSizeGet({ name: pool.name, id: pool.id }) - .done(function (_data) { - FnConsole.log[4](FnConsoleVerbose({ data: _data, message: "Storage Pools, Size, Get:" })); - - if (_data) { - pool.sizeraw = _data.replace(/\n+/g, ""); - - FnFileSystemsGetCommand({ name: pool.name, id: pool.id, altroot: pool.altroot, boot: pool.boot, feature: { allocation_classes: pool.feature.allocation_classes, edonr: pool.feature.edonr, encryption: pool.feature.encryption, large_blocks: pool.feature.large_blocks, large_dnode: pool.feature.large_dnode, lz4_compress: pool.feature.lz4_compress, sha512: pool.feature.sha512, skein: pool.feature.skein }, readonly: pool.readonly, sizeraw: pool.sizeraw }, { data: data, message: message }); - } - }) - .fail(function () { - FnFileSystemsGetCommand({ name: pool.name, id: pool.id, altroot: pool.altroot, boot: pool.boot, feature: { allocation_classes: pool.feature.allocation_classes, edonr: pool.feature.edonr, encryption: pool.feature.encryption, large_blocks: pool.feature.large_blocks, large_dnode: pool.feature.large_dnode, lz4_compress: pool.feature.lz4_compress, sha512: pool.feature.sha512, skein: pool.feature.skein }, readonly: pool.readonly, sizeraw: null }, { data: data, message: message }); - }); - } - - FnConsole.log[1]("File Systems, Get: Success, Pool: " + pool.name); - }) - .fail(function (message, data) { - FnConsole.warn("File Systems, Get: Failed, Pool: " + pool.name + ", Message: " + (data ? data : message)); - }) - .finally(function () { - if (filesystems.empty) { - $("#tbody-storagepool-filesystems-" + pool.id).empty(); - $("#tbody-storagepool-filesystems-" + pool.id).append(`No file systems found.`); - $("#modals-storagepool-filesystems-" + pool.id).remove(); - $("#modals-storagepool-filesystem-" + pool.id).remove(); - $("#modals").append(`
    `); - - //Register file systems modals - if (!pool.readonly) { - FnModalFileSystemsCreate({ name: pool.name, id: pool.id, altroot: pool.altroot, feature: { allocation_classes: pool.feature.allocation_classes, edonr: pool.feature.edonr, encryption: pool.feature.encryption, large_blocks: pool.feature.large_blocks, large_dnode: pool.feature.large_dnode, lz4_compress: pool.feature.lz4_compress, sha512: pool.feature.sha512, skein: pool.feature.skein } }); - } - - $("#tr-storagepool-" + pool.id).attr("data-pool-refresh-filesystems", "true"); - - $("#spinner-storagepool-filesystems-" + pool.id).addClass("hidden"); - $("#paneltitle-storagepool-filesystems-" + pool.id).removeClass("hidden").text(FnDateTime()); - $("#btn-storagepool-filesystems-create-" + pool.id).prop("disabled", false); - $("#btn-storagepool-filesystems-refresh-" + pool.id).prop("disabled", false); - } - - FnStoragePoolSpinnerHide({ name: pool.name, id: pool.id }); - FnCockpitElementsUpdate(); - }); -} - -function FnFileSystemsGetCommand(pool = { name, id, altroot: false, boot: false, feature: { allocation_classes: true, edonr: true, encryption: true, large_blocks: true, large_dnode: true, lz4_compress: true, sha512: true, skein: true }, readonly: false, sizeraw: 0 }, process = { data, message }) { - let filesystems = process.data.split(/\n/g).filter(v => v); - - $("#tbody-storagepool-filesystems-" + pool.id).empty(); - $("#modals-storagepool-filesystems-" + pool.id).remove(); - $("#modals-storagepool-filesystem-" + pool.id).remove(); - $("#modals").append(`
    `); - $("#modals").append(`
    `); - - filesystems.forEach((_value, _index) => { - let filesystem = { - properties: _value.split(/\t/g).filter(v => v), - clone: false, - compression: "", - dedup: "", - encryption: false, - encryptionroot: "", - id: "", - keyformat: "", - keystatus: "", - mounted: false, - mountpoint: "", - name: "", - origin: "", - readonly: false, - recordsize: "", - shares: [], - sharenfs: false, - sharesmb: false, - type: "File System", - actionsmenu: { - register: { - samba: {}, - snapshot: {} - } - } - }; - - filesystem.output = ``; - - filesystem.properties.forEach((__value, __index) => { - //0=readonly, 1=name, 2=avail, 3=used, 4=usedsnap, 5=usedrefreserv, 6=recordsize, 7=compression, 8=dedup, 9=sharenfs, 10=sharesmb, 11=mountpoint, 12=mounted, 13=origin, 14=encryption, 15=encryptionroot, 16=keyformat, 17=keystatus - - switch (__index) { - case 0: //0=readonly - if (__value.toLowerCase() == "on" || pool.boot && zfsmanager.configuration.zfs.storagepool.bootlockdown) { - filesystem.readonly = true; - } - - break; - case 1: //1=name - filesystem.name = __value; - filesystem.id = FnGenerateId({ at: true, colon: true, forwardslash: true, period: true, underscore: true, whitespace: true }, { name: filesystem.name, attribute: true }); - - filesystem.output += `Name:` + __value + (filesystem.readonly ? ` ` : ``) + ``; - - break; - case 2: //2=avail - filesystem.output += `Available:` + FnFormatBytes({ base2: true, decimals: 2, value: __value }) + ``; - - break; - case 3: //3=used - filesystem.output += `Used:` + FnFormatBytes({ base2: true, decimals: 2, value: __value }) + ``; - - break; - case 4: //4=usedsnap - filesystem.output += `Snapshots:` + FnFormatBytes({ base2: true, decimals: 2, value: __value }) + ``; - - break; - case 5: //5=usedrefreserv - if (pool.sizeraw) { - filesystem.usedrefreservpercent = FnRound({ decimals: 1, value: (__value / pool.sizeraw) * 100 }); - - __value = FnFormatBytes({ base2: true, decimals: 2, value: __value }); - - if ($.isNumeric(filesystem.usedrefreservpercent) && filesystem.usedrefreservpercent > 0) { - __value += " (" + filesystem.usedrefreservpercent + " %)"; - } - } else { - __value = FnFormatBytes({ base2: true, decimals: 2, value: __value }); - } - - filesystem.output += `Refreservation:` + __value + ``; - - break; - case 6: //6=recordsize - filesystem.recordsize = __value; - - filesystem.output += `Record Size:` + FnFormatBytes({ base2: true, decimals: 0, value: __value }) + ``; - - break; - case 7: //7=compression - filesystem.compression = __value; - - if (/off|on/gi.test(__value)) { - __value = __value.charAt(0).toUpperCase() + __value.slice(1); - } else { - __value = __value.toUpperCase(); - } - - filesystem.output += `Compression:` + __value + ``; - - break; - case 8: //8=dedup - filesystem.dedup = __value; - - if (/sha256|sha512/gi.test(__value)) { - __value = __value.replace(/sha/gi, "SHA-"); - } - if (/off|on|verify|skein/gi.test(__value)) { - __value = __value.charAt(0).toUpperCase() + __value.slice(1); - } - if (/edonr/gi.test(__value)) { - __value = __value.replace(/edonr/gi, "Edon-R"); - } - - filesystem.output += `Deduplication:` + __value.replace(/,verify/g, " + Verify") + ``; - - break; - case 9: //9=sharenfs - filesystem.sharenfs = __value; - - if (__value.toLowerCase() != "off" && __value.toLowerCase() != "-") { - filesystem.sharenfs = true; - filesystem.shares.push("NFS"); - } else { - filesystem.sharenfs = false; - } - - break; - case 10: //10=sharesmb - filesystem.sharesmb = __value; - - if (__value.toLowerCase() == "on") { - filesystem.sharesmb = true; - filesystem.shares.push("SMB"); - } else { - filesystem.sharesmb = false; - } - - if (/off|on/gi.test(__value)) { - __value = __value.charAt(0).toUpperCase() + __value.slice(1); - } else { - __value = __value.toUpperCase(); - } - - filesystem.output += `Share:` + (filesystem.shares.length > 0 ? filesystem.shares.join(" + ") : "Off") + ``; - - break; - case 11: //11=mountpoint - filesystem.mountpoint = __value; - break; - case 12: //12=mounted - if (__value.toLowerCase() == "yes") { - filesystem.mounted = true; - } else { - filesystem.mounted = false; - } - - if (/yes|no/gi.test(__value)) { - __value = __value.charAt(0).toUpperCase() + __value.slice(1); - } - - filesystem.output += `Mounted:` + __value + ``; - - break; - case 13: //13=origin - if (__value != "-") { - filesystem.origin = __value; - filesystem.clone = true; - filesystem.type = "Clone File System"; - } else { - filesystem.clone = false; - filesystem.type = "File System"; - } - - break; - case 14: //14=encryption - if (__value.toLowerCase() != "off") { - filesystem.encryption = true; - } else { - filesystem.encryption = false; - } - - break; - case 15: //15=encryptionroot - filesystem.encryptionroot = __value; - - break; - case 16: //16=keyformat - if (filesystem.encryption && __value.toLowerCase() == "passphrase") { - filesystem.keyformat = "passphrase"; - } - - break; - case 17: //17=keystatus - if (__value != "-") { - filesystem.keystatus = __value; - } else { - filesystem.keystatus = ""; - } - - break; - } - - //Add icons and actions menu at end of array - if (__index >= (filesystem.properties.length - 1)) { - filesystem.icons = { - clone: ``, - keystatus: { - locked: ``, - unlocked: `` - } - }; - - filesystem.output += `Clone:` + (filesystem.clone ? `Yes` + filesystem.icons.clone : `No`) + ``; - filesystem.output += `Encrypted:` + (/available|unavailable/.test(filesystem.keystatus) ? `Yes` : `No`) + ``; - - if (filesystem.keystatus == "unavailable") { - filesystem.output += filesystem.icons.keystatus.locked; - } else if (filesystem.keystatus == "available") { - filesystem.output += filesystem.icons.keystatus.unlocked; - } - - filesystem.output += ``; - - //Actions menu - filesystem.actionsmenu.items = { - itemconfigure: [], - itemconfiguredivider: function () { - if (this.itemconfigure.length > 0 && this.item.length > 0) { - this.itemconfigure.push(this.divider); - } - }, - item: [], - itemdivider: function () { - if (this.item.length > 0 && this.itemencrypted.length > 0) { - this.item.push(this.divider); - } - }, - itemencrypted: [], - itemencrypteddivider: function () { - if ((this.item.length > 0 || this.itemencrypted.length > 0) && (this.itemsamba.length > 0 || this.itemsnapshot.length > 0)) { - this.itemencrypted.push(this.divider); - } - }, - itemsamba: [], - itemsambadivider: function () { - if ((this.item.length > 0 || this.itemencrypted.length > 0) && this.itemsamba.length > 0 && this.itemsnapshot.length > 0) { - this.itemsamba.push(this.divider); - } - }, - itemsnapshot: [], - divider: `` - }; - filesystem.actionsmenu.display = function () { - if (/@/g.test(filesystem.name) == false && (this.items.itemconfigure.length + this.items.item.length + this.items.itemencrypted.length + this.items.itemsamba.length + this.items.itemsnapshot.length) > 0) { - this.items.itemconfiguredivider(); - this.items.itemdivider(); - this.items.itemencrypteddivider(); - this.items.itemsambadivider(); - - return this.header + this.items.itemconfigure.join("\n") + this.items.item.join("\n") + this.items.itemencrypted.join("\n") + this.items.itemsamba.join("\n") + this.items.itemsnapshot.join("\n") + this.footer; - } else { - return ""; - } - }; - filesystem.actionsmenu.header = ` - - `; - - //Configure File System - filesystem.actionsmenu.items.itemconfigure.push(`
  • Configure ` + filesystem.type + `
  • `); - - //Rename File System - if (!pool.readonly && (!filesystem.readonly || filesystem.readonly && !zfsmanager.configuration.zfs.filesystem.readonlylockdown) && filesystem.name != pool.name) { - filesystem.actionsmenu.items.item.push(`
  • Rename ` + filesystem.type + `
  • `); - - filesystem.actionsmenu.register.rename = true; - } - - //Promote Clone File System - if (!pool.readonly && (!filesystem.readonly || filesystem.readonly && !zfsmanager.configuration.zfs.filesystem.readonlylockdown) && filesystem.clone && filesystem.origin.replace(/^(.*)\@.*$/, "$1") != pool.name) { - filesystem.actionsmenu.items.item.push(`
  • Promote ` + filesystem.type + `
  • `); - - filesystem.actionsmenu.register.promote = true; - } - - //Mount File System / Unmount File System - if (!pool.boot || pool.boot && !zfsmanager.configuration.zfs.storagepool.bootlockdown) { - if (!filesystem.mounted && filesystem.keystatus != "unavailable") { - filesystem.actionsmenu.items.item.push(`
  • Mount ` + filesystem.type + `
  • `); - - filesystem.actionsmenu.register.mount = true; - } else if (filesystem.mounted) { - filesystem.actionsmenu.items.item.push(`
  • Unmount ` + filesystem.type + `
  • `); - - filesystem.actionsmenu.register.unmount = true; - } - } - - //Unlock File System / Lock File System - if (filesystem.keystatus == "unavailable" && !filesystem.clone && filesystem.encryptionroot == filesystem.name) { - filesystem.actionsmenu.items.item.push(`
  • Unlock File System
  • `); - - filesystem.actionsmenu.register.unlock = true; - } else if (filesystem.keystatus == "available" && !filesystem.mounted && !filesystem.clone && filesystem.encryptionroot == filesystem.name) { - filesystem.actionsmenu.items.item.push(`
  • Lock File System
  • `); - - filesystem.actionsmenu.register.lock = true; - } - - //Change Passphrase - if (!pool.readonly && (!filesystem.readonly || filesystem.readonly && !zfsmanager.configuration.zfs.filesystem.readonlylockdown) && filesystem.keystatus == "available" && !filesystem.clone && filesystem.encryptionroot == filesystem.name) { - filesystem.actionsmenu.items.itemencrypted.push(`
  • Change Passphrase
  • `); - - filesystem.actionsmenu.register.changepassphrase = true; - } - - //Destroy File System - if (!pool.readonly && (!filesystem.readonly || filesystem.readonly && !zfsmanager.configuration.zfs.filesystem.readonlylockdown) && filesystem.name != pool.name) { - if (!filesystem.clone || filesystem.clone && new RegExp("^" + filesystem.name + "/").test(filesystem.origin.replace(/^(.*)\@.*$/, "$1")) == false) { //Do not display if clone origin is a child file system - will generate recursive dependency error - filesystem.actionsmenu.items.item.push(`
  • Destroy ` + filesystem.type + `
  • `); - - filesystem.actionsmenu.register.destroy = true; - } - } - - //Enable Samba Share - if (!pool.readonly && (!filesystem.readonly || filesystem.readonly && !zfsmanager.configuration.zfs.filesystem.readonlylockdown) && !filesystem.sharesmb && zfsmanager.configuration.samba.manage) { - filesystem.actionsmenu.items.itemsamba.push(`
  • Enable Samba Share
  • `); - - filesystem.actionsmenu.register.samba.enable = true; - } - - //Configure Samba Share - if (filesystem.sharesmb && zfsmanager.configuration.samba.manage) { - filesystem.actionsmenu.items.itemsamba.push(`
  • Configure Samba Share
  • `); - - filesystem.actionsmenu.register.samba.configure = true; - } - - //Disable Samba Share - if (!pool.readonly && (!filesystem.readonly || filesystem.readonly && !zfsmanager.configuration.zfs.filesystem.readonlylockdown) && filesystem.sharesmb && zfsmanager.configuration.samba.manage) { - filesystem.actionsmenu.items.itemsamba.push(`
  • Disable Samba Share
  • `); - - filesystem.actionsmenu.register.samba.disable = true; - } - - //Create Snapshot - if (!pool.readonly && zfsmanager.configuration.zfs.filesystem.snapshotactions) { - filesystem.actionsmenu.items.itemsnapshot.push(`
  • Create Snapshot
  • `); - - filesystem.actionsmenu.register.snapshot.create = true; - } - - filesystem.output += `` + filesystem.actionsmenu.display() + ``; - } - }); - - filesystem.output += ``; - - $("#tbody-storagepool-filesystems-" + pool.id).append(filesystem.output); - - //Register file system modals - FnModalFileSystemConfigure({ name: pool.name, id: pool.id, altroot: pool.altroot, feature: { allocation_classes: pool.feature.allocation_classes, edonr: pool.feature.edonr, large_blocks: pool.feature.large_blocks, large_dnode: pool.feature.large_dnode, lz4_compress: pool.feature.lz4_compress, sha512: pool.feature.sha512, skein: pool.feature.skein }, readonly: pool.readonly }, { name: filesystem.name, id: filesystem.id, origin: filesystem.origin, type: filesystem.type }); - if (filesystem.actionsmenu.register.changepassphrase) { - FnModalFileSystemChangePassphrase({ name: pool.name, id: pool.id }, { name: filesystem.name, id: filesystem.id }); - } - if (filesystem.actionsmenu.register.destroy) { - FnModalFileSystemDestroy({ name: pool.name, id: pool.id, altroot: pool.altroot, readonly: pool.readonly }, { name: filesystem.name, id: filesystem.id, sharesmb: filesystem.sharesmb, type: filesystem.type }); - } - if (filesystem.actionsmenu.register.lock) { - FnModalFileSystemLock({ name: pool.name, id: pool.id }, { name: filesystem.name, id: filesystem.id, type: filesystem.type }); - } - if (filesystem.actionsmenu.register.mount) { - FnModalFileSystemMount({ name: pool.name, id: pool.id, altroot: pool.altroot, readonly: pool.readonly }, { name: filesystem.name, id: filesystem.id, sharesmb: filesystem.sharesmb, type: filesystem.type }); - } - if (filesystem.actionsmenu.register.promote) { - FnModalFileSystemPromote({ name: pool.name, id: pool.id }, { name: filesystem.name, id: filesystem.id, origin: filesystem.origin, type: filesystem.type }); - } - if (filesystem.actionsmenu.register.rename) { - FnModalFileSystemRename({ name: pool.name, id: pool.id, altroot: pool.altroot }, { name: filesystem.name, id: filesystem.id, clone: filesystem.clone, encryption: filesystem.encryption, encryptionroot: filesystem.encryptionroot, origin: filesystem.origin, sharesmb: filesystem.sharesmb, type: filesystem.type }); - } - if (filesystem.actionsmenu.register.samba.configure) { - FnModalFileSystemSambaConfigure({ name: pool.name, id: pool.id, altroot: pool.altroot, readonly: pool.readonly }, { name: filesystem.name, id: filesystem.id, mountpoint: filesystem.mountpoint }); - } - if (filesystem.actionsmenu.register.samba.disable) { - FnModalFileSystemSambaDisable({ name: pool.name, id: pool.id, altroot: pool.altroot, readonly: pool.readonly }, { name: filesystem.name, id: filesystem.id, type: filesystem.type }); - } - if (filesystem.actionsmenu.register.samba.enable) { - FnModalFileSystemSambaEnable({ name: pool.name, id: pool.id, altroot: pool.altroot, readonly: pool.readonly }, { name: filesystem.name, id: filesystem.id, mounted: filesystem.mounted, mountpoint: filesystem.mountpoint }); - } - if (filesystem.actionsmenu.register.snapshot.create) { - FnModalFileSystemSnapshotCreate({ name: pool.name, id: pool.id }, { name: filesystem.name, id: filesystem.id }); - } - if (filesystem.actionsmenu.register.unlock) { - FnModalFileSystemUnlock({ name: pool.name, id: pool.id, altroot: pool.altroot, readonly: pool.readonly }, { name: filesystem.name, id: filesystem.id, sharesmb: filesystem.sharesmb, type: filesystem.type }); - } - if (filesystem.actionsmenu.register.unmount) { - FnModalFileSystemUnmount({ name: pool.name, id: pool.id, altroot: pool.altroot, readonly: pool.readonly }, { name: filesystem.name, id: filesystem.id, encryptionroot: filesystem.encryptionroot, keystatus: filesystem.keystatus, sharesmb: filesystem.sharesmb, type: filesystem.type }); - } - }); - - //Register file systems modals - if (!pool.readonly) { - FnModalFileSystemsCreate({ name: pool.name, id: pool.id, altroot: pool.altroot, feature: { allocation_classes: pool.feature.allocation_classes, edonr: pool.feature.edonr, encryption: pool.feature.encryption, large_blocks: pool.feature.large_blocks, large_dnode: pool.feature.large_dnode, lz4_compress: pool.feature.lz4_compress, sha512: pool.feature.sha512, skein: pool.feature.skein } }); - } - - $("#tr-storagepool-" + pool.id).attr("data-pool-refresh-filesystems", "true"); - - $("#spinner-storagepool-filesystems-" + pool.id).addClass("hidden"); - $("#paneltitle-storagepool-filesystems-" + pool.id).removeClass("hidden").text(FnDateTime()); - $("#btn-storagepool-filesystems-create-" + pool.id).prop("disabled", false); - $("#btn-storagepool-filesystems-refresh-" + pool.id).prop("disabled", false); - - FnStoragePoolSpinnerHide({ name: pool.name, id: pool.id }); - FnCockpitElementsUpdate(); -} - -function FnFileSystemsLockedGet() { - let filesystems = { - id: [] - }; - let process = { - command: ["/sbin/zfs", "list", "-H", "-o", "name,encryption,encryptionroot,keyformat,keystatus", "-r", "-t", "filesystem"] - }; - - $("#listgroup-storagepools-filesystems-unlock-filesystems").empty().append(`
  • `); - - FnConsole.log[2]("File Systems, Locked, Get: In Progress"); - FnConsole.log[3](FnConsoleCommand({ command: process.command })); - - return cockpit.spawn(process.command, { err: "out" }) - .done(function (data) { - FnConsole.log[4](FnConsoleVerbose({ data: data, message: "File Systems, Locked, Get:" })); - - filesystems.id = data.split(/\n/g).filter(v => { - if (!zfsmanager.configuration.zfs.storagepool.boot && zfsmanager.zfs.storagepool.boot && new RegExp("^" + zfsmanager.zfs.storagepool.boot + "\t|^" + zfsmanager.zfs.storagepool.boot + "/").test(v)) { - //Do not display boot - } else if (!zfsmanager.configuration.zfs.storagepool.root && zfsmanager.zfs.storagepool.root && new RegExp("^" + zfsmanager.zfs.storagepool.root + "\t|^" + zfsmanager.zfs.storagepool.root + "/").test(v)) { - //Do not display root - } else { - return v; - } - }); - - filesystems.id.forEach((_value, _index) => { - let filesystem = { - properties: _value.split(/\t/g).filter(v => v) - }; - - filesystem.name = filesystem.properties[0]; - filesystem.encryption = filesystem.properties[1]; - filesystem.encryptionroot = filesystem.properties[2]; - filesystem.keyformat = filesystem.properties[3]; - filesystem.keystatus = filesystem.properties[4]; - - if (filesystem.encryptionroot == filesystem.name && filesystem.keyformat == "passphrase" && filesystem.keystatus == "unavailable") { - filesystems.output = ` - - `; - - $("#listgroup-storagepools-filesystems-unlock-filesystems").append(filesystems.output); - } - }); - - setTimeout(function () { - $("#spinner-storagepools-filesystems-unlock-filesystems").remove(); - $("#listgroup-storagepools-filesystems-unlock-filesystems > li").removeClass("hidden"); - if ($("#helpblock-storagepools-filesystems-unlock-filesystems-warning").text()) { - $("#helpblock-storagepools-filesystems-unlock-filesystems-warning").removeClass("hidden"); - } - - if ($("#listgroup-storagepools-filesystems-unlock-filesystems > li").length == 0) { - filesystems.output = ` -
  • - -
  • - `; - - $("#listgroup-storagepools-filesystems-unlock-filesystems").append(filesystems.output); - } - }, 200); - - FnConsole.log[1]("File Systems, Locked, Get: Success"); - }) - .fail(function (message, data) { - $("#spinner-storagepools-filesystems-unlock-filesystems").remove(); - $("#listgroup-storagepools-filesystems-unlock-filesystems > li").removeClass("hidden"); - - if ($("#listgroup-storagepools-filesystems-unlock-filesystems > li").length == 0) { - filesystems.output = ` -
  • - -
  • - `; - - $("#listgroup-storagepools-filesystems-unlock-filesystems").append(filesystems.output); - } - - FnConsole.warn("File Systems, Locked, Get: Failed, Message: " + (data ? data : message)); - }); -} - -function FnFileSystemsMountedGet(pool = { name, id }, filesystem = { name, id }, modal = { alert: { id, mount: true } }) { - let process = { - command: ["/sbin/zfs", "list", "-H", "-o", "name,mounted", "-r", "-t", "filesystem", filesystem.name] - }; - - filesystem.children = { - mounted: false - } - - FnConsole.log[2]("File Systems, Mounted, Get: In Progress: Success, Pool: " + pool.name); - FnConsole.log[3](FnConsoleCommand({ command: process.command })); - - return cockpit.spawn(process.command, { err: "out" }) - .done(function (data) { - FnConsole.log[4](FnConsoleVerbose({ data: data, message: "File Systems, Mounted, Get:" })); - - let filesystems = data.split(/\n/g).filter((v, i) => v && i > 0); - - filesystems.forEach((_value, _index) => { - filesystem.properties = _value.split(/\t/g).filter(v => v); - - if (filesystem.properties[1] == "yes" && !filesystem.children.mount) { - filesystem.children.mounted = true; - } - }); - - if (filesystem.children.mounted) { - modal.alert.id.html(FnDisplayInlineAlert({ status: "warning", title: "There are child file systems currently mounted. " + (modal.alert.mount ? "Mounting" : "Unmounting") + " this file system may adversely affect the child file systems.", description: null }, { name: null, id: null, hidden: false })); - } - - FnConsole.log[1]("File Systems, Mounted, Get: Success, Pool: " + pool.name); - }) - .fail(function (message, data) { - FnConsole.warn("File Systems, Mounted, Get: Failed, Pool: " + pool.name + ", Message: " + (data ? data : message)); - }); -} - -function FnFileSystemsNamesGet(pool = { name, id }, filesystem = { existing: { name, clone: false, encryption: false, encryptionroot, origin }, override: false }, modal = { dropdown: { id, selected } }) { - let process = { - command: ["/sbin/zfs", "list", "-H", "-o", "name,encryption,encryptionroot,keystatus", "-r", "-t", "filesystem", pool.name] - }; - - FnConsole.log[2]("File Systems, Names, Get: In Progress, Pool: " + pool.name); - FnConsole.log[3](FnConsoleCommand({ command: process.command })); - - return cockpit.spawn(process.command, { err: "out" }) - .done(function (data) { - FnConsole.log[4](FnConsoleVerbose({ data: data, message: "File Systems, Names, Get:" })); - - let filesystems = data.split(/\n/g).filter(v => v); - - modal.dropdown.items = []; - - modal.dropdown.id.empty(); - - filesystems.forEach((_value, _index) => { - filesystem.properties = _value.split(/\t/g).filter(v => v); - filesystem.name = filesystem.properties[0]; - filesystem.encryption = (filesystem.properties[1].toLowerCase() != "off" ? true : false); - filesystem.encryptionroot = (filesystem.properties[2] && filesystem.properties[2] != "-" ? filesystem.properties[2] : ""); - filesystem.encryptionstatus = ""; - filesystem.existing.regexp = { - name: new RegExp("^" + filesystem.existing.name + "/", "g") - }; - filesystem.keystatus = filesystem.properties[3].toLowerCase(); - - if (filesystem.encryption && /^available$|^unavailable$/.test(filesystem.keystatus)) { - filesystem.encryptionstatus = `` - } - - modal.dropdown.add = false; - modal.dropdown.item = `
  • ` + filesystem.name + filesystem.encryptionstatus + `
  • `; - - if ((filesystem.override || filesystem.existing.encryption) && filesystem.existing.clone) { //Encrypted clone file systems can only move within origin and child file systems - filesystem.existing.regexp.origin = new RegExp("^" + filesystem.existing.origin.replace(/^(.*)\@.*$/, "$1\/"), "g"); - - if (filesystem.name == filesystem.existing.origin.replace(/^(.*)\@.*$/, "$1")) { //Origin file system - modal.dropdown.add = true; - } else if (filesystem.name == filesystem.existing.name.replace(/\/[^\/]+$/, "")) { //File System parent - modal.dropdown.add = true; - } else if (filesystem.name != filesystem.existing.name && filesystem.existing.regexp.origin.test(filesystem.name) && !filesystem.existing.regexp.name.test(filesystem.name)) { //Origin child file systems - modal.dropdown.add = true; - } - } else if (filesystem.override || filesystem.existing.encryption) { //Encrypted file systems that are their own encryption root can move anywhere, child file system of the encryption root can only move within encryption root and its child file systems - if (filesystem.name != filesystem.existing.name && !filesystem.existing.regexp.name.test(filesystem.name)) { - if (filesystem.existing.name == filesystem.existing.encryptionroot) { //File system is its own encryption root - modal.dropdown.add = true; - } else if (filesystem.encryptionroot == filesystem.existing.encryptionroot) { //File system is a child of the encryption root - modal.dropdown.add = true; - } - } - } else { //Unencrypted file systems can only move to unencrypted file systems - if (!filesystem.encryption && filesystem.name != filesystem.existing.name && !filesystem.existing.regexp.name.test(filesystem.name)) { - modal.dropdown.add = true; - } - } - - if (modal.dropdown.add) { - modal.dropdown.items.push(modal.dropdown.item); - } - }); - - modal.dropdown.id.append(modal.dropdown.items.join("\n")); - - FnConsole.log[1]("File Systems, Names, Get: Success, Pool: " + pool.name); - }) - .fail(function (message, data) { - FnConsole.warn("File Systems, Names, Get: Failed, Pool: " + pool.name + ", Message: " + (data ? data : message)); - }); -} - -function FnFileSystemsUnlock(filesystems = { id: [] }, filesystem = { mount: true, overlay: true, passphrase }, modal = { name, id }) { - let promise = Promise.resolve(); - - filesystems.count = { - available: 0, - error: 0, - success: 0 - }; - - $("#listgroup-" + modal.name + modal.id + "-filesystems > li.list-group-item > label > span.pficon").removeClass("list-group-ct-warning"); - - if (filesystems.id.length > 0) { - FnConsole.log[2]("File Systems, Unlock: In Progress"); - - $("#spinner-" + modal.name + modal.id + " span").text("Unlocking file system" + (filesystems.id.length > 1 ? "s" : "") + "..."); - - filesystems.id.forEach((_value, _index) => { - promise = promise.then(_ => new Promise(resolve => - setTimeout(function () { - let pool = { - name: _value.replace(/\/.*$/, ""), - id: FnGenerateId({ at: true, colon: true, forwardslash: true, period: true, underscore: true, whitespace: true }, { name: _value.replace(/\/.*$/, ""), attribute: true }) - }; - - filesystem.name = _value; - filesystem.id = FnGenerateId({ at: true, colon: true, forwardslash: true, period: true, underscore: true, whitespace: true }, { name: _value, attribute: true }); - - FnFileSystemUnlock({ name: pool.name, id: pool.id, altroot: false, readonly: false }, { name: filesystem.name, id: filesystem.id, mount: filesystem.mount, overlay: filesystem.overlay, passphrase: filesystem.passphrase, type: "File System" }, { enable: false }, { name: modal.name, id: modal.id }, { refresh: false }) - .done(function (data) { - FnConsole.log[4](FnConsoleVerbose({ data: data, message: "File Systems, Unlock:" })); - - if (/error|Incorrect key/i.test(data)) { - filesystems.count.error++; - - $("#listgroup-" + modal.name + modal.id + "-filesystems > li.list-group-item[data-filesystem-name='" + filesystem.name + "'] > label > span.pficon").addClass("list-group-ct-warning"); - } else { - filesystems.count.success++; - - $("#listgroup-" + modal.name + modal.id + "-filesystems > li.list-group-item[data-filesystem-name='" + filesystem.name + "']").remove(); - } - }) - .fail(function (message, data) { - if (/Key already loaded/i.test(data)) { - filesystems.count.success++; - - $("#listgroup-" + modal.name + modal.id + "-filesystems > li.list-group-item[data-filesystem-name='" + filesystem.name + "']").remove(); - } else { - filesystems.count.error++; - - $("#listgroup-" + modal.name + modal.id + "-filesystems > li.list-group-item[data-filesystem-name='" + filesystem.name + "'] > label > span.pficon").addClass("list-group-ct-warning"); - } - }) - .finally(function () { - if (_index == (filesystems.id.length - 1)) { - $("#listgroup-storagepools-filesystems-unlock-filesystems input[name='checkbox-storagepools-filesystems-unlock-filesystems']").map(function () { - filesystems.count.available++; - }); - - if (filesystems.count.error == 0) { - FnConsole.log[1]("File Systems, Unlock: Success"); - } else { - FnConsole.warn("File Systems, Unlock: Failed"); - } - - if (filesystems.count.available == 0) { - $("#modal-" + modal.name + modal.id).modal("hide"); - } else { - $("#spinner-" + modal.name + modal.id).addClass("hidden"); - $("#spinner-" + modal.name + modal.id + " span").text(""); - $("#btn-" + modal.name + "-apply" + modal.id).prop("disabled", false); - } - - setTimeout(function () { - FnStoragePoolsGet(); - }, 1000); - } - }); - - resolve(); - }, 1000) - )); - }); - } else { - $("#modal-" + modal.name + modal.id).modal("hide"); - - setTimeout(function () { - FnStoragePoolsGet(); - }, 1000); - } -} - -//#endregion - -//#region File System - -function FnFileSystemChangePassphrase(pool = { name, id }, filesystem = { name, id, passphrase }) { - let process = { - command: [] - }; - - if (!filesystem.passphrase || filesystem.passphrase.length < 8) { - FnFileSystemChangePassphraseFail({ name: pool.name, id: pool.id }, { name: filesystem.name, id: filesystem.id }, { data: "Passphrase requires a minimum of 8 characters.", message: null }); - return; - } - - //Escape percentage and single quote special character for printf - if (/\%/g.test(filesystem.passphrase)) { - filesystem.passphrase = filesystem.passphrase.replace(/\%/g, "\%\%"); - } - if (/\'/g.test(filesystem.passphrase)) { - filesystem.passphrase = filesystem.passphrase.replace(/\'/g, "\'\"\'\"\'"); - } - - process.command = ["/bin/sh", "-c", "printf '" + filesystem.passphrase + "' | /sbin/zfs change-key \"" + filesystem.name + "\""]; - - FnConsole.log[2]("File Systems, Change Passphrase: In Progress, Pool: " + pool.name + ", File System: " + filesystem.name); - FnConsole.log[3](FnConsoleCommand({ command: process.command })); - - $("#spinner-storagepool-filesystem-changepassphrase-" + filesystem.id + " span").text("Changing passphrase..."); - - return cockpit.spawn(process.command, { err: "out", superuser: "require" }) - .done(function (data, message) { - FnConsole.log[4](FnConsoleVerbose({ data: data, message: "File Systems, Change Passphrase:" })); - - if (/error|Key must be loaded/i.test(data)) { - FnFileSystemChangePassphraseFail({ name: pool.name, id: pool.id }, { name: filesystem.name, id: filesystem.id }, { data: data, message: message }); - return; - } - - FnDisplayAlert({ status: "success", title: "File System passphrase successfully changed", description: filesystem.name, breakword: false }, { name: "filesystem-changepassphrase", id: filesystem.id, timeout: 4 }); - - FnConsole.log[1]("File Systems, Change Passphrase: Success, Pool: " + pool.name + ", File System: " + filesystem.name); - - $("#modal-storagepool-filesystem-changepassphrase-" + filesystem.id).modal("hide"); - - setTimeout(function () { - FnStoragePoolRefresh({ name: pool.name, id: pool.id }, { storagepool: true, filesystems: true, snapshots: true, status: false }); - }, 200); - }) - .fail(function (message, data) { - FnFileSystemChangePassphraseFail({ name: pool.name, id: pool.id }, { name: filesystem.name, id: filesystem.id }, { data: data, message: message }); - }); -} - -function FnFileSystemChangePassphraseFail(pool = { name, id }, filesystem = { name, id }, process = { data, message }) { - let modal = { - hide: true - }; - - if (/Passphrase requires a minimum of 8 characters./i.test(process.data)) { - modal.hide = false; - - $("#validationwrapper-storagepool-filesystem-changepassphrase-passphrase-" + filesystem.id).addClass("has-error"); - $("#helpblock-storagepool-filesystem-changepassphrase-passphrase-" + filesystem.id).addClass("has-error").removeClass("hidden").text("Passphrase requires a minimum of 8 characters."); - $("#input-storagepool-filesystem-changepassphrase-passphrase-" + filesystem.id).focus(); - } else if (/Key must be loaded/i.test(process.data)) { - modal.hide = false; - - $("#validationwrapper-storagepool-filesystem-changepassphrase-filesystem-" + filesystem.id).addClass("has-error"); - $("#helpblock-storagepool-filesystem-changepassphrase-filesystem-" + filesystem.id).addClass("has-error").removeClass("hidden").text("File System is locked."); - $("#input-storagepool-filesystem-changepassphrase-filesystem-" + filesystem.id).focus(); - } else if (/encryption failure/i.test(process.data)) { //Error message when pool is read only - modal.hide = true; - } else if (/error/i.test(process.data)) { - modal.hide = false; - - $("#validationwrapper-storagepool-filesystem-changepassphrase-passphrase-" + filesystem.id).addClass("has-error"); - $("#helpblock-storagepool-filesystem-changepassphrase-passphrase-" + filesystem.id).addClass("has-error").removeClass("hidden").text("Passphrase is incorrect."); - $("#input-storagepool-filesystem-changepassphrase-passphrase-" + filesystem.id).focus(); - } - - if (!modal.hide) { - $("#spinner-storagepool-filesystem-changepassphrase-" + filesystem.id).addClass("hidden"); - $("#spinner-storagepool-filesystem-changepassphrase-" + filesystem.id + " span").text(""); - $("#btn-storagepool-filesystem-changepassphrase-apply-" + filesystem.id).prop("disabled", false); - } - - FnConsole.warn("File Systems, Change Passphrase: Failed, Pool: " + pool.name + ", File System: " + filesystem.name + ", Message: " + (process.data ? process.data : process.message)); - - if (modal.hide) { - FnDisplayAlert({ status: "danger", title: "File System passphrase could not be changed", description: filesystem.name, breakword: false }, { name: "filesystem-changepassphrase", id: filesystem.id, timeout: 4 }); - - $("#modal-storagepool-filesystem-changepassphrase-" + filesystem.id).modal("hide"); - - setTimeout(function () { - FnStoragePoolRefresh({ name: pool.name, id: pool.id }, { storagepool: true, filesystems: true, snapshots: true, status: false }); - }, 200); - } -} - -function FnFileSystemChildDatasetsGet(pool = { name, id }, filesystem = { name, id, clones: true }, modal = { name, id }) { - let process = { - command: ["/sbin/zfs", "list", "-H", "-o", "name,clones", "-r", "-t", "filesystem,snapshot", filesystem.name] - }; - - FnConsole.log[2]("File Systems, Child, Datasets, Get: In Progress, Pool: " + pool.name + ", File System: " + filesystem.name); - FnConsole.log[3](FnConsoleCommand({ command: process.command })); - - return cockpit.spawn(process.command, { err: "out" }) - .done(function (data) { - FnConsole.log[4](FnConsoleVerbose({ data: data, message: "File Systems, Child, Datasets, Get:" })); - - data = data.split(/\n/g).filter(v => v); - - let filesystems = { - id: [] - }; - let snapshots = { - id: [] - }; - - if (data.length > 0) { - data.forEach((_value, _index) => { - let dataset = { - properties: _value.split(/\t/g).filter(v => v) - }; - - dataset.name = dataset.properties[0]; - dataset.clones = (dataset.properties[1] ? dataset.properties[1] : ""); - - if (new RegExp("^" + filesystem.name + ".*@").test(dataset.name)) { - snapshots.id.push(dataset.name); - - if (dataset.clones && filesystem.clones) { - dataset.clones = dataset.clones.split(",").filter(v => v); - - dataset.clones.forEach((_value, _index) => { - filesystems.id.push(_value); - }); - } - - } else if (new RegExp("^" + filesystem.name + ".*@").test(dataset.name) == false) { - filesystems.id.push(dataset.name); - } - }); - } - - filesystems.id.sort(); - snapshots.id.sort(); - - FnConsole.log[1]("File Systems, Child, Datasets, Get: Success, Pool: " + pool.name + ", File System: " + filesystem.name); - - FnFileSystemChildFileSystemsGet({ name: pool.name, id: pool.id }, { name: filesystem.name, id: filesystem.id }, { id: filesystems.id }, { name: modal.name, id: modal.id }); - FnFileSystemChildSnapshotsGet({ name: pool.name, id: pool.id }, { name: filesystem.name, id: filesystem.id }, { id: filesystems.id }, { name: modal.name, id: modal.id }); - }) - .fail(function (message, data) { - FnConsole.warn("File Systems, Child, Datasets, Get: Failed, Pool: " + pool.name + ", File System: " + filesystem.name + ", Message: " + (data ? data : message)); - }); -} - -function FnFileSystemChildFileSystemsGet(pool = { name, id }, filesystem = { name, id }, filesystems = { id: [] }, modal = { name, id }) { - let process = { - command: ["/sbin/zfs", "list", "-H", "-o", "name", "-r", "-t", "filesystem"] - }; - - filesystems.id.forEach(_value => _value && process.command.push(_value)); - - FnConsole.log[2]("File Systems, Child, File Systems, Get: In Progress, Pool: " + pool.name + ", File System: " + filesystem.name); - FnConsole.log[3](FnConsoleCommand({ command: process.command })); - - return cockpit.spawn(process.command, { err: "out" }) - .done(function (data) { - FnConsole.log[4](FnConsoleVerbose({ data: data, message: "File Systems, Child, File Systems, Get:" })); - - let filesystems = { - id: data.split(/\n/g).filter(v => v), - count: { - filesystems: 0, - filesystemswithclones: 0 - } - }; - - if (filesystems.id.length > 0) { - filesystems.id.forEach((_value, _index) => { - if (new RegExp("^" + filesystem.name + "/").test(_value)) { - filesystems.count.filesystems++; - - $("#ul-" + modal.name + "-child-filesystems-" + modal.id).append("
  • " + _value + "
  • \n"); - } - - if (_value != filesystem.name) { - filesystems.count.filesystemswithclones++; - - $("#ul-" + modal.name + "-child-filesystemswithclones-" + modal.id).append("
  • " + _value + "
  • \n"); - } - }); - - $("#panelgroup-" + modal.name + "-" + modal.id).attr("data-filesystem-child-filesystems", filesystems.count.filesystems); - $("#panelgroup-" + modal.name + "-" + modal.id).attr("data-filesystem-child-filesystemswithclones", filesystems.count.filesystemswithclones); - } - - FnConsole.log[1]("File Systems, Child, File Systems, Get: Success, Pool: " + pool.name + ", File System: " + filesystem.name); - }) - .fail(function (message, data) { - FnConsole.warn("File Systems, Child, File Systems, Get: Failed, Pool: " + pool.name + ", File System: " + filesystem.name + ", Message: " + (data ? data : message)); - }); -} - -function FnFileSystemChildSnapshotsGet(pool = { name, id }, filesystem = { name, id }, snapshots = { id: [] }, modal = { name, id }) { - let process = { - command: ["/sbin/zfs", "list", "-H", "-o", "name", "-r", "-t", "snapshot"] - }; - - snapshots.id.forEach(_value => _value && process.command.push(_value)); - - FnConsole.log[2]("File Systems, Child, Snapshots, Get: In Progress, Pool: " + pool.name + ", File System: " + filesystem.name); - FnConsole.log[3](FnConsoleCommand({ command: process.command })); - - return cockpit.spawn(process.command, { err: "out" }) - .done(function (data) { - FnConsole.log[4](FnConsoleVerbose({ data: data, message: "File Systems, Child, Snapshots, Get:" })); - - let snapshots = { - id: data.split(/\n/g).filter(v => v), - count: { - snapshots: 0, - snapshotswithclones: 0 - } - }; - - if (snapshots.id.length > 0) { - snapshots.id.forEach((_value, _index) => { - if (new RegExp("^" + filesystem.name + ".*@").test(_value)) { - snapshots.count.snapshots++; - - $("#ul-" + modal.name + "-child-snapshots-" + modal.id).append("
  • " + _value + "
  • \n"); - } - - snapshots.count.snapshotswithclones++; - - $("#ul-" + modal.name + "-child-snapshotswithclones-" + modal.id).append("
  • " + _value + "
  • \n"); - }); - - $("#panelgroup-" + modal.name + "-" + modal.id).attr("data-filesystem-child-snapshots", snapshots.count.snapshots); - $("#panelgroup-" + modal.name + "-" + modal.id).attr("data-filesystem-child-snapshotswithclones", snapshots.count.snapshotswithclones); - } - - FnConsole.log[1]("File Systems, Child, Snapshots, Get: Success, Pool: " + pool.name + ", File System: " + filesystem.name); - }) - .fail(function (message, data) { - FnConsole.warn("File Systems, Child, Snapshots, Get: Failed, Pool: " + pool.name + ", File System: " + filesystem.name + ", Message: " + (data ? data : message)); - }); -} - -function FnFileSystemConfigurationGet(pool = { name, id, readonly: false }, filesystem = { name, id }, modal = { name, id }) { - let process = { - command: ["/sbin/zfs", "get", "readonly,aclinherit,acltype,atime,available,canmount,casesensitivity,checksum,compression,context,dedup,dnodesize,defcontext,encryption,encryptionroot,fscontext,guid,mountpoint,quota,recordsize,refreservation,rootcontext,sharenfs,sharesmb,special_small_blocks,used,xattr", "-H", "-o", "property,value,source", "-p", filesystem.name] - }; - - if (!zfsmanager.user.admin) { - pool.readonly = true; - } - - filesystem.available = ""; - filesystem.context = false; - filesystem.fscontext = false; - filesystem.defcontext = false; - filesystem.readonly = false; - filesystem.rootcontext = false; - - FnConsole.log[2]("File Systems, Configuration, Get: In Progress, Pool: " + pool.name + ", File System: " + filesystem.name); - FnConsole.log[3](FnConsoleCommand({ command: process.command })); - - return cockpit.spawn(process.command, { err: "out" }) - .done(function (data) { - FnConsole.log[4](FnConsoleVerbose({ data: data, message: "File Systems, Configuration, Get:" })); - - process.data = data.replace(/\t+/g, "\u22C5").split(/\n/g).filter(v => v); - - process.data.forEach((_value, _index) => { - _value = _value.split("\u22C5"); - - filesystem.properties = { - property: _value[0].toLowerCase(), - value: _value[1].toLowerCase(), - valueraw: _value[1], - source: _value[2] - }; - - let size = {}; - - switch (filesystem.properties.property) { - case "aclinherit": //Default is restricted - filesystem.property = { - value: "Restricted", - valueinherited: "" - }; - - switch (filesystem.properties.value) { - case "discard": - filesystem.property.value = "Discard"; - break; - case "noallow": - filesystem.property.value = "No Allow"; - break; - case "restricted": - filesystem.property.value = "Restricted"; - break; - case "passthrough": - filesystem.property.value = "Passthrough"; - break; - case "passthrough-x": - filesystem.property.value = "Passthrough-X"; - break; - default: - filesystem.property.value = "Restricted"; - break; - } - - if (/^inherited/gi.test(filesystem.properties.source)) { - filesystem.property.source = "inherited"; - filesystem.property.valueinherited = "Inherited (" + filesystem.property.value + ")"; - - $("#dropdown-" + modal.name + "-aclinherit-" + modal.id + " li[value='Inherited']").removeClass("hidden"); - $("#dropdown-" + modal.name + "-aclinherit-" + modal.id + " li[value='Inherited'] a").text(filesystem.property.valueinherited); - } else if (/^default|^local/gi.test(filesystem.properties.source)) { - $("#dropdown-" + modal.name + "-aclinherit-" + modal.id + " li[value='InheritedReset']").removeClass("hidden"); - - if (/^default/gi.test(filesystem.properties.source)) { - filesystem.property.source = "default"; - filesystem.property.valueinherited = "Default (Restricted)"; - - $("#dropdown-" + modal.name + "-aclinherit-" + modal.id + " li[value='InheritedReset'] a").text(filesystem.property.valueinherited); - } else if (/^local/gi.test(filesystem.properties.source) && filesystem.name == pool.name) { - filesystem.property.source = "local"; - - $("#dropdown-" + modal.name + "-aclinherit-" + modal.id + " li[value='InheritedReset'] a").text("Default (Restricted)"); - } else if (/^local/gi.test(filesystem.properties.source) && filesystem.name != pool.name) { - filesystem.property.source = "local"; - - FnFileSystemConfigurationInheritedPropertyGet({ name: pool.name, id: pool.id }, { name: filesystem.name, id: filesystem.id, property: "aclinherit" }, { name: modal.name, id: modal.id }); - } - } - - $("#btnspan-" + modal.name + "-aclinherit-" + modal.id).text((filesystem.property.valueinherited ? filesystem.property.valueinherited : filesystem.property.value)).attr("data-field-value", filesystem.properties.valueraw).attr("data-field-source", filesystem.property.source); - $("#dropdown-" + modal.name + "-aclinherit-" + modal.id + " li").siblings().removeClass("active"); - $("#dropdown-" + modal.name + "-aclinherit-" + modal.id + " li[value='" + (filesystem.property.valueinherited ? (filesystem.property.source == "inherited" ? "Inherited" : "InheritedReset") : filesystem.properties.valueraw) + "']").addClass("active"); - - if (filesystem.readonly && zfsmanager.configuration.zfs.filesystem.readonlylockdown || pool.readonly) { - $("#div-" + modal.name + "-aclinherit-dropdown-" + modal.id + " button").prop("disabled", true); - } - - break; - case "acltype": //Default is off - filesystem.property = { - value: "Off", - valueinherited: "" - }; - - switch (filesystem.properties.value) { - case "off": - filesystem.property.value = "Off"; - break; - case "noacl": - filesystem.property.value = "No ACL"; - break; - case "posixacl": - filesystem.property.value = "POSIX ACL"; - break; - default: - filesystem.property.value = "Off"; - break; - } - - if (/^inherited/gi.test(filesystem.properties.source)) { - filesystem.property.source = "inherited"; - filesystem.property.valueinherited = "Inherited (" + filesystem.property.value + ")"; - - $("#dropdown-" + modal.name + "-acltype-" + modal.id + " li[value='Inherited']").removeClass("hidden"); - $("#dropdown-" + modal.name + "-acltype-" + modal.id + " li[value='Inherited'] a").text(filesystem.property.valueinherited); - } else if (/^default|^local/gi.test(filesystem.properties.source)) { - $("#dropdown-" + modal.name + "-acltype-" + modal.id + " li[value='InheritedReset']").removeClass("hidden"); - - if (/^default/gi.test(filesystem.properties.source)) { - filesystem.property.source = "default"; - filesystem.property.valueinherited = "Default (Off)"; - - $("#dropdown-" + modal.name + "-acltype-" + modal.id + " li[value='InheritedReset'] a").text(filesystem.property.valueinherited); - } else if (/^local/gi.test(filesystem.properties.source) && filesystem.name == pool.name) { - filesystem.property.source = "local"; - - $("#dropdown-" + modal.name + "-acltype-" + modal.id + " li[value='InheritedReset'] a").text("Default (Off)"); - } else if (/^local/gi.test(filesystem.properties.source) && filesystem.name != pool.name) { - filesystem.property.source = "local"; - - FnFileSystemConfigurationInheritedPropertyGet({ name: pool.name, id: pool.id }, { name: filesystem.name, id: filesystem.id, property: "acltype" }, { name: modal.name, id: modal.id }); - } - } - - $("#btnspan-" + modal.name + "-acltype-" + modal.id).text((filesystem.property.valueinherited ? filesystem.property.valueinherited : filesystem.property.value)).attr("data-field-value", filesystem.properties.valueraw).attr("data-field-source", filesystem.property.source); - $("#dropdown-" + modal.name + "-acltype-" + modal.id + " li").siblings().removeClass("active"); - $("#dropdown-" + modal.name + "-acltype-" + modal.id + " li[value='" + (filesystem.property.valueinherited ? (filesystem.property.source == "inherited" ? "Inherited" : "InheritedReset") : filesystem.properties.valueraw) + "']").addClass("active"); - - if (filesystem.readonly && zfsmanager.configuration.zfs.filesystem.readonlylockdown || pool.readonly) { - $("#div-" + modal.name + "-acltype-dropdown-" + modal.id + " button").prop("disabled", true); - } - break; - case "atime": //Default is on - filesystem.property = { - source: "", - value: "On", - valueinherited: "" - }; - - switch (filesystem.properties.value) { - case "off": - filesystem.property.value = "Off"; - break; - case "on": - filesystem.property.value = "On"; - break; - default: - filesystem.property.value = "On"; - break; - } - - if (/^inherited/gi.test(filesystem.properties.source)) { - filesystem.property.source = "inherited"; - filesystem.property.valueinherited = "Inherited (" + filesystem.property.value + ")"; - - $("#dropdown-" + modal.name + "-atime-" + modal.id + " li[value='Inherited']").removeClass("hidden"); - $("#dropdown-" + modal.name + "-atime-" + modal.id + " li[value='Inherited'] a").text(filesystem.property.valueinherited); - } else if (/^default|^local/gi.test(filesystem.properties.source)) { - $("#dropdown-" + modal.name + "-atime-" + modal.id + " li[value='InheritedReset']").removeClass("hidden"); - - if (/^default/gi.test(filesystem.properties.source)) { - filesystem.property.source = "default"; - filesystem.property.valueinherited = "Default (On)"; - - $("#dropdown-" + modal.name + "-atime-" + modal.id + " li[value='InheritedReset'] a").text(filesystem.property.valueinherited); - } else if (/^local/gi.test(filesystem.properties.source) && filesystem.name == pool.name) { - filesystem.property.source = "local"; - - $("#dropdown-" + modal.name + "-atime-" + modal.id + " li[value='InheritedReset'] a").text("Default (On)"); - } else if (/^local/gi.test(filesystem.properties.source) && filesystem.name != pool.name) { - filesystem.property.source = "local"; - - FnFileSystemConfigurationInheritedPropertyGet({ name: pool.name, id: pool.id }, { name: filesystem.name, id: filesystem.id, property: "atime" }, { name: modal.name, id: modal.id }); - } - } - - $("#btnspan-" + modal.name + "-atime-" + modal.id).text((filesystem.property.valueinherited ? filesystem.property.valueinherited : filesystem.property.value)).attr("data-field-value", filesystem.properties.valueraw).attr("data-field-source", filesystem.property.source); - $("#dropdown-" + modal.name + "-atime-" + modal.id + " li").siblings().removeClass("active"); - $("#dropdown-" + modal.name + "-atime-" + modal.id + " li[value='" + (filesystem.property.valueinherited ? (filesystem.property.source == "inherited" ? "Inherited" : "InheritedReset") : filesystem.properties.valueraw) + "']").addClass("active"); - - if (filesystem.readonly && zfsmanager.configuration.zfs.filesystem.readonlylockdown || pool.readonly) { - $("#div-" + modal.name + "-atime-dropdown-" + modal.id + " button").prop("disabled", true); - } - break; - case "available": - filesystem.available = filesystem.properties.value; - - filesystem.property = { - value: "0 B" - }; - - if (filesystem.properties.value == "none" || filesystem.properties.value == "0" || filesystem.properties.value == "0b") { - filesystem.property.value = "0 B"; - } else { - filesystem.property.value = FnFormatBytes({ base2: true, decimals: 2, value: filesystem.properties.value }); - } - - $("#helpblock-" + modal.name + "-available-" + modal.id).text("Available size: " + filesystem.property.value); - break; - case "canmount": //Default is on - filesystem.property = { - value: "On" - }; - - switch (filesystem.properties.value) { - case "on": - filesystem.property.value = "On"; - break; - case "off": - filesystem.property.value = "Off"; - break; - case "noauto": - filesystem.property.value = "No Auto"; - break; - default: - filesystem.property.value = "On"; - break; - } - - $("#btnspan-" + modal.name + "-canmount-" + modal.id).text(filesystem.property.value).attr("data-field-value", filesystem.properties.value); - $("#dropdown-" + modal.name + "-canmount-" + modal.id + " li").siblings().removeClass("active"); - $("#dropdown-" + modal.name + "-canmount-" + modal.id + " li[value='" + filesystem.properties.valueraw + "']").addClass("active"); - - if (filesystem.readonly && zfsmanager.configuration.zfs.filesystem.readonlylockdown || pool.readonly) { - $("#div-" + modal.name + "-canmount-dropdown-" + modal.id + " button").prop("disabled", true); - } - break; - case "casesensitivity": //Default is sensitive - $("#div-" + modal.name + "-casesensitivity-" + modal.id).text(filesystem.properties.value.charAt(0).toUpperCase() + filesystem.properties.value.slice(1)); - break; - case "checksum": //Default is on - filesystem.property = { - value: "On", - valueinherited: "" - }; - - switch (filesystem.properties.value) { - case "on": - filesystem.property.value = "On"; - break; - case "off": - filesystem.property.value = "Off"; - break; - case "edonr": - filesystem.property.value = "Edon-R"; - break; - case "fletcher2": - filesystem.property.value = "Fletcher2"; - break; - case "fletcher4": - filesystem.property.value = "Fletcher4"; - break; - case "noparity": - filesystem.property.value = "No Parity"; - break; - case "sha256": - filesystem.property.value = "SHA-256"; - break; - case "sha512": - filesystem.property.value = "SHA-512"; - break; - case "skein": - filesystem.property.value = "Skein"; - break; - default: - filesystem.property.value = "On"; - break; - } - - if (/^inherited/gi.test(filesystem.properties.source)) { - filesystem.property.source = "inherited"; - filesystem.property.valueinherited = "Inherited (" + filesystem.property.value + ")"; - - $("#dropdown-" + modal.name + "-checksum-" + modal.id + " li[value='Inherited']").removeClass("hidden"); - $("#dropdown-" + modal.name + "-checksum-" + modal.id + " li[value='Inherited'] a").text(filesystem.property.valueinherited); - } else if (/^default|^local/gi.test(filesystem.properties.source)) { - $("#dropdown-" + modal.name + "-checksum-" + modal.id + " li[value='InheritedReset']").removeClass("hidden"); - - if (/^default/gi.test(filesystem.properties.source)) { - filesystem.property.source = "default"; - filesystem.property.valueinherited = "Default (On)"; - - $("#dropdown-" + modal.name + "-checksum-" + modal.id + " li[value='InheritedReset'] a").text(filesystem.property.valueinherited); - } else if (/^local/gi.test(filesystem.properties.source) && filesystem.name == pool.name) { - filesystem.property.source = "local"; - - $("#dropdown-" + modal.name + "-checksum-" + modal.id + " li[value='InheritedReset'] a").text("Default (On)"); - } else if (/^local/gi.test(filesystem.properties.source) && filesystem.name != pool.name) { - filesystem.property.source = "local"; - - FnFileSystemConfigurationInheritedPropertyGet({ name: pool.name, id: pool.id }, { name: filesystem.name, id: filesystem.id, property: "checksum" }, { name: modal.name, id: modal.id }); - } - } - - $("#btnspan-" + modal.name + "-checksum-" + modal.id).text((filesystem.property.valueinherited ? filesystem.property.valueinherited : filesystem.property.value)).attr("data-field-value", filesystem.properties.valueraw).attr("data-field-source", filesystem.property.source); - $("#dropdown-" + modal.name + "-checksum-" + modal.id + " li").siblings().removeClass("active"); - $("#dropdown-" + modal.name + "-checksum-" + modal.id + " li[value='" + (filesystem.property.valueinherited ? (filesystem.property.source == "inherited" ? "Inherited" : "InheritedReset") : filesystem.properties.valueraw) + "']").addClass("active"); - - if (filesystem.readonly && zfsmanager.configuration.zfs.filesystem.readonlylockdown || pool.readonly) { - $("#div-" + modal.name + "-checksum-dropdown-" + modal.id + " button").prop("disabled", true); - } - break; - case "compression": //Default is off - filesystem.property = { - value: "Off", - valueinherited: "" - }; - - switch (filesystem.properties.value) { - case "on": - filesystem.property.value = "On"; - break; - case "gzip": - filesystem.property.value = "GZIP"; - break; - case "lz4": - filesystem.property.value = "LZ4"; - break; - case "lzjb": - filesystem.property.value = "LZJB"; - break; - case "zle": - filesystem.property.value = "ZLE"; - break; - default: - filesystem.property.value = "Off"; - break; - } - - if (/^inherited/gi.test(filesystem.properties.source)) { - filesystem.property.source = "inherited"; - filesystem.property.valueinherited = "Inherited (" + filesystem.property.value + ")"; - - $("#dropdown-" + modal.name + "-compression-" + modal.id + " li[value='Inherited']").removeClass("hidden"); - $("#dropdown-" + modal.name + "-compression-" + modal.id + " li[value='Inherited'] a").text(filesystem.property.valueinherited); - } else if (/^default|^local/gi.test(filesystem.properties.source)) { - $("#dropdown-" + modal.name + "-compression-" + modal.id + " li[value='InheritedReset']").removeClass("hidden"); - - if (/^default/gi.test(filesystem.properties.source)) { - filesystem.property.source = "default"; - filesystem.property.valueinherited = "Default (Off)"; - - $("#dropdown-" + modal.name + "-compression-" + modal.id + " li[value='InheritedReset'] a").text(filesystem.property.valueinherited); - } else if (/^local/gi.test(filesystem.properties.source) && filesystem.name == pool.name) { - filesystem.property.source = "local"; - - $("#dropdown-" + modal.name + "-compression-" + modal.id + " li[value='InheritedReset'] a").text("Default (Off)"); - } else if (/^local/gi.test(filesystem.properties.source) && filesystem.name != pool.name) { - filesystem.property.source = "local"; - - FnFileSystemConfigurationInheritedPropertyGet({ name: pool.name, id: pool.id }, { name: filesystem.name, id: filesystem.id, property: "compression" }, { name: modal.name, id: modal.id }); - } - } - - $("#btnspan-" + modal.name + "-compression-" + modal.id).text((filesystem.property.valueinherited ? filesystem.property.valueinherited : filesystem.property.value)).attr("data-field-value", filesystem.properties.valueraw).attr("data-field-source", filesystem.property.source); - $("#dropdown-" + modal.name + "-compression-" + modal.id + " li").siblings().removeClass("active"); - $("#dropdown-" + modal.name + "-compression-" + modal.id + " li[value='" + (filesystem.property.valueinherited ? (filesystem.property.source == "inherited" ? "Inherited" : "InheritedReset") : filesystem.properties.valueraw) + "']").addClass("active"); - - if (filesystem.readonly && zfsmanager.configuration.zfs.filesystem.readonlylockdown || pool.readonly) { - $("#div-" + modal.name + "-compression-dropdown-" + modal.id + " button").prop("disabled", true); - } - break; - case "context": //Default is empty - if (filesystem.properties.value == "system_u:object_r:samba_share_t:s0") { - filesystem.context = true; - } - break; - case "dedup": //Default is off - filesystem.property = { - value: "Off", - valueinherited: "" - }; - - switch (filesystem.properties.value) { - case "on": - filesystem.property.value = "On"; - break; - case "off": - filesystem.property.value = "Off"; - break; - case "edonr,verify": - filesystem.property.value = "Edon-R + Verify"; - break; - case "sha256": - filesystem.property.value = "SHA-256"; - break; - case "sha256,verify": - filesystem.property.value = "SHA-256 + Verify"; - break; - case "sha512": - filesystem.property.value = "SHA-512"; - break; - case "sha512,verify": - filesystem.property.value = "SHA-512 + Verify"; - break; - case "skein": - filesystem.property.value = "Skein"; - break; - case "skein,verify": - filesystem.property.value = "Skein + Verify"; - break; - case "verify": - filesystem.property.value = "Verify"; - break; - default: - filesystem.property.value = "Off"; - break; - } - - if (/^inherited/gi.test(filesystem.properties.source)) { - filesystem.property.source = "inherited"; - filesystem.property.valueinherited = "Inherited (" + filesystem.property.value + ")"; - - $("#dropdown-" + modal.name + "-dedup-" + modal.id + " li[value='Inherited']").removeClass("hidden"); - $("#dropdown-" + modal.name + "-dedup-" + modal.id + " li[value='Inherited'] a").text(filesystem.property.valueinherited); - } else if (/^default|^local/gi.test(filesystem.properties.source)) { - $("#dropdown-" + modal.name + "-dedup-" + modal.id + " li[value='InheritedReset']").removeClass("hidden"); - - if (/^default/gi.test(filesystem.properties.source)) { - filesystem.property.source = "default"; - filesystem.property.valueinherited = "Default (Off)"; - - $("#dropdown-" + modal.name + "-dedup-" + modal.id + " li[value='InheritedReset'] a").text(filesystem.property.valueinherited); - } else if (/^local/gi.test(filesystem.properties.source) && filesystem.name == pool.name) { - filesystem.property.source = "local"; - - $("#dropdown-" + modal.name + "-dedup-" + modal.id + " li[value='InheritedReset'] a").text("Default (Off)"); - } else if (/^local/gi.test(filesystem.properties.source) && filesystem.name != pool.name) { - filesystem.property.source = "local"; - - FnFileSystemConfigurationInheritedPropertyGet({ name: pool.name, id: pool.id }, { name: filesystem.name, id: filesystem.id, property: "dedup" }, { name: modal.name, id: modal.id }); - } - } - - $("#btnspan-" + modal.name + "-dedup-" + modal.id).text((filesystem.property.valueinherited ? filesystem.property.valueinherited : filesystem.property.value)).attr("data-field-value", filesystem.properties.valueraw).attr("data-field-source", filesystem.property.source); - $("#dropdown-" + modal.name + "-dedup-" + modal.id + " li").siblings().removeClass("active"); - $("#dropdown-" + modal.name + "-dedup-" + modal.id + " li[value='" + (filesystem.property.valueinherited ? (filesystem.property.source == "inherited" ? "Inherited" : "InheritedReset") : filesystem.properties.valueraw) + "']").addClass("active"); - - if (filesystem.readonly && zfsmanager.configuration.zfs.filesystem.readonlylockdown || pool.readonly) { - $("#div-" + modal.name + "-dedup-dropdown-" + modal.id + " button").prop("disabled", true); - } - break; - case "dnodesize": //Default is legacy - filesystem.property = { - value: "Off", - valueinherited: "" - }; - - switch (filesystem.properties.value) { - case "1k": - filesystem.property.value = "1 KiB"; - break; - case "2k": - filesystem.property.value = "2 KiB"; - break; - case "4k": - filesystem.property.value = "4 KiB"; - break; - case "8k": - filesystem.property.value = "8 KiB"; - break; - case "16k": - filesystem.property.value = "16 KiB"; - break; - case "auto": - filesystem.property.value = "Auto"; - break; - case "legacy": - filesystem.property.value = "Legacy"; - break; - default: - filesystem.property.value = "Legacy"; - break; - } - - if (/^inherited/gi.test(filesystem.properties.source)) { - filesystem.property.source = "inherited"; - filesystem.property.valueinherited = "Inherited (" + filesystem.property.value + ")"; - - $("#dropdown-" + modal.name + "-dnodesize-" + modal.id + " li[value='Inherited']").removeClass("hidden"); - $("#dropdown-" + modal.name + "-dnodesize-" + modal.id + " li[value='Inherited'] a").text(filesystem.property.valueinherited); - } else if (/^default|^local/gi.test(filesystem.properties.source)) { - $("#dropdown-" + modal.name + "-dnodesize-" + modal.id + " li[value='InheritedReset']").removeClass("hidden"); - - if (/^default/gi.test(filesystem.properties.source)) { - filesystem.property.source = "default"; - filesystem.property.valueinherited = "Default (Legacy)"; - - $("#dropdown-" + modal.name + "-dnodesize-" + modal.id + " li[value='InheritedReset'] a").text(filesystem.property.valueinherited); - } else if (/^local/gi.test(filesystem.properties.source) && filesystem.name == pool.name) { - filesystem.property.source = "local"; - - $("#dropdown-" + modal.name + "-dnodesize-" + modal.id + " li[value='InheritedReset'] a").text("Default (Legacy)"); - } else if (/^local/gi.test(filesystem.properties.source) && filesystem.name != pool.name) { - filesystem.property.source = "local"; - - FnFileSystemConfigurationInheritedPropertyGet({ name: pool.name, id: pool.id }, { name: filesystem.name, id: filesystem.id, property: "dnodesize" }, { name: modal.name, id: modal.id }); - } - } - - $("#btnspan-" + modal.name + "-dnodesize-" + modal.id).text((filesystem.property.valueinherited ? filesystem.property.valueinherited : filesystem.property.value)).attr("data-field-value", filesystem.properties.valueraw).attr("data-field-source", filesystem.property.source); - $("#dropdown-" + modal.name + "-dnodesize-" + modal.id + " li").siblings().removeClass("active"); - $("#dropdown-" + modal.name + "-dnodesize-" + modal.id + " li[value='" + (filesystem.property.valueinherited ? (filesystem.property.source == "inherited" ? "Inherited" : "InheritedReset") : filesystem.properties.valueraw) + "']").addClass("active"); - - if (filesystem.readonly && zfsmanager.configuration.zfs.filesystem.readonlylockdown || pool.readonly) { - $("#div-" + modal.name + "-dnodesize-dropdown-" + modal.id + " button").prop("disabled", true); - } - break; - case "defcontext": //Default is empty - if (filesystem.properties.value == "system_u:object_r:samba_share_t:s0") { - filesystem.defcontext = true; - } - break; - case "encryption": //Default is off - filesystem.property = { - value: "Off" - }; - - switch (filesystem.properties.value) { - case "on": - filesystem.property.value = "On"; - break; - case "off": - filesystem.property.value = "Off"; - break; - case "aes-128-ccm": - filesystem.property.value = "AES-128-CCM"; - break; - case "aes-192-ccm": - filesystem.property.value = "AES-192-CCM"; - break; - case "aes-256-ccm": - filesystem.property.value = "AES-256-CCM"; - break; - case "aes-128-gcm": - filesystem.property.value = "AES-128-GCM"; - break; - case "aes-192-gcm": - filesystem.property.value = "AES-192-GCM"; - break; - case "aes-256-gcm": - filesystem.property.value = "AES-256-GCM"; - break; - default: - filesystem.property.value = "Off"; - break; - } - - $("#div-" + modal.name + "-encryption-" + modal.id).text(filesystem.property.value); - - if (filesystem.property.value != "Off") { - $("#controllabel-" + modal.name + "-encryption-" + modal.id).removeClass("hidden"); - $("#div-" + modal.name + "-encryption-" + modal.id).removeClass("hidden"); - } - break; - case "encryptionroot": - if (filesystem.properties.valueraw && filesystem.properties.valueraw == "-") { - filesystem.properties.valueraw = ""; - } - - if (filesystem.properties.valueraw && filesystem.properties.valueraw != filesystem.name) { - $("#controllabel-" + modal.name + "-encryptionroot-" + modal.id).removeClass("hidden"); - $("#div-" + modal.name + "-encryptionroot-" + modal.id).text(filesystem.properties.valueraw).removeClass("hidden"); - } - break; - case "fscontext": //Default is empty - if (filesystem.properties.value == "system_u:object_r:samba_share_t:s0") { - filesystem.fscontext = true; - } - break; - case "guid": - $("#div-" + modal.name + "-guid-" + modal.id).text(filesystem.properties.value); - break; - case "mountpoint": - $("#input-" + modal.name + "-mountpoint-" + modal.id).val(filesystem.properties.valueraw).attr("data-field-value", filesystem.properties.valueraw); - - if (filesystem.readonly && zfsmanager.configuration.zfs.filesystem.readonlylockdown || pool.readonly) { - $("#input-" + modal.name + "-mountpoint-" + modal.id).prop("disabled", true); - } - break; - case "quota": //Default is none - filesystem.property = { - value: "0 B", - valueraw: "0", - valueunit: "KiB" - }; - - if (filesystem.properties.value == "none" || filesystem.properties.value == "0" || filesystem.properties.value == "0b") { - filesystem.property.value = "0 B"; - } else { - filesystem.property.value = FnFormatBytes({ base2: true, decimals: 1, value: filesystem.properties.value }); - - if (/KiB/g.test(filesystem.property.value)) { - filesystem.property.valueunit = "KiB"; - } else if (/MiB/g.test(filesystem.property.value)) { - filesystem.property.valueunit = "MiB"; - } else if (/GiB/g.test(filesystem.property.value)) { - filesystem.property.valueunit = "GiB"; - } else if (/TiB/g.test(filesystem.property.value)) { - filesystem.property.valueunit = "TiB"; - } - - filesystem.property.valueraw = filesystem.property.value.toString().replace(" " + filesystem.property.valueunit, ""); - } - - $("#input-" + modal.name + "-quota-" + modal.id).val(filesystem.property.valueraw); - - size.quota = { - quota: parseInt(filesystem.properties.value), - max: { - raw: 1099511627776000, - unit: "", - unitnumber: 0 - }, - slider: { - valuemax: 1000 - }, - property: filesystem.property - }; - - FnStoragePoolSizeGet({ name: pool.name, id: null }) - .done(function (_data) { - FnConsole.log[4](FnConsoleVerbose({ data: _data, message: "Storage Pools, Size, Get:" })); - - if (_data && zfsmanager.configuration.zfs.filesystem.quotarestrict) { - size.quota.max.raw = parseInt(_data.replace(/\n+/g, "")); - } - }) - .finally(function () { - size.quota.max.raw = (size.quota.max.raw > size.quota.quota ? size.quota.max.raw : size.quota.quota); - size.quota.max.unitnumber = FnFormatBytes({ base2: true, decimals: 2, value: size.quota.max.raw }).replace(/ .*$/g, ""); - size.quota.max.unit = FnFormatBytes({ base2: true, decimals: 2, value: size.quota.max.raw }).replace(/ /g, "").replace(/^[0-9.]/, ""); - - if (size.quota.max.raw <= 1024000) { - $("#input-" + modal.name + "-quota-" + modal.id).attr("data-filesystem-quota-max-kib", size.quota.max.unitnumber); - } - if (size.quota.max.raw > 1024000) { - $("#dropdown-" + modal.name + "-quota-" + modal.id + " li[value='MiB']").removeClass("hidden"); - - $("#input-" + modal.name + "-quota-" + modal.id).attr("data-filesystem-quota-max-kib", size.quota.slider.valuemax); - $("#input-" + modal.name + "-quota-" + modal.id).attr("data-filesystem-quota-max-mib", size.quota.max.unitnumber); - } - if (size.quota.max.raw > 1048576000) { - $("#dropdown-" + modal.name + "-quota-" + modal.id + " li[value='GiB']").removeClass("hidden"); - - $("#input-" + modal.name + "-quota-" + modal.id).attr("data-filesystem-quota-max-kib", size.quota.slider.valuemax); - $("#input-" + modal.name + "-quota-" + modal.id).attr("data-filesystem-quota-max-mib", size.quota.slider.valuemax); - $("#input-" + modal.name + "-quota-" + modal.id).attr("data-filesystem-quota-max-gib", size.quota.max.unitnumber); - } - if (size.quota.max.raw > 1073741824000) { - $("#dropdown-" + modal.name + "-quota-" + modal.id + " li[value='TiB']").removeClass("hidden"); - - $("#input-" + modal.name + "-quota-" + modal.id).attr("data-filesystem-quota-max-kib", size.quota.slider.valuemax); - $("#input-" + modal.name + "-quota-" + modal.id).attr("data-filesystem-quota-max-mib", size.quota.slider.valuemax); - $("#input-" + modal.name + "-quota-" + modal.id).attr("data-filesystem-quota-max-gib", size.quota.slider.valuemax); - $("#input-" + modal.name + "-quota-" + modal.id).attr("data-filesystem-quota-max-tib", size.quota.max.unitnumber); - } - - if (size.quota.property.valueunit == "KiB") { - size.quota.slider.valuemax = $("#input-" + modal.name + "-quota-" + modal.id).attr("data-filesystem-quota-max-kib"); - } - if (size.quota.property.valueunit == "MiB") { - size.quota.slider.valuemax = $("#input-" + modal.name + "-quota-" + modal.id).attr("data-filesystem-quota-max-mib"); - } - if (size.quota.property.valueunit == "GiB") { - size.quota.slider.valuemax = $("#input-" + modal.name + "-quota-" + modal.id).attr("data-filesystem-quota-max-gib"); - } - if (size.quota.property.valueunit == "TiB") { - size.quota.slider.valuemax = $("#input-" + modal.name + "-quota-" + modal.id).attr("data-filesystem-quota-max-tib"); - } - - $("#slider-" + modal.name + "-quota-" + modal.id).data("slider").options.max = size.quota.slider.valuemax; - $("#slider-" + modal.name + "-quota-" + modal.id).data("slider").options.step = (size.quota.slider.valuemax < 10 ? "0.1" : "1"); - $("#slider-" + modal.name + "-quota-" + modal.id).slider("setValue", size.quota.property.valueraw); - - $("#btnspan-" + modal.name + "-quota-" + modal.id).text(size.quota.property.valueunit).attr("data-field-value", size.quota.property.valueunit); - $("#dropdown-" + modal.name + "-quota-" + modal.id + " li").siblings().removeClass("active"); - $("#dropdown-" + modal.name + "-quota-" + modal.id + " li[value='" + size.quota.property.valueunit + "']").addClass("active"); - $("#input-" + modal.name + "-quota-" + modal.id).attr("data-field-value", size.quota.property.value.toString().replace(/ /g, "").replace(/iB$/g, "")); - }); - - if (filesystem.readonly && zfsmanager.configuration.zfs.filesystem.readonlylockdown || pool.readonly) { - $("#input-" + modal.name + "-quota-" + modal.id).prop("disabled", true); - $("#div-" + modal.name + "-quota-dropdown-" + modal.id + " button").prop("disabled", true); - $("#validationwrapper-" + modal.name + "-quota-" + modal.id + " .slider-pf .slider *").addClass("disabled"); - $("#slider-" + modal.name + "-quota-" + modal.id).slider("disable"); - } - break; - case "readonly": //Default is off - if (filesystem.properties.value == "on") { - filesystem.readonly = true; - } - - if (filesystem.properties.value == "on" && !$("#switch-" + modal.name + "-readonly-" + modal.id + " input").prop("checked")) { - $("#switch-" + modal.name + "-readonly-" + modal.id + " input").click(); - } - - $("#switch-" + modal.name + "-readonly-" + modal.id).attr("data-field-value", filesystem.properties.value); - - if (pool.readonly) { - $("#switch-" + modal.name + "-readonly-" + modal.id + " input").prop("disabled", true); - } - break; - case "recordsize": //Default is 128K - filesystem.property = { - value: FnFormatBytes({ base2: true, decimals: 0, value: filesystem.properties.value }), - valueinherited: "" - }; - - if (/^inherited/gi.test(filesystem.properties.source)) { - filesystem.property.source = "inherited"; - filesystem.property.valueinherited = "Inherited (" + filesystem.property.value + ")"; - - $("#dropdown-" + modal.name + "-recordsize-" + modal.id + " li[value='Inherited']").removeClass("hidden"); - $("#dropdown-" + modal.name + "-recordsize-" + modal.id + " li[value='Inherited'] a").text(filesystem.property.valueinherited); - } else if (/^default|^local/gi.test(filesystem.properties.source)) { - $("#dropdown-" + modal.name + "-recordsize-" + modal.id + " li[value='InheritedReset']").removeClass("hidden"); - - if (/^default/gi.test(filesystem.properties.source)) { - filesystem.property.source = "default"; - filesystem.property.valueinherited = "Default (128 KiB)"; - - $("#dropdown-" + modal.name + "-recordsize-" + modal.id + " li[value='InheritedReset'] a").text(filesystem.property.valueinherited); - } else if (/^local/gi.test(filesystem.properties.source) && filesystem.name == pool.name) { - filesystem.property.source = "local"; - - $("#dropdown-" + modal.name + "-recordsize-" + modal.id + " li[value='InheritedReset'] a").text("Default (128 KiB)"); - } else if (/^local/gi.test(filesystem.properties.source) && filesystem.name != pool.name) { - filesystem.property.source = "local"; - - FnFileSystemConfigurationInheritedPropertyGet({ name: pool.name, id: pool.id }, { name: filesystem.name, id: filesystem.id, property: "recordsize" }, { name: modal.name, id: modal.id }); - } - } - - $("#btnspan-" + modal.name + "-recordsize-" + modal.id).text((filesystem.property.valueinherited ? filesystem.property.valueinherited : filesystem.property.value)).attr("data-field-value", filesystem.properties.valueraw).attr("data-field-source", filesystem.property.source); - $("#dropdown-" + modal.name + "-recordsize-" + modal.id + " li").siblings().removeClass("active"); - $("#dropdown-" + modal.name + "-recordsize-" + modal.id + " li[value='" + (filesystem.property.valueinherited ? (filesystem.property.source == "inherited" ? "Inherited" : "InheritedReset") : filesystem.properties.valueraw) + "']").addClass("active"); - - if (filesystem.readonly && zfsmanager.configuration.zfs.filesystem.readonlylockdown || pool.readonly) { - $("#div-" + modal.name + "-recordsize-dropdown-" + modal.id + " button").prop("disabled", true); - } - break; - case "refreservation": //Default is none / 0 - filesystem.property = { - value: "0 B", - valueraw: "0", - valueunit: "KiB" - }; - - if (filesystem.properties.value == "none" || filesystem.properties.value == "0" || filesystem.properties.value == "0b") { - filesystem.property.value = "0 B"; - } else { - filesystem.property.value = FnFormatBytes({ base2: true, decimals: 1, value: filesystem.properties.value }); - - if (/KiB/g.test(filesystem.property.value)) { - filesystem.property.valueunit = "KiB"; - } else if (/MiB/g.test(filesystem.property.value)) { - filesystem.property.valueunit = "MiB"; - } else if (/GiB/g.test(filesystem.property.value)) { - filesystem.property.valueunit = "GiB"; - } else if (/TiB/g.test(filesystem.property.value)) { - filesystem.property.valueunit = "TiB"; - } - - filesystem.property.valueraw = filesystem.property.value.toString().replace(" " + filesystem.property.valueunit, ""); - } - - $("#input-" + modal.name + "-refreservation-" + modal.id).val(filesystem.property.valueraw); - - size.refreservation = { - available: parseInt(filesystem.available), - refreservation: parseInt(filesystem.properties.value), - max: { - raw: 0, - unit: "", - unitnumber: 0 - }, - slider: { - valuemax: 1000 - } - }; - - size.refreservation.max.raw = (size.refreservation.available > size.refreservation.refreservation ? size.refreservation.available : size.refreservation.refreservation); - size.refreservation.max.unitnumber = FnFormatBytes({ base2: true, decimals: 2, value: size.refreservation.max.raw }).replace(/ .*$/g, ""); - size.refreservation.max.unit = FnFormatBytes({ base2: true, decimals: 2, value: size.refreservation.max.raw }).replace(/ /g, "").replace(/^[0-9.]/, ""); - - if (size.refreservation.max.raw <= 1024000) { - $("#input-" + modal.name + "-refreservation-" + modal.id).attr("data-filesystem-refreservation-max-kib", size.refreservation.max.unitnumber); - } - if (size.refreservation.max.raw > 1024000) { - $("#dropdown-" + modal.name + "-refreservation-" + modal.id + " li[value='MiB']").removeClass("hidden"); - - $("#input-" + modal.name + "-refreservation-" + modal.id).attr("data-filesystem-refreservation-max-kib", size.refreservation.slider.valuemax); - $("#input-" + modal.name + "-refreservation-" + modal.id).attr("data-filesystem-refreservation-max-mib", size.refreservation.max.unitnumber); - } - if (size.refreservation.max.raw > 1048576000) { - $("#dropdown-" + modal.name + "-refreservation-" + modal.id + " li[value='GiB']").removeClass("hidden"); - - $("#input-" + modal.name + "-refreservation-" + modal.id).attr("data-filesystem-refreservation-max-kib", size.refreservation.slider.valuemax); - $("#input-" + modal.name + "-refreservation-" + modal.id).attr("data-filesystem-refreservation-max-mib", size.refreservation.slider.valuemax); - $("#input-" + modal.name + "-refreservation-" + modal.id).attr("data-filesystem-refreservation-max-gib", size.refreservation.max.unitnumber); - } - if (size.refreservation.max.raw > 1073741824000) { - $("#dropdown-" + modal.name + "-refreservation-" + modal.id + " li[value='TiB']").removeClass("hidden"); - - $("#input-" + modal.name + "-refreservation-" + modal.id).attr("data-filesystem-refreservation-max-kib", size.refreservation.slider.valuemax); - $("#input-" + modal.name + "-refreservation-" + modal.id).attr("data-filesystem-refreservation-max-mib", size.refreservation.slider.valuemax); - $("#input-" + modal.name + "-refreservation-" + modal.id).attr("data-filesystem-refreservation-max-gib", size.refreservation.slider.valuemax); - $("#input-" + modal.name + "-refreservation-" + modal.id).attr("data-filesystem-refreservation-max-tib", size.refreservation.max.unitnumber); - } - - if (filesystem.property.valueunit == "KiB") { - size.refreservation.slider.valuemax = $("#input-" + modal.name + "-refreservation-" + modal.id).attr("data-filesystem-refreservation-max-kib"); - } - if (filesystem.property.valueunit == "MiB") { - size.refreservation.slider.valuemax = $("#input-" + modal.name + "-refreservation-" + modal.id).attr("data-filesystem-refreservation-max-mib"); - } - if (filesystem.property.valueunit == "GiB") { - size.refreservation.slider.valuemax = $("#input-" + modal.name + "-refreservation-" + modal.id).attr("data-filesystem-refreservation-max-gib"); - } - if (filesystem.property.valueunit == "TiB") { - size.refreservation.slider.valuemax = $("#input-" + modal.name + "-refreservation-" + modal.id).attr("data-filesystem-refreservation-max-tib"); - } - - $("#slider-" + modal.name + "-refreservation-" + modal.id).data("slider").options.max = size.refreservation.slider.valuemax; - $("#slider-" + modal.name + "-refreservation-" + modal.id).data("slider").options.step = (size.refreservation.slider.valuemax < 10 ? "0.1" : "1"); - $("#slider-" + modal.name + "-refreservation-" + modal.id).slider("setValue", filesystem.property.valueraw); - - $("#btnspan-" + modal.name + "-refreservation-" + modal.id).text(filesystem.property.valueunit).attr("data-field-value", filesystem.property.valueunit); - $("#dropdown-" + modal.name + "-refreservation-" + modal.id + " li").siblings().removeClass("active"); - $("#dropdown-" + modal.name + "-refreservation-" + modal.id + " li[value='" + filesystem.property.valueunit + "']").addClass("active"); - $("#input-" + modal.name + "-refreservation-" + modal.id).attr("data-field-value", filesystem.property.value.toString().replace(/ /g, "").replace(/iB$/g, "")); - - if (filesystem.readonly && zfsmanager.configuration.zfs.filesystem.readonlylockdown || pool.readonly) { - $("#input-" + modal.name + "-refreservation-" + modal.id).prop("disabled", true); - $("#div-" + modal.name + "-refreservation-dropdown-" + modal.id + " button").prop("disabled", true); - $("#validationwrapper-" + modal.name + "-refreservation-" + modal.id + " .slider-pf .slider *").addClass("disabled"); - $("#slider-" + modal.name + "-refreservation-" + modal.id).slider("disable"); - } - break; - case "rootcontext": //Default is empty - if (filesystem.properties.value == "system_u:object_r:samba_share_t:s0") { - filesystem.rootcontext = true; - } - break; - case "sharenfs": //Default is off - if (filesystem.properties.value != "off") { - if (!$("#switch-" + modal.name + "-sharenfs-" + modal.id + " input").prop("checked")) { - $("#switch-" + modal.name + "-sharenfs-" + modal.id + " input").click(); - } - - $("#controllabel-" + modal.name + "-sharenfs-options-" + modal.id).removeClass("hidden"); - $("#validationwrapper-" + modal.name + "-sharenfs-options-" + modal.id).removeClass("hidden"); - $("#input-" + modal.name + "-sharenfs-options-" + modal.id).val((filesystem.properties.value == "on" ? "sec=sys,rw,crossmnt,no_subtree_check,no_root_squash" : filesystem.properties.value)); - - FnSystemNfsVersionGet({ alert: { id: $("#alert-" + modal.name + "-sharenfs-options-" + modal.id) } }); - } - - $("#input-" + modal.name + "-sharenfs-options-" + modal.id).attr("data-field-value", filesystem.properties.value); - - if (filesystem.readonly && zfsmanager.configuration.zfs.filesystem.readonlylockdown || pool.readonly) { - $("#switch-" + modal.name + "-sharenfs-" + modal.id + " input").prop("disabled", true); - $("#input-" + modal.name + "-sharenfs-options-" + modal.id).prop("disabled", true); - } - break; - case "sharesmb": - if (filesystem.properties.value == "on" && !$("#switch-" + modal.name + "-sharesmb-" + modal.id + " input").prop("checked")) { - $("#switch-" + modal.name + "-sharesmb-" + modal.id + " input").click(); - } - - if (pool.readonly || zfsmanager.configuration.samba.manage) { - $("#switch-" + modal.name + "-sharesmb-" + modal.id + " input").prop("disabled", true); - } - - $("#switch-" + modal.name + "-sharesmb-" + modal.id).attr("data-field-value", filesystem.properties.value); - break; - case "special_small_blocks": //Default is 0 - filesystem.property = { - value: FnFormatBytes({ base2: true, decimals: 0, value: filesystem.properties.value }), - valueinherited: "" - }; - - if (/^inherited/gi.test(filesystem.properties.source)) { - filesystem.property.source = "inherited"; - filesystem.property.valueinherited = "Inherited (" + filesystem.property.value + ")"; - - $("#dropdown-" + modal.name + "-special_small_blocks-" + modal.id + " li[value='Inherited']").removeClass("hidden"); - $("#dropdown-" + modal.name + "-special_small_blocks-" + modal.id + " li[value='Inherited'] a").text(filesystem.property.valueinherited); - } else if (/^default|^local/gi.test(filesystem.properties.source)) { - $("#dropdown-" + modal.name + "-special_small_blocks-" + modal.id + " li[value='InheritedReset']").removeClass("hidden"); - - if (/^default/gi.test(filesystem.properties.source)) { - filesystem.property.source = "default"; - filesystem.property.valueinherited = "Default (0 B)"; - - $("#dropdown-" + modal.name + "-special_small_blocks-" + modal.id + " li[value='InheritedReset'] a").text(filesystem.property.valueinherited); - } else if (/^local/gi.test(filesystem.properties.source) && filesystem.name == pool.name) { - filesystem.property.source = "local"; - - $("#dropdown-" + modal.name + "-special_small_blocks-" + modal.id + " li[value='InheritedReset'] a").text("Default (0 B)"); - } else if (/^local/gi.test(filesystem.properties.source) && filesystem.name != pool.name) { - filesystem.property.source = "local"; - - FnFileSystemConfigurationInheritedPropertyGet({ name: pool.name, id: pool.id }, { name: filesystem.name, id: filesystem.id, property: "special_small_blocks" }, { name: modal.name, id: modal.id }); - } - } - - $("#btnspan-" + modal.name + "-special_small_blocks-" + modal.id).text((filesystem.property.valueinherited ? filesystem.property.valueinherited : filesystem.property.value)).attr("data-field-value", filesystem.properties.valueraw).attr("data-field-source", filesystem.property.source); - $("#dropdown-" + modal.name + "-special_small_blocks-" + modal.id + " li").siblings().removeClass("active"); - $("#dropdown-" + modal.name + "-special_small_blocks-" + modal.id + " li[value='" + (filesystem.property.valueinherited ? (filesystem.property.source == "inherited" ? "Inherited" : "InheritedReset") : filesystem.properties.valueraw) + "']").addClass("active"); - - if (filesystem.readonly && zfsmanager.configuration.zfs.filesystem.readonlylockdown || pool.readonly) { - $("#div-" + modal.name + "-special_small_blocks-dropdown-" + modal.id + " button").prop("disabled", true); - } - break; - case "used": - filesystem.used = filesystem.properties.value; - - filesystem.property = { - value: "0 B" - }; - - if (filesystem.properties.value == "none" || filesystem.properties.value == "0" || filesystem.properties.value == "0b") { - filesystem.property.value = "0 B"; - } else { - filesystem.property.value = FnFormatBytes({ base2: true, decimals: 2, value: filesystem.properties.value }); - } - - $("#helpblock-" + modal.name + "-used-" + modal.id).text("Used size: " + filesystem.property.value); - break; - case "xattr": //Default is on - filesystem.property = { - value: "On", - valueinherited: "" - }; - - switch (filesystem.properties.value) { - case "off": - filesystem.property.value = "Off"; - break; - case "sa": - filesystem.property.value = "System Attribute"; - break; - default: - filesystem.property.value = "On"; - break; - } - - if (/^inherited/gi.test(filesystem.properties.source)) { - filesystem.property.source = "inherited"; - filesystem.property.valueinherited = "Inherited (" + filesystem.property.value + ")"; - - $("#dropdown-" + modal.name + "-xattr-" + modal.id + " li[value='Inherited']").removeClass("hidden"); - $("#dropdown-" + modal.name + "-xattr-" + modal.id + " li[value='Inherited'] a").text(filesystem.property.valueinherited); - } else if (/^default|^local/gi.test(filesystem.properties.source)) { - $("#dropdown-" + modal.name + "-xattr-" + modal.id + " li[value='InheritedReset']").removeClass("hidden"); - - if (/^default/gi.test(filesystem.properties.source)) { - filesystem.property.source = "default"; - filesystem.property.valueinherited = "Default (On)"; - - $("#dropdown-" + modal.name + "-xattr-" + modal.id + " li[value='InheritedReset'] a").text(filesystem.property.valueinherited); - } else if (/^local/gi.test(filesystem.properties.source) && filesystem.name == pool.name) { - filesystem.property.source = "local"; - - $("#dropdown-" + modal.name + "-xattr-" + modal.id + " li[value='InheritedReset'] a").text("Default (On)"); - } else if (/^local/gi.test(filesystem.properties.source) && filesystem.name != pool.name) { - filesystem.property.source = "local"; - - FnFileSystemConfigurationInheritedPropertyGet({ name: pool.name, id: pool.id }, { name: filesystem.name, id: filesystem.id, property: "xattr" }, { name: modal.name, id: modal.id }); - } - } - - $("#btnspan-" + modal.name + "-xattr-" + modal.id).text((filesystem.property.valueinherited ? filesystem.property.valueinherited : filesystem.property.value)).attr("data-field-value", filesystem.properties.valueraw).attr("data-field-source", filesystem.property.source); - $("#dropdown-" + modal.name + "-xattr-" + modal.id + " li").siblings().removeClass("active"); - $("#dropdown-" + modal.name + "-xattr-" + modal.id + " li[value='" + (filesystem.property.valueinherited ? (filesystem.property.source == "inherited" ? "Inherited" : "InheritedReset") : filesystem.properties.valueraw) + "']").addClass("active"); - - if (filesystem.readonly && zfsmanager.configuration.zfs.filesystem.readonlylockdown || pool.readonly) { - $("#div-" + modal.name + "-xattr-dropdown-" + modal.id + " button").prop("disabled", true); - } - break; - } - }); - - if (filesystem.context && filesystem.fscontext && filesystem.defcontext && filesystem.rootcontext) { - if (!$("#switch-" + modal.name + "-selinux-" + modal.id + " input").prop("checked")) { - $("#switch-" + modal.name + "-selinux-" + modal.id + " input").click(); - } - - $("#switch-" + modal.name + "-selinux-" + modal.id).attr("data-field-value", "true"); - } else { - $("#switch-" + modal.name + "-selinux-" + modal.id).attr("data-field-value", "false"); - } - - if (filesystem.readonly && zfsmanager.configuration.zfs.filesystem.readonlylockdown || pool.readonly) { - $("#switch-" + modal.name + "-selinux-" + modal.id + " input").prop("disabled", true); - } - if (pool.readonly) { - $("#btn-" + modal.name + "-apply-" + modal.id).prop("disabled", true); - } - - FnConsole.log[1]("File Systems, Configuration, Get: Success, Pool: " + pool.name + ", File System: " + filesystem.name); - }) - .fail(function (message, data) { - FnConsole.warn("File Systems, Configuration, Get: Failed, Pool: " + pool.name + ", File System: " + filesystem.name + " , Message: " + (data ? data : message)); - }); -} - -function FnFileSystemConfigurationInheritedGet(pool = { name, id }, filesystem = { name }, modal = { name, id }) { - let process = { - command: ["/sbin/zfs", "get", "atime,casesensitivity,compression,dedup,dnodesize,encryption,recordsize,special_small_blocks,xattr", "-H", "-o", "property,value,source", "-p", filesystem.name] - }; - - FnConsole.log[2]("File Systems, Configuration, Inherited, Get: In Progress, Pool: " + pool.name + ", File System: " + filesystem.name); - FnConsole.log[3](FnConsoleCommand({ command: process.command })); - - return cockpit.spawn(process.command, { err: "out" }) - .done(function (data) { - FnConsole.log[4](FnConsoleVerbose({ data: data, message: "File Systems, Configuration, Inherited, Get:" })); - - process.data = data.replace(/\t+/g, "\u22C5").split(/\n/g).filter(v => v); - - process.data.forEach((_value, _index) => { - _value = _value.split("\u22C5"); - - filesystem.properties = { - property: _value[0].toLowerCase(), - value: _value[1].toLowerCase(), - valueraw: _value[1], - source: _value[2] - }; - - switch (filesystem.properties.property) { - case "atime": //Default is on - filesystem.property = { - value: "On", - valueinherited: "" - }; - - switch (filesystem.properties.value) { - case "on": - filesystem.property.value = "On"; - break; - case "gzip": - filesystem.property.value = "GZIP"; - break; - case "lz4": - filesystem.property.value = "LZ4"; - break; - case "lzjb": - filesystem.property.value = "LZJB"; - break; - case "zle": - filesystem.property.value = "ZLE"; - break; - default: - filesystem.property.value = "Off"; - break; - } - - filesystem.property.valueinherited = "Inherited (" + filesystem.property.value + ")"; - - $("#btnspan-" + modal.name + "-atime-" + modal.id).text(filesystem.property.valueinherited).attr("data-field-value", "Inherited"); - $("#dropdown-" + modal.name + "-atime-" + modal.id + " li").siblings().removeClass("active"); - $("#dropdown-" + modal.name + "-atime-" + modal.id + " li[value='Inherited']").removeClass("hidden"); - $("#dropdown-" + modal.name + "-atime-" + modal.id + " li[value='Inherited'] a").text(filesystem.property.valueinherited); - $("#dropdown-" + modal.name + "-atime-" + modal.id + " li[value='Inherited']").addClass("active"); - break; case "casesensitivity": //Default is sensitive - filesystem.property = { - value: "Sensitive", - valueinherited: "" - }; - - switch (filesystem.properties.value) { - case "insensitive": - filesystem.property.value = "Insensitive"; - break; - case "mixed": - filesystem.property.value = "Mixed"; - break; - case "sensitive": - filesystem.property.value = "Sensitive"; - break; - default: - filesystem.property.value = "Sensitive"; - break; - } - - filesystem.property.valueinherited = "Inherited (" + filesystem.property.value + ")"; - - $("#btnspan-" + modal.name + "-casesensitivity-" + modal.id).text(filesystem.property.valueinherited).attr("data-field-value", "Inherited"); - $("#dropdown-" + modal.name + "-casesensitivity-" + modal.id + " li").siblings().removeClass("active"); - $("#dropdown-" + modal.name + "-casesensitivity-" + modal.id + " li[value='Inherited']").removeClass("hidden"); - $("#dropdown-" + modal.name + "-casesensitivity-" + modal.id + " li[value='Inherited'] a").text(filesystem.property.valueinherited); - $("#dropdown-" + modal.name + "-casesensitivity-" + modal.id + " li[value='Inherited']").addClass("active"); - break; - case "compression": //Default is off - filesystem.property = { - value: "Off", - valueinherited: "" - }; - - switch (filesystem.properties.value) { - case "on": - filesystem.property.value = "On"; - break; - case "gzip": - filesystem.property.value = "GZIP"; - break; - case "lz4": - filesystem.property.value = "LZ4"; - break; - case "lzjb": - filesystem.property.value = "LZJB"; - break; - case "zle": - filesystem.property.value = "ZLE"; - break; - default: - filesystem.property.value = "Off"; - break; - } - - filesystem.property.valueinherited = "Inherited (" + filesystem.property.value + ")"; - - $("#btnspan-" + modal.name + "-compression-" + modal.id).text(filesystem.property.valueinherited).attr("data-field-value", "Inherited"); - $("#dropdown-" + modal.name + "-compression-" + modal.id + " li").siblings().removeClass("active"); - $("#dropdown-" + modal.name + "-compression-" + modal.id + " li[value='Inherited']").removeClass("hidden"); - $("#dropdown-" + modal.name + "-compression-" + modal.id + " li[value='Inherited'] a").text(filesystem.property.valueinherited); - $("#dropdown-" + modal.name + "-compression-" + modal.id + " li[value='Inherited']").addClass("active"); - break; - case "dedup": //Default is off - filesystem.property = { - value: "Off", - valueinherited: "" - }; - - switch (filesystem.properties.value) { - case "on": - filesystem.property.value = "On"; - break; - case "off": - filesystem.property.value = "Off"; - break; - case "verify": - filesystem.property.value = "Verify"; - break; - case "sha256": - filesystem.property.value = "SHA-256"; - break; - case "sha256,verify": - filesystem.property.value = "SHA-256 + Verify"; - break; - case "sha512": - filesystem.property.value = "SHA-512"; - break; - case "sha512,verify": - filesystem.property.value = "SHA-512 + Verify"; - break; - case "skein": - filesystem.property.value = "Skein"; - break; - case "skein,verify": - filesystem.property.value = "Skein + Verify"; - break; - case "edonr,verify": - filesystem.property.value = "Edon-R + Verify"; - break; - default: - filesystem.property.value = "Off"; - break; - } - - filesystem.property.valueinherited = "Inherited (" + filesystem.property.value + ")"; - - $("#btnspan-" + modal.name + "-dedup-" + modal.id).text(filesystem.property.valueinherited).attr("data-field-value", "Inherited"); - $("#dropdown-" + modal.name + "-dedup-" + modal.id + " li").siblings().removeClass("active"); - $("#dropdown-" + modal.name + "-dedup-" + modal.id + " li[value='Inherited']").removeClass("hidden"); - $("#dropdown-" + modal.name + "-dedup-" + modal.id + " li[value='Inherited'] a").text(filesystem.property.valueinherited); - $("#dropdown-" + modal.name + "-dedup-" + modal.id + " li[value='Inherited']").addClass("active"); - break; - case "dnodesize": //Default is legacy - filesystem.property = { - value: "Off", - valueinherited: "" - }; - - switch (filesystem.properties.value) { - case "1k": - filesystem.property.value = "1 KiB"; - break; - case "2k": - filesystem.property.value = "2 KiB"; - break; - case "4k": - filesystem.property.value = "4 KiB"; - break; - case "8k": - filesystem.property.value = "8 KiB"; - break; - case "16k": - filesystem.property.value = "16 KiB"; - break; - case "auto": - filesystem.property.value = "Auto"; - break; - case "legacy": - filesystem.property.value = "Legacy"; - break; - default: - filesystem.property.value = "Legacy"; - break; - } - - filesystem.property.valueinherited = "Inherited (" + filesystem.property.value + ")"; - - $("#btnspan-" + modal.name + "-dnodesize-" + modal.id).text(filesystem.property.valueinherited).attr("data-field-value", "Inherited"); - $("#dropdown-" + modal.name + "-dnodesize-" + modal.id + " li").siblings().removeClass("active"); - $("#dropdown-" + modal.name + "-dnodesize-" + modal.id + " li[value='Inherited']").removeClass("hidden"); - $("#dropdown-" + modal.name + "-dnodesize-" + modal.id + " li[value='Inherited'] a").text(filesystem.property.valueinherited); - $("#dropdown-" + modal.name + "-dnodesize-" + modal.id + " li[value='Inherited']").addClass("active"); - break; - case "encryption": //Default is off - filesystem.property = { - value: "Off", - valueinherited: "" - }; - - switch (filesystem.properties.value) { - case "on": - filesystem.property.value = "On"; - break; - case "off": - filesystem.property.value = "Off"; - break; - case "aes-128-ccm": - filesystem.property.value = "AES-128-CCM"; - break; - case "aes-192-ccm": - filesystem.property.value = "AES-192-CCM"; - break; - case "aes-256-ccm": - filesystem.property.value = "AES-256-CCM"; - break; - case "aes-128-gcm": - filesystem.property.value = "AES-128-GCM"; - break; - case "aes-192-gcm": - filesystem.property.value = "AES-192-GCM"; - break; - case "aes-256-gcm": - filesystem.property.value = "AES-256-GCM"; - break; - } - - filesystem.property.valueinherited = "Inherited (" + filesystem.property.value + ")"; - - if (filesystem.properties.value != "off") { - if (!$("#switch-" + modal.name + "-encryption-" + modal.id + " input").prop("checked")) { - $("#switch-" + modal.name + "-encryption-" + modal.id + " input").click(); - } - - $("#switch-" + modal.name + "-encryption-" + modal.id + " input").prop("disabled", true); - $("#btnspan-" + modal.name + "-encryption-cipher-" + modal.id).text(filesystem.property.valueinherited).attr("data-field-value", "Inherited"); - $("#dropdown-" + modal.name + "-encryption-cipher-" + modal.id + " li").siblings().removeClass("active"); - $("#dropdown-" + modal.name + "-encryption-cipher-" + modal.id + " li[value='Inherited']").removeClass("hidden"); - $("#dropdown-" + modal.name + "-encryption-cipher-" + modal.id + " li[value='Inherited'] a").text(filesystem.property.valueinherited); - $("#dropdown-" + modal.name + "-encryption-cipher-" + modal.id + " li[value='Inherited']").addClass("active"); - $("#helpblock-" + modal.name + "-encryption-passphrase-" + modal.id).removeClass("has-error").removeClass("hidden").text("Passphrase is not required."); - } else if (filesystem.properties.value == "off") { - $("#switch-" + modal.name + "-encryption-" + modal.id + " input").prop("disabled", false); - - if ($("#switch-" + modal.name + "-encryption-" + modal.id + " input").prop("checked")) { - $("#switch-" + modal.name + "-encryption-" + modal.id + " input").click(); - } - - $("#btnspan-" + modal.name + "-encryption-cipher-" + modal.id).text("AES-256-GCM").attr("data-field-value", "aes-256-gcm"); - $("#dropdown-" + modal.name + "-encryption-cipher-" + modal.id + " li").siblings().removeClass("active"); - $("#dropdown-" + modal.name + "-encryption-cipher-" + modal.id + " li[value='aes-256-gcm']").addClass("active"); - $("#dropdown-" + modal.name + "-encryption-cipher-" + modal.id + " li[value='Inherited']").addClass("hidden"); - $("#dropdown-" + modal.name + "-encryption-cipher-" + modal.id + " li[value='Inherited'] a").text("Inherited"); - - if ($("#input-" + modal.name + "-encryption-passphrase-" + modal.id).val().length == 0) { - $("#validationwrapper-" + modal.name + "-encryption-passphrase-" + modal.id).removeClass("has-error"); - $("#helpblock-" + modal.name + "-encryption-passphrase-" + modal.id).removeClass("has-error").addClass("hidden").text(""); - $("#validationwrapper-" + modal.name + "-encryption-passphrase-confirm-" + modal.id).removeClass("has-error"); - $("#helpblock-" + modal.name + "-encryption-passphrase-" + modal.id).removeClass("has-error").addClass("hidden").text(""); - } - } - break; - case "recordsize": //Default is 128K - filesystem.property = { - value: FnFormatBytes({ base2: true, decimals: 0, value: filesystem.properties.value }), - valueinherited: "" - }; - - filesystem.property.valueinherited = "Inherited (" + filesystem.property.value + ")"; - - $("#btnspan-" + modal.name + "-recordsize-" + modal.id).text(filesystem.property.valueinherited).attr("data-field-value", "Inherited"); - $("#dropdown-" + modal.name + "-recordsize-" + modal.id + " li").siblings().removeClass("active"); - $("#dropdown-" + modal.name + "-recordsize-" + modal.id + " li[value='Inherited']").removeClass("hidden"); - $("#dropdown-" + modal.name + "-recordsize-" + modal.id + " li[value='Inherited'] a").text(filesystem.property.valueinherited); - $("#dropdown-" + modal.name + "-recordsize-" + modal.id + " li[value='Inherited']").addClass("active"); - break; - case "special_small_blocks": //Default is 0 - filesystem.property = { - value: FnFormatBytes({ base2: true, decimals: 0, value: filesystem.properties.value }), - valueinherited: "" - }; - - filesystem.property.valueinherited = "Inherited (" + filesystem.property.value + ")"; - - $("#btnspan-" + modal.name + "-special_small_blocks-" + modal.id).text(filesystem.property.valueinherited).attr("data-field-value", "Inherited"); - $("#dropdown-" + modal.name + "-special_small_blocks-" + modal.id + " li").siblings().removeClass("active"); - $("#dropdown-" + modal.name + "-special_small_blocks-" + modal.id + " li[value='Inherited']").removeClass("hidden"); - $("#dropdown-" + modal.name + "-special_small_blocks-" + modal.id + " li[value='Inherited'] a").text(filesystem.property.valueinherited); - $("#dropdown-" + modal.name + "-special_small_blocks-" + modal.id + " li[value='Inherited']").addClass("active"); - break; - case "xattr": //Default is on - filesystem.property = { - value: "On", - valueinherited: "" - }; - - switch (filesystem.properties.value) { - case "on": - filesystem.property.value = "On"; - break; - case "off": - filesystem.property.value = "Off"; - break; - case "sa": - filesystem.property.value = "System Attribute"; - break; - default: - filesystem.property.value = "On"; - break; - } - - filesystem.property.valueinherited = "Inherited (" + filesystem.property.value + ")"; - - $("#btnspan-" + modal.name + "-xattr-" + modal.id).text(filesystem.property.valueinherited).attr("data-field-value", "Inherited"); - $("#dropdown-" + modal.name + "-xattr-" + modal.id + " li").siblings().removeClass("active"); - $("#dropdown-" + modal.name + "-xattr-" + modal.id + " li[value='Inherited']").removeClass("hidden"); - $("#dropdown-" + modal.name + "-xattr-" + modal.id + " li[value='Inherited'] a").text(filesystem.property.valueinherited); - $("#dropdown-" + modal.name + "-xattr-" + modal.id + " li[value='Inherited']").addClass("active"); - break; - } - }); - - //Quota - let size = { - quota: { - max: { - raw: 1099511627776000, - unit: "", - unitnumber: 0 - }, - slider: { - valuemax: 1000 - }, - property: { - value: "0 B", - valueraw: "0", - valueunit: "KiB" - } - } - }; - - FnStoragePoolSizeGet({ name: pool.name, id: null }) - .done(function (_data) { - FnConsole.log[4](FnConsoleVerbose({ data: _data, message: "Storage Pools, Size, Get:" })); - - if (_data && zfsmanager.configuration.zfs.filesystem.quotarestrict) { - size.quota.max.raw = parseInt(_data.replace(/\n+/g, "")); - } - }) - .finally(function () { - size.quota.max.unitnumber = FnFormatBytes({ base2: true, decimals: 2, value: size.quota.max.raw }).replace(/ .*$/g, ""); - size.quota.max.unit = FnFormatBytes({ base2: true, decimals: 2, value: size.quota.max.raw }).replace(/ /g, "").replace(/^[0-9.]/, ""); - - if (size.quota.max.raw <= 1024000) { - $("#input-" + modal.name + "-quota-" + modal.id).attr("data-filesystem-quota-max-kib", size.quota.max.unitnumber); - } - if (size.quota.max.raw > 1024000) { - $("#dropdown-" + modal.name + "-quota-" + modal.id + " li[value='MiB']").removeClass("hidden"); - - $("#input-" + modal.name + "-quota-" + modal.id).attr("data-filesystem-quota-max-kib", size.quota.slider.valuemax); - $("#input-" + modal.name + "-quota-" + modal.id).attr("data-filesystem-quota-max-mib", size.quota.max.unitnumber); - } - if (size.quota.max.raw > 1048576000) { - $("#dropdown-" + modal.name + "-quota-" + modal.id + " li[value='GiB']").removeClass("hidden"); - - $("#input-" + modal.name + "-quota-" + modal.id).attr("data-filesystem-quota-max-kib", size.quota.slider.valuemax); - $("#input-" + modal.name + "-quota-" + modal.id).attr("data-filesystem-quota-max-mib", size.quota.slider.valuemax); - $("#input-" + modal.name + "-quota-" + modal.id).attr("data-filesystem-quota-max-gib", size.quota.max.unitnumber); - } - if (size.quota.max.raw > 1073741824000) { - $("#dropdown-" + modal.name + "-quota-" + modal.id + " li[value='TiB']").removeClass("hidden"); - - $("#input-" + modal.name + "-quota-" + modal.id).attr("data-filesystem-quota-max-kib", size.quota.slider.valuemax); - $("#input-" + modal.name + "-quota-" + modal.id).attr("data-filesystem-quota-max-mib", size.quota.slider.valuemax); - $("#input-" + modal.name + "-quota-" + modal.id).attr("data-filesystem-quota-max-gib", size.quota.slider.valuemax); - $("#input-" + modal.name + "-quota-" + modal.id).attr("data-filesystem-quota-max-tib", size.quota.max.unitnumber); - } - - if (size.quota.property.valueunit == "KiB") { - size.quota.slider.valuemax = $("#input-" + modal.name + "-quota-" + modal.id).attr("data-filesystem-quota-max-kib"); - } - if (size.quota.property.valueunit == "MiB") { - size.quota.slider.valuemax = $("#input-" + modal.name + "-quota-" + modal.id).attr("data-filesystem-quota-max-mib"); - } - if (size.quota.property.valueunit == "GiB") { - size.quota.slider.valuemax = $("#input-" + modal.name + "-quota-" + modal.id).attr("data-filesystem-quota-max-gib"); - } - if (size.quota.property.valueunit == "TiB") { - size.quota.slider.valuemax = $("#input-" + modal.name + "-quota-" + modal.id).attr("data-filesystem-quota-max-tib"); - } - - $("#slider-" + modal.name + "-quota-" + modal.id).data("slider").options.max = size.quota.slider.valuemax; - $("#slider-" + modal.name + "-quota-" + modal.id).data("slider").options.step = (size.quota.slider.valuemax < 10 ? "0.1" : "1"); - $("#slider-" + modal.name + "-quota-" + modal.id).slider("setValue", size.quota.property.valueraw); - - $("#btnspan-" + modal.name + "-quota-" + modal.id).text(size.quota.property.valueunit).attr("data-field-value", size.quota.property.valueunit); - $("#dropdown-" + modal.name + "-quota-" + modal.id + " li").siblings().removeClass("active"); - $("#dropdown-" + modal.name + "-quota-" + modal.id + " li[value='" + size.quota.property.valueunit + "']").addClass("active"); - $("#input-" + modal.name + "-quota-" + modal.id).attr("data-field-value", size.quota.property.value.toString().replace(/ /g, "").replace(/iB$/g, "")); - }); - - FnConsole.log[1]("File Systems, Configuration, Inherited, Get: Success, Pool: " + pool.name + ", File System: " + filesystem.name); - }) - .fail(function (message, data) { - FnConsole.warn("File Systems, Configuration, Inherited, Get: Failed, Pool: " + pool.name + ", File System: " + filesystem.name + " , Message: " + (data ? data : message)); - }); -} - -function FnFileSystemConfigurationInheritedPropertyGet(pool = { name, id }, filesystem = { name, id, property }, modal = { name, id }) { - let process = { - command: ["/sbin/zfs", "get", filesystem.property, "-H", "-o", "value", "-p", "-d", "0", filesystem.name.replace(/\/[^\/]+$/, "")] - }; - - FnConsole.log[2]("File Systems, Configuration, Property, Inherited, Get: In Progress, Pool: " + pool.name + ", File System: " + filesystem.name); - FnConsole.log[3](FnConsoleCommand({ command: process.command })); - - return cockpit.spawn(process.command, { err: "out" }) - .done(function (data) { - FnConsole.log[4](FnConsoleVerbose({ data: data, message: "File Systems, Configuration, Property, Get:" })); - - filesystem.properties = { - value: data.trim() - }; - - switch (filesystem.properties.value) { - case "edonr": - filesystem.properties.value = "Edon-R"; - break; - case "edonr,verify": - filesystem.properties.value = "Edon-R + Verify"; - break; - case "gzip": - filesystem.properties.value = "GZIP"; - break; - case "lz4": - filesystem.properties.value = "LZ4"; - break; - case "lzjb": - filesystem.properties.value = "LZJB"; - break; - case "noacl": - filesystem.properties.value = "No ACL"; - break; - case "noallow": - filesystem.properties.value = "No Allow"; - break; - case "noparity": - filesystem.properties.value = "No Parity"; - break; - case "passthrough-x": - filesystem.properties.value = "Passthrough-X"; - break; - case "posixacl": - filesystem.properties.value = "POSIX ACL"; - break; - case "sa": - filesystem.properties.value = "System Attribute"; - break; - case "sha256": - filesystem.properties.value = "SHA-256"; - break; - case "sha256,verify": - filesystem.properties.value = "SHA-256 + Verify"; - break; - case "sha512": - filesystem.properties.value = "SHA-512"; - break; - case "sha512,verify": - filesystem.properties.value = "SHA-512 + Verify"; - break; - case "skein,verify": - filesystem.properties.value = "Skein + Verify"; - break; - case "zle": - filesystem.properties.value = "ZLE"; - break; - default: - filesystem.properties.value = ($.isNumeric(filesystem.properties.value) ? FnFormatBytes({ base2: true, decimals: 0, value: filesystem.properties.value }) : filesystem.properties.value.charAt(0).toUpperCase() + filesystem.properties.value.slice(1)); - } - - $("#dropdown-" + modal.name + "-" + filesystem.property + "-" + modal.id + " li[value='InheritedReset'] a").text("Inherited" + (filesystem.properties.value ? " (" + filesystem.properties.value + ")" : "")); - - FnConsole.log[2]("File Systems, Configuration, Property, Inherited, Get: Success, Pool: " + pool.name + ", File System: " + filesystem.name); - }) - .fail(function (message, data) { - $("#dropdown-" + modal.name + "-" + filesystem.property + "-" + modal.id + " li[value='InheritedReset'] a").text("Inherited"); - - FnConsole.warn("File Systems, Configuration, Property, Inherited, Get: Failed, Pool: " + pool.name + ", File System: " + filesystem.name + " , Message: " + (data ? data : message)); - }); -} - -function FnFileSystemConfigure(pool = { name, id, altroot: false, readonly: false }, filesystem = { name, id, aclinherit, acltype, atime, canmount, checksum, compression, context, dedup, dnodesize, defcontext, fscontext, mountpoint, quota, readonly, recordsize, refreservation, rootcontext, sharenfs, sharesmb, special_small_blocks, type, xattr }, samba = { restart: false }, modal = { id }) { - filesystem.properties = { - inherit: [], - new: [] - }; - - if (filesystem.aclinherit) { - if (/^Default|^Inherited/g.test(filesystem.aclinherit)) { - filesystem.properties.inherit.push("aclinherit"); - } else { - filesystem.properties.new.push("aclinherit=" + filesystem.aclinherit); - } - } - if (filesystem.acltype) { - if (/^Default|^Inherited/g.test(filesystem.acltype)) { - filesystem.properties.inherit.push("acltype"); - } else { - filesystem.properties.new.push("acltype=" + filesystem.acltype); - } - } - if (filesystem.atime) { - if (/^Default|^Inherited/g.test(filesystem.atime)) { - filesystem.properties.inherit.push("atime"); - } else { - filesystem.properties.new.push("atime=" + filesystem.atime); - } - } - if (filesystem.canmount) { - filesystem.properties.new.push("canmount=" + filesystem.canmount); - } - if (filesystem.checksum) { - if (/^Default|^Inherited/g.test(filesystem.checksum)) { - filesystem.properties.inherit.push("checksum"); - } else { - filesystem.properties.new.push("checksum=" + filesystem.checksum); - } - } - if (filesystem.compression) { - if (/^Default|^Inherited/g.test(filesystem.compression)) { - filesystem.properties.inherit.push("compression"); - } else { - filesystem.properties.new.push("compression=" + filesystem.compression); - } - } - if (filesystem.context) { - filesystem.properties.new.push("context=" + filesystem.context); - } - if (filesystem.dedup) { - if (/^Default|^Inherited/g.test(filesystem.dedup)) { - filesystem.properties.inherit.push("dedup"); - } else { - filesystem.properties.new.push("dedup=" + filesystem.dedup); - } - } - if (filesystem.dnodesize) { - if (/^Default|^Inherited/g.test(filesystem.dnodesize)) { - filesystem.properties.inherit.push("dnodesize"); - } else { - filesystem.properties.new.push("dnodesize=" + filesystem.dnodesize); - } - } - if (filesystem.defcontext) { - filesystem.properties.new.push("defcontext=" + filesystem.defcontext); - } - if (filesystem.fscontext) { - filesystem.properties.new.push("fscontext=" + filesystem.fscontext); - } - if (filesystem.mountpoint) { - filesystem.properties.new.push(`mountpoint="` + filesystem.mountpoint + `"`); - } - if (filesystem.quota) { - filesystem.properties.new.push(`quota="` + filesystem.quota + `"`); - } - if (filesystem.readonly) { - filesystem.properties.new.push("readonly=" + filesystem.readonly); - } - if (filesystem.recordsize) { - if (/^Default|^Inherited/g.test(filesystem.recordsize)) { - filesystem.properties.inherit.push("recordsize"); - } else { - filesystem.properties.new.push("recordsize=" + filesystem.recordsize); - } - } - if (filesystem.refreservation) { - filesystem.properties.new.push("refreservation=" + filesystem.refreservation); - } - if (filesystem.rootcontext) { - filesystem.properties.new.push("rootcontext=" + filesystem.rootcontext); - } - if (filesystem.sharenfs) { - filesystem.properties.new.push(`sharenfs="` + filesystem.sharenfs + `"`); - } - if (filesystem.sharesmb && !zfsmanager.configuration.samba.manage) { - filesystem.properties.new.push("sharesmb=" + filesystem.sharesmb); - } - if (filesystem.special_small_blocks) { - if (/^Default|^Inherited/g.test(filesystem.special_small_blocks)) { - filesystem.properties.inherit.push("special_small_blocks"); - } else { - filesystem.properties.new.push("special_small_blocks=" + filesystem.special_small_blocks); - } - } - if (filesystem.xattr) { - if (/^Default|^Inherited/g.test(filesystem.xattr)) { - filesystem.properties.inherit.push("xattr"); - } else { - filesystem.properties.new.push("xattr=" + filesystem.xattr); - } - } - - if (filesystem.properties.inherit.length > 0 && !pool.readonly) { - FnFileSystemConfigureInheritance({ name: pool.name, id: pool.id }, { name: filesystem.name, id: filesystem.id, properties: { inherit: filesystem.properties.inherit }, type: filesystem.type }) - .finally(function () { - if (filesystem.properties.new.length > 0 && !pool.readonly) { - FnFileSystemConfigureCommand({ name: pool.name, id: pool.id, altroot: pool.altroot }, { name: filesystem.name, id: filesystem.id, mountpoint: filesystem.mountpoint, properties: { new: filesystem.properties.new }, type: filesystem.type }, { restart: samba.restart }, { id: modal.id }); - } else { - modal.id.modal("hide"); - } - }); - } else if (filesystem.properties.new.length > 0 && !pool.readonly) { - FnFileSystemConfigureCommand({ name: pool.name, id: pool.id, altroot: pool.altroot }, { name: filesystem.name, id: filesystem.id, mountpoint: filesystem.mountpoint, properties: { new: filesystem.properties.new }, type: filesystem.type }, { restart: samba.restart }, { id: modal.id }); - } else { - modal.id.modal("hide"); - } -} - -function FnFileSystemConfigureCommand(pool = { name, id, altroot: false }, filesystem = { name, id, mountpoint, properties: { new: [] }, type }, samba = { restart: false }, modal = { id }) { - let process = { - command: ["/bin/sh", "-c", "pkexec /sbin/zfs set " + filesystem.properties.new.join(" ") + " " + `"` + filesystem.name + `"`] - }; - - modal.hide = true; - - FnConsole.log[2]("File Systems, Configure: In Progress, Pool: " + pool.name + ", File System: " + filesystem.name); - FnConsole.log[3](FnConsoleCommand({ command: process.command })); - - $("#spinner-storagepool-filesystem-configure-" + filesystem.id + " span").text("Configuring " + filesystem.type.toLowerCase() + "..."); - - return cockpit.spawn(process.command, { err: "out" }) - .done(function () { - FnDisplayAlert({ status: "success", title: "File System successfully configured", description: filesystem.name, breakword: false }, { name: "filesystem-configure", id: filesystem.id, timeout: 4 }); - - FnConsole.log[1]("File Systems, Configure: Success, Pool: " + pool.name + ", File System: " + filesystem.name); - - if (zfsmanager.configuration.samba.manage) { - if (filesystem.mountpoint) { - modal.hide = false; - - $("#spinner-storagepool-filesystem-configure-" + filesystem.id + " span").text("Updating Samba shares..."); - - FnSambaZfsShareConfigurationPathsSet({ name: pool.name, id: pool.id, altroot: pool.altroot }, { name: filesystem.name }, { restart: samba.restart }, display = { refresh: false, silent: true }) - .finally(function () { - modal.id.modal("hide"); - - setTimeout(function () { - FnStoragePoolRefresh({ name: pool.name, id: pool.id }, { storagepool: true, filesystems: true, snapshots: true, status: false }); - }, 200); - }); - } else if (samba.restart) { - FnSambaRestart(); - } - } else { - if (samba.restart) { - FnSambaRestart(); - } - } - }) - .fail(function (message, data) { - filesystem.configured = false; - - if (/size is greater than available space/gi.test(data)) { - modal.hide = false; - - $("#validationwrapper-storagepool-filesystem-configure-refreservation-" + filesystem.id).addClass("has-error"); - $("#helpblock-storagepool-filesystem-configure-refreservation-" + filesystem.id).addClass("has-error").removeClass("hidden").text("Refreservation can not be greater than available size."); - $("#input-storagepool-filesystem-configure-refreservation-" + filesystem.id).focus(); - } else if (/size is less than current used or reserved space/gi.test(data)) { - modal.hide = false; - - $("#validationwrapper-storagepool-filesystem-configure-quota-" + filesystem.id).addClass("has-error"); - $("#helpblock-storagepool-filesystem-configure-quota-" + filesystem.id).addClass("has-error").removeClass("hidden").text("Quota can not be less than used size."); - $("#input-storagepool-filesystem-configure-quota-" + filesystem.id).focus(); - } else if (/property may be set/gi.test(data)) { - filesystem.configured = true; - - FnDisplayAlert({ status: "warning", title: "File system configured with errors", description: filesystem.name, breakword: false }, { name: "filesystem-configure", id: filesystem.id, timeout: 4 }); - - FnConsole.warn("File Systems, Configure: Warning, Pool: " + pool.name + ", File System: " + filesystem.name + ", Message: " + (data ? data : message)); - } - - if (!filesystem.configured) { - if (modal.hide) { - FnDisplayAlert({ status: "danger", title: "File System could not be configured", description: filesystem.name, breakword: false }, { name: "filesystem-configure", id: filesystem.id, timeout: 4 }); - } - - FnConsole.warn("File Systems, Configure: Failed, Pool: " + pool.name + ", File System: " + filesystem.name + ", Message: " + (data ? data : message)); - } - - if (!modal.hide) { - $("#spinner-storagepool-filesystem-configure-" + filesystem.id).addClass("hidden"); - $("#spinner-storagepool-filesystem-configure-" + filesystem.id + " span").text(""); - $("#btn-storagepool-filesystem-configure-apply-" + filesystem.id).prop("disabled", false); - } - }) - .finally(function () { - if (modal.hide) { - modal.id.modal("hide"); - - setTimeout(function () { - FnStoragePoolRefresh({ name: pool.name, id: pool.id }, { storagepool: true, filesystems: true, snapshots: true, status: false }); - }, 200); - } - }); -} - -function FnFileSystemConfigureInheritance(pool = { name, id }, filesystem = { name, id, properties: { inherit: [] }, type }) { - let process = { - promise: cockpit.defer() - }; - let promise = Promise.resolve(); - - filesystem.properties.errorcount = 0; - - $("#spinner-storagepool-filesystem-configure-" + filesystem.id + " span").text("Configuring " + filesystem.type.toLowerCase() + " inheritance..."); - - filesystem.properties.inherit.forEach((_value, _index) => { - promise = promise.then(_ => new Promise(resolve => - setTimeout(function () { - process.command = ["pkexec", "/sbin/zfs", "inherit", _value, filesystem.name]; - - FnConsole.log[2]("File Systems, Configure, Inheritance: In Progress, Pool: " + pool.name + ", File System: " + filesystem.name); - FnConsole.log[2](FnConsoleCommand({ command: process.command })); - - cockpit.spawn(process.command, { err: "out" }) - .done(function () { - FnConsole.log[2]("File Systems, Configure, Inheritance: Success, Pool: " + pool.name + ", File System: " + filesystem.name); - - if (_index == (filesystem.properties.inherit.length - 1)) { - if (filesystem.properties.errorcount == 0) { - FnDisplayAlert({ status: "success", title: "File System inheritance successfully configured", description: filesystem.name, breakword: false }, { name: "filesystem-configure-inheritance", id: filesystem.id, timeout: 4 }); - } else { - FnDisplayAlert({ status: "danger", title: "File System inheritance could not be configured", description: filesystem.name, breakword: false }, { name: "filesystem-configure-inheritance", id: filesystem.id, timeout: 4 }); - } - - process.promise.resolve(); - } - }) - .fail(function (message, data) { - filesystem.properties.errorcount++; - - FnConsole.warn("File Systems, Configure, Inheritance: Failed, Pool: " + pool.name + ", File System: " + filesystem.name + ", Message: " + (data ? data : message)); - - if (_index == (filesystem.properties.inherit.length - 1)) { - FnDisplayAlert({ status: "danger", title: "File System inheritance could not be configured", description: filesystem.name, breakword: false }, { name: "filesystem-configure-inheritance", id: filesystem.id, timeout: 4 }); - - process.promise.resolve(); - } - }); - - resolve(); - }, 500) - )); - }); - - return process.promise.promise(); -} - -function FnFileSystemCreate(pool = { name, id, altroot: false }, filesystem = { name, id, atime, casesensitivity, cipher, compression, dedup, dnodesize, encryption, passphrase, quota, readonly, recordsize, selinux, sharenfs, sharesmb, special_small_blocks, xattr }) { - let process = { - command: [], - options: `-o normalization=formD -o sharenfs="` + filesystem.sharenfs + `" -o sharesmb=` + filesystem.sharesmb + ` -o utf8only=on` - }; - - if (filesystem.quota) { - process.options += " -o quota=" + filesystem.quota; - } - if (filesystem.readonly) { - process.options += " -o readonly=" + filesystem.readonly; - } - if (filesystem.selinux) { - process.options += " -o context=system_u:object_r:samba_share_t:s0 -o fscontext=system_u:object_r:samba_share_t:s0 -o defcontext=system_u:object_r:samba_share_t:s0 -o rootcontext=system_u:object_r:samba_share_t:s0"; - } - if (/^Inherited/g.test(filesystem.atime) == false) { - process.options += " -o atime=" + filesystem.atime; - } - if (/^Inherited/g.test(filesystem.casesensitivity) == false) { - process.options += " -o casesensitivity=" + filesystem.casesensitivity; - } - if (/^Inherited/g.test(filesystem.dedup) == false) { - process.options += " -o dedup=" + filesystem.dedup; - } - if (/^Inherited/g.test(filesystem.dnodesize) == false) { - process.options += " -o dnodesize=" + filesystem.dnodesize; - } - if (/^Inherited/g.test(filesystem.compression) == false) { - process.options += " -o compression=" + filesystem.compression; - } - if (/^Inherited/g.test(filesystem.recordsize) == false) { - process.options += " -o recordsize=" + filesystem.recordsize; - } - if (/^Inherited/g.test(filesystem.special_small_blocks) == false) { - process.options += " -o special_small_blocks=" + filesystem.special_small_blocks; - } - if (/^Inherited/g.test(filesystem.xattr) == false) { - process.options += " -o xattr=" + filesystem.xattr; - } - if (/^Inherited/g.test(filesystem.cipher) == false && filesystem.encryption) { - process.options += " -o encryption=" + filesystem.cipher; - } - - if (filesystem.encryption && filesystem.passphrase) { - process.options += " -o keyformat=passphrase -o keylocation=prompt"; - - if (filesystem.passphrase.length < 8) { - FnFileSystemCreateFail({ name: pool.name, id: pool.id, altroot: pool.altroot }, { name: filesystem.name, id: filesystem.id, sharesmb: filesystem.sharesmb }, { data: "Passphrase requires a minimum of 8 characters.", message: null }); - return; - } - - //Escape percentage and single quote special character for printf - if (/\%/g.test(filesystem.passphrase)) { - filesystem.passphrase = filesystem.passphrase.replace(/\%/g, "\%\%"); - } - if (/\'/g.test(filesystem.passphrase)) { - filesystem.passphrase = filesystem.passphrase.replace(/\'/g, "\'\"\'\"\'"); - } - - process.command = ["/bin/sh", "-c", "printf '" + filesystem.passphrase + "' | /sbin/zfs create " + process.options + ` "` + filesystem.name + `"`]; - } else { - process.command = ["/bin/sh", "-c", "pkexec /sbin/zfs create " + process.options + ` "` + filesystem.name + `"`]; - } - - FnConsole.log[1]("File Systems, Create: In Progress, Pool: " + pool.name + ", File System: " + filesystem.name); - FnConsole.log[2](FnConsoleCommand({ command: process.command })); - - $("#spinner-storagepool-filesystems-create-" + pool.id + " span").text("Creating file system..."); - - return cockpit.spawn(process.command, { err: "out" }) - .done(function () { - FnDisplayAlert({ status: "success", title: "File System successfully created", description: filesystem.name, breakword: false }, { name: "filesystem-create", id: filesystem.id, timeout: 4 }); - - FnConsole.log[1]("File Systems, Create: Success, Pool: " + pool.name + ", File System: " + filesystem.name); - - if (filesystem.sharesmb == "on" && zfsmanager.configuration.samba.manage) { - $("#spinner-storagepool-filesystems-create-" + pool.id + " span").text("Enabling Samba share..."); - - FnSambaShareEnableMountpointGet({ name: pool.name, id: pool.id, altroot: pool.altroot, readonly: false }, { name: filesystem.name, id: filesystem.id, sharesmb: true }, { silent: false }); - } - - setTimeout(function () { - $("#modal-storagepool-filesystems-create-" + pool.id).modal("hide"); - - setTimeout(function () { - FnStoragePoolRefresh({ name: pool.name, id: pool.id }, { storagepool: true, filesystems: true, snapshots: true, status: false }); - }, 200); - }, (filesystem.sharesmb == "on" && zfsmanager.configuration.samba.manage ? 500 : 0)); - }) - .fail(function (message, data) { - FnFileSystemCreateFail({ name: pool.name, id: pool.id, altroot: pool.altroot }, { name: filesystem.name, id: filesystem.id, sharesmb: filesystem.sharesmb }, { data: data, message: message }); - }); -} - -function FnFileSystemCreateFail(pool = { name, id, altroot: false }, filesystem = { name, id, sharesmb }, process = { data, message }) { - let modal = { - hide: true - }; - - filesystem.created = false; - - if (/dataset already exists/gi.test(process.data)) { - modal.hide = false; - - $("#validationwrapper-storagepool-filesystems-create-name-" + pool.id).addClass("has-error"); - $("#helpblock-storagepool-filesystems-create-name-" + pool.id).addClass("has-error").removeClass("hidden").text("Name already exists."); - $("#input-storagepool-filesystems-create-name-" + pool.id).focus(); - } else if (/encryption root's key is not loaded or provided/gi.test(process.data)) { - modal.hide = false; - - $("#validationwrapper-storagepool-filesystems-create-encryption-passphrase-" + pool.id).addClass("has-error"); - $("#helpblock-storagepool-filesystems-create-encryption-passphrase-" + pool.id).addClass("has-error").removeClass("hidden").html("Parent file system is locked.
    Unlock parent file system or enter a passphrase to create an independent encryption root."); - $("#input-storagepool-filesystems-create-encryption-passphrase-" + pool.id).focus(); - } else if (/Passphrase requires a minimum of 8 characters./i.test(process.data)) { - modal.hide = false; - - $("#validationwrapper-storagepool-filesystems-create-encryption-passphrase-" + pool.id).addClass("has-error"); - $("#helpblock-storagepool-filesystems-create-encryption-passphrase-" + pool.id).addClass("has-error").removeClass("hidden").text("Passphrase requires a minimum of 8 characters."); - $("#input-storagepool-filesystems-create-encryption-passphrase-" + pool.id).focus(); - } else if (/filesystem successfully created/gi.test(process.data)) { - filesystem.created = true; - - FnDisplayAlert({ status: "warning", title: "File system created with errors", description: filesystem.name, breakword: false }, { name: "filesystem-create", id: filesystem.id, timeout: 4 }); - - FnConsole.warn("File Systems, Create: Warning, Pool: " + pool.name + ", File System: " + filesystem.name + ", Message: " + (process.data ? process.data : process.message)); - - if (filesystem.sharesmb == "on" && zfsmanager.configuration.samba.manage) { - $("#spinner-storagepool-filesystems-create-" + pool.id + " span").text("Enabling Samba share..."); - - FnSambaShareEnableMountpointGet({ name: pool.name, id: pool.id, altroot: pool.altroot, readonly: false }, { name: filesystem.name, id: filesystem.id, sharesmb: true }, { silent: false }); - } - } - - if (!modal.hide) { - $("#spinner-storagepool-filesystems-create-" + pool.id).addClass("hidden"); - $("#spinner-storagepool-filesystems-create-" + pool.id + " span").text(""); - $("#btn-storagepool-filesystems-create-apply-" + pool.id).prop("disabled", false); - } - - if (!filesystem.created) { - FnConsole.warn("File Systems, Create: Failed, Pool: " + pool.name + ", File System: " + filesystem.name + ", Message: " + (process.data ? process.data : process.message)); - } - - if (modal.hide) { - if (!filesystem.created) { - FnDisplayAlert({ status: "danger", title: "File System could not be created", description: filesystem.name, breakword: false }, { name: "filesystem-create", id: filesystem.id, timeout: 4 }); - } - - $("#modal-storagepool-filesystems-create-" + pool.id).modal("hide"); - - setTimeout(function () { - FnStoragePoolRefresh({ name: pool.name, id: pool.id }, { storagepool: true, filesystems: true, snapshots: true, status: false }); - }, 200); - } -} - -function FnFileSystemDestroy(pool = { name, id, altroot: false, readonly: false }, filesystem = { name, id, force: false, recursive: false, recursiveall: false, sharesmb: false, type }, samba = { restart: false }) { - if (samba.restart) { - FnSambaStop() - .finally(function () { - if ((filesystem.recursive || filesystem.recursiveall) && zfsmanager.configuration.samba.manage) { - $("#spinner-storagepool-filesystem-destroy-" + filesystem.id + " span").text("Retrieving Samba shares..."); - - FnSambaSharesGet({ name: pool.name, id: pool.id }, { name: filesystem.name, clones: [] }) - .done(function (data) { - FnConsole.log[4](FnConsoleVerbose({ data: data, message: "Samba, Shares, Get:" })); - - let filesystems = { - id: data.split(/\n/g).filter(v => v && /\ton$/i.test(v)) - }; - - $("#spinner-storagepool-filesystem-destroy-" + filesystem.id + " span").text("Destroying " + filesystem.type.toLowerCase() + "s..."); - - if (filesystems.id.length > 0) { - FnFileSystemDestroyCommand({ name: pool.name, id: pool.id }, { name: filesystem.name, id: filesystem.id, force: filesystem.force, recursive: filesystem.recursive, recursiveall: filesystem.recursiveall }, { refresh: false }) - .done(function () { - $("#spinner-storagepool-filesystem-destroy-" + filesystem.id + " span").text("Destroying Samba shares..."); - - FnSambaSharesDestroy({ name: pool.name, id: pool.id, altroot: pool.altroot, readonly: false }, { id: filesystems.id }, { restart: samba.restart }, { silent: true }) - .finally(function () { - $("#modal-storagepool-filesystem-destroy-" + filesystem.id).modal("hide"); - - setTimeout(function () { - FnStoragePoolRefresh({ name: pool.name, id: pool.id }, { storagepool: true, filesystems: true, snapshots: true, status: false }); - }, 200); - }); - }); - } else { - FnFileSystemDestroyCommand({ name: pool.name, id: pool.id }, { name: filesystem.name, id: filesystem.id, force: filesystem.force, recursive: filesystem.recursive, recursiveall: filesystem.recursiveall }, { refresh: true }) - } - }) - .fail(function (message, data) { - FnFileSystemDestroyFail({ name: pool.name, id: pool.id }, { name: filesystem.name, id: filesystem.id }, { data: data, message: message }, { refresh: true }); - FnSambaStart(); - }); - } else { - $("#spinner-storagepool-filesystem-destroy-" + filesystem.id + " span").text("Destroying " + filesystem.type.toLowerCase() + "..."); - - if (filesystem.sharesmb && zfsmanager.configuration.samba.manage) { - FnFileSystemDestroyCommand({ name: pool.name, id: pool.id }, { name: filesystem.name, id: filesystem.id, force: filesystem.force, recursive: filesystem.recursive, recursiveall: filesystem.recursiveall }, { refresh: false }) - .done(function () { - $("#spinner-storagepool-filesystem-destroy-" + filesystem.id + " span").text("Destroying Samba share..."); - - FnSambaShareDestroy({ name: pool.name, id: pool.id, altroot: pool.altroot, readonly: false }, { name: filesystem.name, id: filesystem.id }, { restart: samba.restart }, { silent: true }) - .finally(function () { - $("#modal-storagepool-filesystem-destroy-" + filesystem.id).modal("hide"); - - setTimeout(function () { - FnStoragePoolRefresh({ name: pool.name, id: pool.id }, { storagepool: true, filesystems: true, snapshots: true, status: false }); - }, 200); - }); - }); - } else { - FnFileSystemDestroyCommand({ name: pool.name, id: pool.id }, { name: filesystem.name, id: filesystem.id, force: filesystem.force, recursive: filesystem.recursive, recursiveall: filesystem.recursiveall }, { refresh: true }) - .finally(function () { - if (!filesystem.sharesmb || !zfsmanager.configuration.samba.manage) { - FnSambaStart(); - } - }); - } - } - }); - } else { - if ((filesystem.recursive || filesystem.recursiveall) && zfsmanager.configuration.samba.manage) { - $("#spinner-storagepool-filesystem-destroy-" + filesystem.id + " span").text("Retrieving Samba shares..."); - - FnSambaSharesGet({ name: pool.name, id: pool.id }, { name: filesystem.name, clones: [] }) - .done(function (data) { - FnConsole.log[4](FnConsoleVerbose({ data: data, message: "Samba, Shares, Get:" })); - - let filesystems = { - id: data.split(/\n/g).filter(v => v && /\ton$/i.test(v)) - }; - - $("#spinner-storagepool-filesystem-destroy-" + filesystem.id + " span").text("Destroying " + filesystem.type.toLowerCase() + "s..."); - - if (filesystems.id.length > 0) { - FnFileSystemDestroyCommand({ name: pool.name, id: pool.id }, { name: filesystem.name, id: filesystem.id, force: filesystem.force, recursive: filesystem.recursive, recursiveall: filesystem.recursiveall }, { refresh: false }) - .done(function () { - $("#spinner-storagepool-filesystem-destroy-" + filesystem.id + " span").text("Destroying Samba shares..."); - - FnSambaSharesDestroy({ name: pool.name, id: pool.id, altroot: pool.altroot, readonly: false }, { id: filesystems.id }, { restart: samba.restart }, { silent: true }) - .finally(function () { - $("#modal-storagepool-filesystem-destroy-" + filesystem.id).modal("hide"); - - setTimeout(function () { - FnStoragePoolRefresh({ name: pool.name, id: pool.id }, { storagepool: true, filesystems: true, snapshots: true, status: false }); - }, 200); - }); - }); - } else { - FnFileSystemDestroyCommand({ name: pool.name, id: pool.id }, { name: filesystem.name, id: filesystem.id, force: filesystem.force, recursive: filesystem.recursive, recursiveall: filesystem.recursiveall }, { refresh: true }) - } - }) - .fail(function (message, data) { - FnFileSystemDestroyFail({ name: pool.name, id: pool.id }, { name: filesystem.name, id: filesystem.id }, { data: data, message: message }, { refresh: true }); - }); - } else { - $("#spinner-storagepool-filesystem-destroy-" + filesystem.id + " span").text("Destroying " + filesystem.type.toLowerCase() + "..."); - - if (filesystem.sharesmb && zfsmanager.configuration.samba.manage) { - FnFileSystemDestroyCommand({ name: pool.name, id: pool.id }, { name: filesystem.name, id: filesystem.id, force: filesystem.force, recursive: filesystem.recursive, recursiveall: filesystem.recursiveall }, { refresh: false }) - .done(function () { - $("#spinner-storagepool-filesystem-destroy-" + filesystem.id + " span").text("Destroying Samba share..."); - - FnSambaShareDestroy({ name: pool.name, id: pool.id, altroot: pool.altroot, readonly: false }, { name: filesystem.name, id: filesystem.id }, { restart: samba.restart }, { silent: true }) - .finally(function () { - $("#modal-storagepool-filesystem-destroy-" + filesystem.id).modal("hide"); - - setTimeout(function () { - FnStoragePoolRefresh({ name: pool.name, id: pool.id }, { storagepool: true, filesystems: true, snapshots: true, status: false }); - }, 200); - }); - }); - } else { - FnFileSystemDestroyCommand({ name: pool.name, id: pool.id }, { name: filesystem.name, id: filesystem.id, force: filesystem.force, recursive: filesystem.recursive, recursiveall: filesystem.recursiveall }, { refresh: true }) - } - } - } -} - -function FnFileSystemDestroyCommand(pool = { name, id }, filesystem = { name, id, force: false, recursive: false, recursiveall: false }, display = { refresh: true }) { - let process = { - command: [((zfsmanager.user.admin || !zfsmanager.user.name) ? "pkexec" : ""), "/sbin/zfs", "destroy", filesystem.name] - }; - - if (filesystem.force) { - process.command.splice(3, 0, "-f"); - } - if (filesystem.recursive) { - process.command.splice(3, 0, "-r"); - } - if (filesystem.recursiveall) { - process.command.splice(3, 0, "-R"); - } - - FnConsole.log[1]("File Systems, Destroy: In Progress, Pool: " + pool.name + ", File System: " + filesystem.name); - FnConsole.log[3](FnConsoleCommand({ command: process.command })); - - return cockpit.spawn(process.command, { err: "out" }) - .done(function () { - FnDisplayAlert({ status: "success", title: "File System successfully destroyed", description: filesystem.name, breakword: false }, { name: "filesystem-destroy", id: filesystem.id, timeout: 4 }); - - FnConsole.log[1]("File Systems, Destroy: Success, Pool: " + pool.name + ", File System: " + filesystem.name); - }) - .fail(function (message, data) { - FnFileSystemDestroyFail({ name: pool.name, id: pool.id }, { name: filesystem.name, id: filesystem.id }, { data: data, message: message }, { refresh: false }); - - display.refresh = true; - }) - .finally(function () { - if (display.refresh) { - $("#modal-storagepool-filesystem-destroy-" + filesystem.id).modal("hide"); - - setTimeout(function () { - FnStoragePoolRefresh({ name: pool.name, id: pool.id }, { storagepool: true, filesystems: true, snapshots: true, status: false }); - }, 200); - } - }); -} - -function FnFileSystemDestroyFail(pool = { name, id }, filesystem = { name, id }, process = { data, message }, display = { refresh: true }) { - FnDisplayAlert({ status: "danger", title: "File System could not be destroyed", description: filesystem.name, breakword: false }, { name: "filesystem-destroy", id: filesystem.id, timeout: 4 }); - - FnConsole.warn("File Systems, Destroy: Failed, Pool: " + pool.name + ", File System: " + filesystem.name + ", Message: " + (process.data ? process.data : process.message)); - - if (display.refresh) { - $("#modal-storagepool-filesystem-destroy-" + filesystem.id).modal("hide"); - - setTimeout(function () { - FnStoragePoolRefresh({ name: pool.name, id: pool.id }, { storagepool: true, filesystems: true, snapshots: true, status: false }); - }, 200); - } -} - -function FnFileSystemLock(pool = { name, id }, filesystem = { name, id, type }, display = { refresh: true }) { - let process = { - command: ["/sbin/zfs", "unload-key", filesystem.name] - }; - - FnConsole.log[2]("File Systems, Lock: In Progress, Pool: " + pool.name + ", File System: " + filesystem.name); - FnConsole.log[3](FnConsoleCommand({ command: process.command })); - - $("#spinner-storagepool-filesystem-lock-" + filesystem.id + " span").text("Locking " + filesystem.type.toLowerCase() + "..."); - - return cockpit.spawn(process.command, { err: "out", superuser: "require" }) - .done(function () { - FnDisplayAlert({ status: "success", title: "File System successfully locked", description: filesystem.name, breakword: false }, { name: "filesystem-lock", id: filesystem.id, timeout: 4 }); - - FnConsole.log[1]("File Systems, Lock: Success, Pool: " + pool.name + ", File System: " + filesystem.name); - }) - .fail(function (message, data) { - FnDisplayAlert({ status: "danger", title: "File System could not be locked", description: filesystem.name, breakword: false }, { name: "filesystem-lock", id: filesystem.id, timeout: 4 }); - - FnConsole.warn("File Systems, Lock: Failed, Pool: " + pool.name + ", File System: " + filesystem.name + ", Message: " + (data ? data : message)); - }) - .finally(function () { - if (display.refresh) { - $("#modal-storagepool-filesystem-lock-" + filesystem.id).modal("hide"); - - setTimeout(function () { - FnStoragePoolRefresh({ name: pool.name, id: pool.id }, { storagepool: true, filesystems: true, snapshots: true, status: false }); - }, 200); - } - }); -} - -function FnFileSystemMount(pool = { name, id, altroot: false, readonly: false }, filesystem = { name, id, overlay: true, type }, samba = { enable: false }, display = { refresh: true }) { - let process = { - command: [((zfsmanager.user.admin || !zfsmanager.user.name) ? "pkexec" : ""), "/sbin/zfs", "mount", filesystem.name] - }; - - if (filesystem.overlay) { - process.command.splice(3, 0, "-O"); - } - - FnConsole.log[2]("File Systems, Mount: In Progress, Pool: " + pool.name + ", File System: " + filesystem.name); - FnConsole.log[3](FnConsoleCommand({ command: process.command })); - - $("#spinner-storagepool-filesystem-mount-" + filesystem.id + " span").text("Mounting " + filesystem.type.toLowerCase() + "..."); - - return cockpit.spawn(process.command, { err: "out" }) - .done(function () { - FnDisplayAlert({ status: "success", title: "File System successfully mounted", description: filesystem.name, breakword: false }, { name: "filesystem-mount", id: filesystem.id, timeout: 4 }); - - FnConsole.log[1]("File Systems, Mount: Success, Pool: " + pool.name + ", File System: " + filesystem.name); - - if (samba.enable) { - $("#spinner-storagepool-filesystem-mount-" + filesystem.id + " span").text("Enabling Samba share..."); - - if (zfsmanager.configuration.samba.manage) { - FnSambaShareEnableMountpointGet({ name: pool.name, id: pool.id, altroot: pool.altroot, readonly: pool.readonly }, { name: filesystem.name, id: filesystem.id, sharesmb: false }, { silent: false }); - } else { - FnFileSystemShareSmbEnable({ name: pool.name, id: pool.id }, { name: filesystem.name, id: filesystem.id }); - } - } - }) - .fail(function (message, data) { - if (/filesystem already mounted/gi.test(data)) { - FnDisplayAlert({ status: "warning", title: "File System was already mounted", description: filesystem.name, breakword: false }, { name: "filesystem-mount", id: filesystem.id, timeout: 4 }); - } else { - FnDisplayAlert({ status: "danger", title: "File System could not be mounted", description: filesystem.name, breakword: false }, { name: "filesystem-mount", id: filesystem.id, timeout: 4 }); - } - - FnConsole.warn("File Systems, Mount: Failed, Pool: " + pool.name + ", File System: " + filesystem.name + ", Message: " + (data ? data : message)); - }) - .finally(function () { - setTimeout(function () { - $("#modal-storagepool-filesystem-mount-" + filesystem.id).modal("hide"); - - if (display.refresh) { - setTimeout(function () { - FnStoragePoolRefresh({ name: pool.name, id: pool.id }, { storagepool: true, filesystems: true, snapshots: false, status: false }); - }, 200); - } - }, (samba.enable ? 500 : 0)); - }); -} - -function FnFileSystemMountpointGet(pool = { name, id }, filesystem = { name, id }) { - let process = { - command: ["/sbin/zfs", "get", "mountpoint", "-H", "-o", "value", filesystem.name] - }; - - FnConsole.log[2]("File Systems, Mountpoint, Get: In Progress, Pool: " + pool.name + ", File System: " + filesystem.name); - FnConsole.log[3](FnConsoleCommand({ command: process.command })); - - return cockpit.spawn(process.command, { err: "out" }) - .done(function () { - FnConsole.log[1]("File Systems, Mountpoint, Get: Success, Pool: " + pool.name + ", File System: " + filesystem.name); - }) - .fail(function (message, data) { - FnConsole.warn("File Systems, Mountpoint, Get: Failed, Pool: " + pool.name + ", File System: " + filesystem.name + ", Message: " + (data ? data : message)); - }); -} - -function FnFileSystemPromote(pool = { name, id }, filesystem = { name, id, type }) { - let process = { - command: ["/sbin/zfs", "promote", filesystem.name] - }; - - FnConsole.log[2]("File Systems, Promote: In Progress, Pool: " + pool.name + ", File System: " + filesystem.name); - FnConsole.log[3](FnConsoleCommand({ command: process.command })); - - $("#spinner-storagepool-filesystem-promote-" + filesystem.id + " span").text("Promoting " + filesystem.type.toLowerCase() + "..."); - - return cockpit.spawn(process.command, { err: "out", superuser: "require" }) - .done(function () { - FnDisplayAlert({ status: "success", title: "File System successfully promoted", description: filesystem.name, breakword: false }, { name: "filesystem-promote", id: filesystem.id, timeout: 4 }); - - FnConsole.log[1]("File Systems, Promote: Success, Pool: " + pool.name + ", File System: " + filesystem.name); - }) - .fail(function (message, data) { - FnDisplayAlert({ status: "danger", title: "File System could not be promoted", description: filesystem.name, breakword: false }, { name: "filesystem-promote", id: filesystem.id, timeout: 4 }); - - FnConsole.warn("File Systems, Promote: Failed, Pool: " + pool.name + ", File System: " + filesystem.name + ", Message: " + (data ? data : message)); - }) - .finally(function () { - $("#modal-storagepool-filesystem-promote-" + filesystem.id).modal("hide"); - - setTimeout(function () { - FnStoragePoolRefresh({ name: pool.name, id: pool.id }, { storagepool: true, filesystems: true, snapshots: true, status: false }); - }, 200); - }); -} - -function FnFileSystemRename(pool = { name, id, altroot: false }, filesystem = { name, id, createnonexistparents: false, force: false, namenew, parent, sharesmb: false, type }, samba = { restart: false }) { - if (samba.restart) { - FnSambaStop() - .finally(function () { - if (zfsmanager.configuration.samba.manage) { - $("#spinner-storagepool-filesystem-rename-" + filesystem.id + " span").text("Retrieving Samba shares..."); - - FnSambaSharesGet({ name: pool.name, id: pool.id }, { name: filesystem.name, clones: [] }) - .done(function (data) { - FnConsole.log[4](FnConsoleVerbose({ data: data, message: "Samba, Shares, Get:" })); - - let filesystems = { - id: data.split(/\n/g).filter(v => v && /\ton$/i.test(v)) - }; - - $("#spinner-storagepool-filesystem-rename-" + filesystem.id + " span").text("Renaming " + filesystem.type.toLowerCase() + "..."); - - if (filesystems.id.length > 0) { - FnFileSystemRenameCommand({ name: pool.name, id: pool.id }, { name: filesystem.name, id: filesystem.id, createnonexistparents: filesystem.createnonexistparents, force: filesystem.force, namenew: filesystem.namenew, parent: filesystem.parent }, { refresh: false }) - .done(function (data) { - FnConsole.log[4](FnConsoleVerbose({ data: data, message: "File Systems, Rename:" })); - - if (/dataset already exists/i.test(data) == false) { - $("#spinner-storagepool-filesystem-rename-" + filesystem.id + " span").text("Renaming Samba share" + (filesystems.id.length > 1 ? "s" : "") + "..."); - - FnSambaSharesRename({ name: pool.name, id: pool.id, altroot: pool.altroot, readonly: false }, filesystems = { id: filesystems.id, parent: { name: filesystem.name, namenew: filesystem.namenew } }, { restart: samba.restart }, { silent: false }) - .finally(function () { - if (filesystem.createnonexistparents) { - FnFileSystemShareSmbInheritedDisable({ name: pool.name, id: pool.id, altroot: pool.altroot }, { name: filesystem.parent }, { disable: true }) - .finally(function () { - $("#modal-storagepool-filesystem-rename-" + filesystem.id).modal("hide"); - - setTimeout(function () { - FnStoragePoolRefresh({ name: pool.name, id: pool.id }, { storagepool: true, filesystems: true, snapshots: true, status: false }); - }, 500); - }); - } else { - $("#modal-storagepool-filesystem-rename-" + filesystem.id).modal("hide"); - - setTimeout(function () { - FnStoragePoolRefresh({ name: pool.name, id: pool.id }, { storagepool: true, filesystems: true, snapshots: true, status: false }); - }, 500); - } - }); - - } - }); - } else { - FnFileSystemRenameCommand({ name: pool.name, id: pool.id }, { name: filesystem.name, id: filesystem.id, createnonexistparents: filesystem.createnonexistparents, force: filesystem.force, namenew: filesystem.namenew, parent: filesystem.parent }, { refresh: (filesystem.createnonexistparents ? false : true) }) - .done(function () { - if (filesystem.createnonexistparents) { - $("#spinner-storagepool-filesystem-rename-" + filesystem.id + " span").text("Disabling Samba share inheritance..."); - - FnFileSystemShareSmbInheritedDisable({ name: pool.name, id: pool.id, altroot: pool.altroot }, { name: filesystem.parent }, { disable: true }) - .finally(function () { - $("#modal-storagepool-filesystem-rename-" + filesystem.id).modal("hide"); - - setTimeout(function () { - FnStoragePoolRefresh({ name: pool.name, id: pool.id }, { storagepool: true, filesystems: true, snapshots: true, status: false }); - }, 500); - - FnSambaStart(); - }); - } else { - FnSambaStart(); - } - }) - .fail(function () { - FnSambaStart(); - }); - } - }) - .fail(function (message, data) { - FnFileSystemRenameFail({ name: pool.name, id: pool.id }, { name: filesystem.name, id: filesystem.id, createnonexistparents: filesystem.createnonexistparents, parent: filesystem.parent }, { data: data, message: message }, { refresh: true }); - FnSambaStart(); - }); - } else { - FnFileSystemRenameCommand({ name: pool.name, id: pool.id }, { name: filesystem.name, id: filesystem.id, createnonexistparents: filesystem.createnonexistparents, force: filesystem.force, namenew: filesystem.namenew, parent: filesystem.parent }, { refresh: true }) - .finally(function () { - FnSambaStart(); - }); - } - }); - } else { - if (zfsmanager.configuration.samba.manage) { - $("#spinner-storagepool-filesystem-rename-" + filesystem.id + " span").text("Retrieving Samba shares..."); - - FnSambaSharesGet({ name: pool.name, id: pool.id }, { name: filesystem.name, clones: [] }) - .done(function (data) { - FnConsole.log[4](FnConsoleVerbose({ data: data, message: "Samba, Shares, Get:" })); - - let filesystems = { - id: data.split(/\n/g).filter(v => v && /\ton$/i.test(v)) - }; - - $("#spinner-storagepool-filesystem-rename-" + filesystem.id + " span").text("Renaming " + filesystem.type.toLowerCase() + "..."); - - if (filesystems.id.length > 0) { - FnFileSystemRenameCommand({ name: pool.name, id: pool.id }, { name: filesystem.name, id: filesystem.id, createnonexistparents: filesystem.createnonexistparents, force: filesystem.force, namenew: filesystem.namenew, parent: filesystem.parent }, { refresh: false }) - .done(function (data) { - FnConsole.log[4](FnConsoleVerbose({ data: data, message: "File Systems, Rename:" })); - - if (/dataset already exists/i.test(data) == false) { - $("#spinner-storagepool-filesystem-rename-" + filesystem.id + " span").text("Renaming Samba share" + (filesystems.id.length > 1 ? "s" : "") + "..."); - - FnSambaSharesRename({ name: pool.name, id: pool.id, altroot: pool.altroot, readonly: false }, filesystems = { id: filesystems.id, parent: { name: filesystem.name, namenew: filesystem.namenew } }, { restart: samba.restart }, { silent: false }) - .finally(function () { - if (filesystem.createnonexistparents) { - FnFileSystemShareSmbInheritedDisable({ name: pool.name, id: pool.id, altroot: pool.altroot }, { name: filesystem.parent }, { disable: true }) - .finally(function () { - $("#modal-storagepool-filesystem-rename-" + filesystem.id).modal("hide"); - - setTimeout(function () { - FnStoragePoolRefresh({ name: pool.name, id: pool.id }, { storagepool: true, filesystems: true, snapshots: true, status: false }); - }, 500); - }); - } else { - $("#modal-storagepool-filesystem-rename-" + filesystem.id).modal("hide"); - - setTimeout(function () { - FnStoragePoolRefresh({ name: pool.name, id: pool.id }, { storagepool: true, filesystems: true, snapshots: true, status: false }); - }, 500); - } - }); - } - }); - } else { - FnFileSystemRenameCommand({ name: pool.name, id: pool.id }, { name: filesystem.name, id: filesystem.id, createnonexistparents: filesystem.createnonexistparents, force: filesystem.force, namenew: filesystem.namenew, parent: filesystem.parent }, { refresh: (filesystem.createnonexistparents ? false : true) }) - .done(function () { - if (filesystem.createnonexistparents) { - $("#spinner-storagepool-filesystem-rename-" + filesystem.id + " span").text("Disabling Samba share inheritance..."); - - FnFileSystemShareSmbInheritedDisable({ name: pool.name, id: pool.id, altroot: pool.altroot }, { name: filesystem.parent }, { disable: true }) - .finally(function () { - $("#modal-storagepool-filesystem-rename-" + filesystem.id).modal("hide"); - - setTimeout(function () { - FnStoragePoolRefresh({ name: pool.name, id: pool.id }, { storagepool: true, filesystems: true, snapshots: true, status: false }); - }, 500); - }); - } - }); - } - }) - .fail(function (message, data) { - FnFileSystemRenameFail({ name: pool.name, id: pool.id }, { name: filesystem.name, id: filesystem.id, createnonexistparents: filesystem.createnonexistparents, parent: filesystem.parent }, { data: data, message: message }, { refresh: true }); - }); - } else { - FnFileSystemRenameCommand({ name: pool.name, id: pool.id }, { name: filesystem.name, id: filesystem.id, createnonexistparents: filesystem.createnonexistparents, force: filesystem.force, namenew: filesystem.namenew, parent: filesystem.parent }, { refresh: true }); - } - } -} - -function FnFileSystemRenameCommand(pool = { name, id }, filesystem = { name, id, createnonexistparents: false, force: false, namenew, parent }, display = { refresh: true }) { - let process = { - command: [((zfsmanager.user.admin || !zfsmanager.user.name) ? "pkexec" : ""), "/sbin/zfs", "rename", filesystem.name, filesystem.namenew] - }; - - if (filesystem.force) { - process.command.splice(3, 0, "-f"); - } - if (filesystem.createnonexistparents) { - process.command.splice(3, 0, "-p"); - } - - FnConsole.log[1]("File Systems, Rename: In Progress, Pool: " + pool.name + ", File System: " + filesystem.name); - FnConsole.log[3](FnConsoleCommand({ command: process.command })); - - return cockpit.spawn(process.command, { err: "out" }) - .done(function (data, message) { - FnConsole.log[4](FnConsoleVerbose({ data: data, message: "File Systems, Rename:" })); - - if (/dataset already exists/i.test(data)) { - FnFileSystemRenameFail({ name: pool.name, id: pool.id }, { name: filesystem.name, id: filesystem.id, createnonexistparents: filesystem.createnonexistparents, parent: filesystem.parent }, { data: data, message: message }, { refresh: true }); - return; - } - - FnDisplayAlert({ status: "success", title: "File System successfully renamed", description: filesystem.name, breakword: false }, { name: "filesystem-rename", id: filesystem.id, timeout: 4 }); - - FnConsole.log[1]("File Systems, Rename: Success, Pool: " + pool.name + ", File System: " + filesystem.name); - - if (display.refresh) { - $("#modal-storagepool-filesystem-rename-" + filesystem.id).modal("hide"); - - setTimeout(function () { - FnStoragePoolRefresh({ name: pool.name, id: pool.id }, { storagepool: true, filesystems: true, snapshots: true, status: false }); - }, 500); - } - }) - .fail(function (message, data) { - FnFileSystemRenameFail({ name: pool.name, id: pool.id }, { name: filesystem.name, id: filesystem.id, createnonexistparents: filesystem.createnonexistparents, parent: filesystem.parent }, { data: data, message: message }, { refresh: true }); - }); -} - -function FnFileSystemRenameFail(pool = { name, id }, filesystem = { name, id, createnonexistparents: false, parent }, process = { data, message }, display = { refresh: true }) { - let modal = { - hide: true - }; - - if (/dataset already exists/i.test(process.data)) { - modal.hide = false; - - $("#validationwrapper-storagepool-filesystem-rename-name-" + filesystem.id).addClass("has-error"); - $("#helpblock-storagepool-filesystem-rename-name-" + filesystem.id).addClass("has-error").removeClass("hidden").text("Name already exists."); - $("#input-storagepool-filesystem-rename-name-" + filesystem.id).focus(); - } else if (/parent does not exist/i.test(process.data)) { - modal.hide = false; - - $("#validationwrapper-storagepool-filesystem-rename-name-" + filesystem.id).addClass("has-error"); - $("#helpblock-storagepool-filesystem-rename-name-" + filesystem.id).addClass("has-error").removeClass("hidden").text("Parent file system does not exist."); - $("#input-storagepool-filesystem-rename-name-" + filesystem.id).focus(); - } - - if (!modal.hide) { - $("#spinner-storagepool-filesystem-rename-" + filesystem.id).addClass("hidden"); - $("#spinner-storagepool-filesystem-rename-" + filesystem.id + " span").text(""); - $("#btn-storagepool-filesystem-rename-apply-" + filesystem.id).prop("disabled", false); - } - - FnConsole.warn("File Systems, Rename: Failed, Pool: " + pool.name + ", File System: " + filesystem.name + ", Message: " + (process.data ? process.data : process.message)); - - if (modal.hide) { - FnDisplayAlert({ status: "danger", title: "File System could not be renamed", description: filesystem.name, breakword: false }, { name: "filesystem-rename", id: filesystem.id, timeout: 4 }); - - $("#modal-storagepool-filesystem-rename-" + filesystem.id).modal("hide"); - - if (display.refresh) { - setTimeout(function () { - FnStoragePoolRefresh({ name: pool.name, id: pool.id }, { storagepool: true, filesystems: true, snapshots: true, status: false }); - }, 200); - } - } -} - -function FnFileSystemSelinuxContextsSambaSet(pool = { name, id }, filesystem = { name }) { - let process = { - command: ["/sbin/zfs", "set", "context=system_u:object_r:samba_share_t:s0", "defcontext=system_u:object_r:samba_share_t:s0", "fscontext=system_u:object_r:samba_share_t:s0", "rootcontext=system_u:object_r:samba_share_t:s0", filesystem.name] - }; - - FnConsole.log[2]("File Systems, SELinux Contexts, Samba, Set: In Progress, Pool: " + pool.name + ", File System: " + filesystem.name); - FnConsole.log[3](FnConsoleCommand({ command: process.command })); - - return cockpit.spawn(process.command, { err: "out", superuser: "require" }) - .done(function () { - FnConsole.log[1]("File Systems, SELinux Contexts, Samba, Set: Success, Pool: " + pool.name + ", File System: " + filesystem.name); - }) - .fail(function (message, data) { - FnConsole.warn("File Systems, SELinux Contexts, Samba, Set: Failed, Pool: " + pool.name + ", File System: " + filesystem.name + ", Message: " + (data ? data : message)); - }) -} - -function FnFileSystemShareSmbDisable(pool = { name, id }, filesystem = { name, id }) { - let process = { - command: [((zfsmanager.user.admin || !zfsmanager.user.name) ? "pkexec" : ""), "/sbin/zfs", "set", "sharesmb=off", filesystem.name] - }; - - FnConsole.log[2]("File Systems, Share SMB, Disable: In Progress, Pool: " + pool.name + ", File System: " + filesystem.name); - FnConsole.log[3](FnConsoleCommand({ command: process.command })); - - return cockpit.spawn(process.command, { err: "out" }) - .done(function () { - FnConsole.log[1]("File Systems, Share SMB, Disable: Success, Pool: " + pool.name + ", File System: " + filesystem.name); - }) - .fail(function (message, data) { - if (/property may be set/gi.test(data)) { //False error is generated when configuring filesystem - FnConsole.log[1]("File Systems, Share SMB, Disable: Success, Pool: " + pool.name + ", File System: " + filesystem.name); - } else { - FnConsole.warn("File Systems, Share SMB, Disable: Failed, Pool: " + pool.name + ", File System: " + filesystem.name + ", Message: " + (data ? data : message)); - } - }); -} - -function FnFileSystemShareSmbEnable(pool = { name, id }, filesystem = { name, id }) { - let process = { - command: [((zfsmanager.user.admin || !zfsmanager.user.name) ? "pkexec" : ""), "/sbin/zfs", "set", "sharesmb=on", filesystem.name] - }; - - FnConsole.log[2]("File Systems, Share SMB, Enable: In Progress, Pool: " + pool.name + ", File System: " + filesystem.name); - FnConsole.log[3](FnConsoleCommand({ command: process.command })); - - return cockpit.spawn(process.command, { err: "out" }) - .done(function () { - FnConsole.log[1]("File Systems, Share SMB, Enable: Success, Pool: " + pool.name + ", File System: " + filesystem.name); - }) - .fail(function (message, data) { - if (/property may be set/gi.test(data)) { //False error is generated when configuring filesystem - FnConsole.log[1]("File Systems, Share SMB, Enable: Success, Pool: " + pool.name + ", File System: " + filesystem.name); - } else { - FnConsole.warn("File Systems, Share SMB, Enable: Failed, Pool: " + pool.name + ", File System: " + filesystem.name + ", Message: " + (data ? data : message)); - } - }); -} - -function FnFileSystemShareSmbInheritedDisable(pool = { name, id, altroot: false }, filesystem = { name }, force = { disable: false }) { - let process = { - command: ["/sbin/zfs", "get", "-H", "name,sharesmb", "-o", "property,value,source", "-r", "-t", "filesystem"], - promise: cockpit.defer() - }; - - if (filesystem.name) { - process.command.push(filesystem.name); - } else if (pool.name) { - process.command.push(pool.name); - } - - FnConsole.log[2]("File Systems, Share SMB, Inherited, Disable: In Progress"); - FnConsole.log[3](FnConsoleCommand({ command: process.command })); - - cockpit.spawn(process.command, { err: "out" }) - .done(function (data) { - FnConsole.log[4](FnConsoleVerbose({ data: data, message: "File Systems, Share SMB, Inherited, Disable:" })); - - let filesystems = data.replace(/\nsharesmb/g, "\u22C5sharesmb").replace(/\t+/g, "\u22C5").split(/\n/g).filter(v => v && /\u22C5sharesmb\u22C5on\u22C5inherited from|\u22C5sharesmb\u22C5off\u22C5inherited from/gi.test(v)); - let promise = Promise.resolve(); - - if (filesystems.length > 0) { - filesystems.forEach((_value, _index) => { - _value = _value.split("\u22C5"); - - let filesystem = { - name: _value[1], - id: FnGenerateId({ at: true, colon: true, forwardslash: true, period: true, underscore: true, whitespace: true }, { name: _value[1], attribute: true }), - sharesmb: { - enabled: (_value[4].toLowerCase() == "on" ? true : false), - source: _value[5] - } - }; - let pool = { - name: filesystem.name.replace(/\/.*$/, ""), - id: FnGenerateId({ at: true, colon: true, forwardslash: true, period: true, underscore: true, whitespace: true }, { name: filesystem.name, attribute: true }) - }; - - promise = promise.then(_ => new Promise(resolve => - setTimeout(function () { - if (filesystem.sharesmb.enabled && !force.disable) { - FnFileSystemShareSmbEnable({ name: pool.name, id: pool.id }, { name: filesystem.name, id: filesystem.id }) - .finally(function () { - if (_index == (filesystems.length - 1)) { - FnConsole.log[1]("File Systems, Share SMB, Inherited, Disable: Success"); - - process.promise.resolve(); - } - }); - } else { - if (force.disable) { - FnSambaShareDisable({ name: pool.name, id: pool.id, altroot: pool.altroot, readonly: false }, { name: filesystem.name, id: filesystem.id }, { restart: false }, { modal: false, silent: true }); - - if (_index == (filesystems.length - 1)) { - setTimeout(function () { - FnConsole.log[1]("File Systems, Share SMB, Inherited, Disable: Success"); - - process.promise.resolve(); - }, 1000); - } - } else { - FnFileSystemShareSmbDisable({ name: pool.name, id: pool.id }, { name: filesystem.name, id: filesystem.id }) - .finally(function () { - if (_index == (filesystems.length - 1)) { - FnConsole.log[1]("File Systems, Share SMB, Inherited, Disable: Success"); - - process.promise.resolve(); - } - }); - } - } - - resolve(); - }, (force.disable ? 1000 : 500)) - )); - }); - } else { - FnConsole.log[1]("File Systems, Share SMB, Inherited, Disable: Success" + (pool.name ? ", Pool: " + pool.name : "")); - - process.promise.resolve(); - } - }) - .fail(function (message, data) { - FnConsole.warn("File Systems, Share SMB, Inherited, Disable: Failed" + ", Message: " + (data ? data : message)); - - process.promise.resolve(); - }); - - return process.promise.promise(); -} - -function FnFileSystemUnlock(pool = { name, id, altroot: false, readonly: false }, filesystem = { name, id, mount: true, overlay: true, passphrase, type }, samba = { enable: false }, modal = { name, id }, display = { refresh: true }) { - let process = { - command: [] - }; - - modal.id = (modal.id ? "-" + modal.id : ""); - - //Escape percentage and single quote special character for printf - if (/\%/g.test(filesystem.passphrase)) { - filesystem.passphrase = filesystem.passphrase.replace(/\%/g, "\%\%"); - } - if (/\'/g.test(filesystem.passphrase)) { - filesystem.passphrase = filesystem.passphrase.replace(/\'/g, "\'\"\'\"\'"); - } - - process.command = ["/bin/sh", "-c", "printf '" + filesystem.passphrase + "' | /sbin/zfs load-key \"" + filesystem.name + "\""]; - - FnConsole.log[2]("File Systems, Unlock: In Progress, Pool: " + pool.name + ", File System: " + filesystem.name); - FnConsole.log[3](FnConsoleCommand({ command: process.command })); - - if (display.refresh) { - $("#spinner-" + modal.name + modal.id + " span").text("Unlocking " + filesystem.type.toLowerCase() + "..."); - } - - return cockpit.spawn(process.command, { err: "out", superuser: "require" }) - .done(function (data, message) { - FnConsole.log[4](FnConsoleVerbose({ data: data, message: "File Systems, Unlock:" })); - - if (/error|Incorrect key/i.test(data)) { - FnFileSystemUnlockFail({ name: pool.name, id: pool.id }, { name: filesystem.name, id: filesystem.id, type: filesystem.type }, { name: modal.name, id: modal.id }, { refresh: display.refresh }, { data: data, message: message }); - return; - } - - FnDisplayAlert({ status: "success", title: "File System successfully unlocked", description: filesystem.name, breakword: false }, { name: "filesystem-unlock", id: filesystem.id, timeout: 4 }); - - FnConsole.log[1]("File Systems, Unlock: Success, Pool: " + pool.name + ", File System: " + filesystem.name); - - if (filesystem.mount) { - setTimeout(function () { - FnFileSystemMount({ name: pool.name, id: pool.id, altroot: pool.altroot, readonly: pool.readonly }, { name: filesystem.name, id: filesystem.id, overlay: filesystem.overlay, type: filesystem.type }, { enable: samba.enable }, { refresh: display.refresh }) - .finally(function () { - if (display.refresh) { - $("#modal-" + modal.name + modal.id).modal("hide"); - - setTimeout(function () { - FnStoragePoolRefresh({ name: pool.name, id: pool.id }, { storagepool: true, filesystems: true, snapshots: true, status: false }); - }, 200); - } - }); - }, 200); - } else if (display.refresh) { - $("#modal-" + modal.name + modal.id).modal("hide"); - - setTimeout(function () { - FnStoragePoolRefresh({ name: pool.name, id: pool.id }, { storagepool: true, filesystems: true, snapshots: true, status: false }); - }, 200); - } - }) - .fail(function (message, data) { - if (/Key already loaded/i.test(data)) { - FnFileSystemUnlockWarn({ name: pool.name, id: pool.id, altroot: pool.altroot, readonly: pool.readonly }, { name: filesystem.name, id: filesystem.id, mount: filesystem.mount, overlay: filesystem.overlay, type: filesystem.type }, { enable: samba.enable }, { name: modal.name, id: modal.id }, { refresh: display.refresh }, { data: data, message: message }); - } else { - FnFileSystemUnlockFail({ name: pool.name, id: pool.id }, { name: filesystem.name, id: filesystem.id, type: filesystem.type }, { name: modal.name, id: modal.id }, { refresh: display.refresh }, { data: data, message: message }); - } - }); -} - -function FnFileSystemUnlockFail(pool = { name, id }, filesystem = { name, id, type }, modal = { name, id }, display = { refresh: true }, process = { data, message }) { - modal.hide = true; - - if (/Incorrect key provided/gi.test(process.data)) { - modal.hide = false; - - $("#validationwrapper-" + modal.name + "-passphrase" + modal.id).addClass("has-error"); - $("#helpblock-" + modal.name + "-passphrase" + modal.id).addClass("has-error").removeClass("hidden").text("Passphrase is incorrect."); - $("#input-" + modal.name + "-passphrase" + modal.id).focus(); - } - - if (!modal.hide && display.refresh) { - $("#spinner-" + modal.name + modal.id).addClass("hidden"); - $("#spinner-" + modal.name + modal.id + " span").text(""); - $("#btn-" + modal.name + "-apply" + modal.id).prop("disabled", false); - } - - if (modal.hide || !display.refresh) { - FnDisplayAlert({ status: "danger", title: "File System could not be unlocked", description: filesystem.name, breakword: false }, { name: "filesystem-unlock", id: filesystem.id, timeout: 4 }); - } - - if (modal.hide) { - if (display.refresh) { - $("#modal-" + modal.name + modal.id).modal("hide"); - - setTimeout(function () { - FnStoragePoolRefresh({ name: pool.name, id: pool.id }, { storagepool: true, filesystems: true, snapshots: true, status: false }); - }, 200); - } - } - - FnConsole.warn("File Systems, Unlock: Failed, Pool: " + pool.name + ", File System: " + filesystem.name + ", Message: " + (process.data ? process.data : process.message)); -} - -function FnFileSystemUnlockWarn(pool = { name, id, altroot: false, readonly: false }, filesystem = { name, id, mount: true, overlay: true, type }, samba = { enable: false }, modal = { name, id }, display = { refresh: true }, process = { data, message }) { - FnDisplayAlert({ status: "warning", title: "File System was already unlocked", description: filesystem.name, breakword: false }, { name: "filesystem-unlock", id: filesystem.id, timeout: 4 }); - - FnConsole.warn("File Systems, Unlock: Warning, Pool: " + pool.name + ", File System: " + filesystem.name + ", Message: " + (process.data ? process.data : process.message)); - - if (filesystem.mount) { - setTimeout(function () { - FnFileSystemMount({ name: pool.name, id: pool.id, altroot: pool.altroot, readonly: pool.readonly }, { name: filesystem.name, id: filesystem.id, overlay: filesystem.overlay, type: filesystem.type }, { enable: samba.enable }, { refresh: display.refresh }) - .finally(function () { - if (display.refresh) { - $("#modal-" + modal.name + modal.id).modal("hide"); - - setTimeout(function () { - FnStoragePoolRefresh({ name: pool.name, id: pool.id }, { storagepool: true, filesystems: true, snapshots: true, status: false }); - }, 200); - } - }); - }, 200); - } else if (display.refresh) { - $("#modal-" + modal.name + modal.id).modal("hide"); - - setTimeout(function () { - FnStoragePoolRefresh({ name: pool.name, id: pool.id }, { storagepool: true, filesystems: true, snapshots: true, status: false }); - }, 200); - } -} - -function FnFileSystemUnmount(pool = { name, id, altroot: false, readonly: false }, filesystem = { name, id, force: false, lock: false, type }, samba = { disable: false, restart: false }) { - if (samba.restart) { - FnSambaStop() - .finally(function () { - $("#spinner-storagepool-filesystem-unmount-" + filesystem.id + " span").text("Unmounting " + filesystem.type.toLowerCase() + "..."); - - FnFileSystemUnmountCommand({ name: pool.name, id: pool.id }, { name: filesystem.name, id: filesystem.id, force: filesystem.force, lock: filesystem.lock }, { refresh: ((filesystem.lock || samba.disable) ? false : true) }) - .done(function () { - if (filesystem.lock) { - $("#spinner-storagepool-filesystem-unmount-" + filesystem.id + " span").text("Locking " + filesystem.type.toLowerCase() + "..."); - - FnFileSystemLock({ name: pool.name, id: pool.id }, { name: filesystem.name, id: filesystem.id, type: filesystem.type }, { refresh: false }) - .finally(function () { - if (samba.disable) { - $("#spinner-storagepool-filesystem-unmount-" + filesystem.id + " span").text("Disabling Samba share..."); - - if (zfsmanager.configuration.samba.manage) { - FnSambaShareDisable({ name: pool.name, id: pool.id, altroot: pool.altroot, readonly: pool.readonly }, { name: filesystem.name, id: filesystem.id }, { restart: samba.restart }, { modal: false, silent: false }); - } else { - FnFileSystemShareSmbDisable({ name: pool.name, id: pool.id }, { name: filesystem.name, id: filesystem.id }); - } - } - - setTimeout(function () { - $("#modal-storagepool-filesystem-unmount-" + filesystem.id).modal("hide"); - - setTimeout(function () { - FnStoragePoolRefresh({ name: pool.name, id: pool.id }, { storagepool: true, filesystems: true, snapshots: true, status: false }); - }, 200); - }, (samba.disable ? 1000 : 200)); - }); - } else { - if (samba.disable) { - $("#spinner-storagepool-filesystem-unmount-" + filesystem.id + " span").text("Disabling Samba share..."); - - if (zfsmanager.configuration.samba.manage) { - FnSambaShareDisable({ name: pool.name, id: pool.id, altroot: pool.altroot, readonly: pool.readonly }, { name: filesystem.name, id: filesystem.id }, { restart: samba.restart }, { modal: false, silent: false }); - } else { - FnFileSystemShareSmbDisable({ name: pool.name, id: pool.id }, { name: filesystem.name, id: filesystem.id }); - } - } - - setTimeout(function () { - $("#modal-storagepool-filesystem-unmount-" + filesystem.id).modal("hide"); - - setTimeout(function () { - FnStoragePoolRefresh({ name: pool.name, id: pool.id }, { storagepool: true, filesystems: true, snapshots: true, status: false }); - }, 200); - }, (samba.disable ? 1000 : 200)); - } - }) - .finally(function () { - if (!samba.disable || !zfsmanager.configuration.samba.manage) { - FnSambaStart(); - } - }); - }); - } else { - $("#spinner-storagepool-filesystem-unmount-" + filesystem.id + " span").text("Unmounting " + filesystem.type.toLowerCase() + "..."); - - FnFileSystemUnmountCommand({ name: pool.name, id: pool.id }, { name: filesystem.name, id: filesystem.id, force: filesystem.force, lock: filesystem.lock }, { refresh: ((filesystem.lock || samba.disable) ? false : true) }) - .done(function () { - if (filesystem.lock) { - $("#spinner-storagepool-filesystem-unmount-" + filesystem.id + " span").text("Locking " + filesystem.type.toLowerCase() + "..."); - - FnFileSystemLock({ name: pool.name, id: pool.id }, { name: filesystem.name, id: filesystem.id, type: filesystem.type }, { refresh: false }) - .finally(function () { - if (samba.disable) { - $("#spinner-storagepool-filesystem-unmount-" + filesystem.id + " span").text("Disabling Samba share..."); - - if (zfsmanager.configuration.samba.manage) { - FnSambaShareDisable({ name: pool.name, id: pool.id, altroot: pool.altroot, readonly: pool.readonly }, { name: filesystem.name, id: filesystem.id }, { restart: samba.restart }, { modal: false, silent: false }); - } else { - FnFileSystemShareSmbDisable({ name: pool.name, id: pool.id }, { name: filesystem.name, id: filesystem.id }); - } - } - - setTimeout(function () { - $("#modal-storagepool-filesystem-unmount-" + filesystem.id).modal("hide"); - - setTimeout(function () { - FnStoragePoolRefresh({ name: pool.name, id: pool.id }, { storagepool: true, filesystems: true, snapshots: true, status: false }); - }, 200); - }, (samba.disable ? 1000 : 200)); - }); - } else { - if (samba.disable) { - $("#spinner-storagepool-filesystem-unmount-" + filesystem.id + " span").text("Disabling Samba share..."); - - if (zfsmanager.configuration.samba.manage) { - FnSambaShareDisable({ name: pool.name, id: pool.id, altroot: pool.altroot, readonly: pool.readonly }, { name: filesystem.name, id: filesystem.id }, { restart: samba.restart }, { modal: false, silent: false }); - } else { - FnFileSystemShareSmbDisable({ name: pool.name, id: pool.id }, { name: filesystem.name, id: filesystem.id }); - } - } - - setTimeout(function () { - $("#modal-storagepool-filesystem-unmount-" + filesystem.id).modal("hide"); - - setTimeout(function () { - FnStoragePoolRefresh({ name: pool.name, id: pool.id }, { storagepool: true, filesystems: true, snapshots: true, status: false }); - }, 200); - }, (samba.disable ? 1000 : 200)); - } - }); - } -} - -function FnFileSystemUnmountCommand(pool = { name, id }, filesystem = { name, id, force: false, lock: false }, display = { refresh: true }) { - let process = { - command: [((zfsmanager.user.admin || !zfsmanager.user.name) ? "pkexec" : ""), "/sbin/zfs", "unmount", filesystem.name] - }; - - if (filesystem.force) { - process.command.splice(3, 0, "-f"); - } - - FnConsole.log[2]("File Systems, Unmount: In Progress, Pool: " + pool.name + ", File System: " + filesystem.name); - FnConsole.log[3](FnConsoleCommand({ command: process.command })); - - return cockpit.spawn(process.command, { err: "out" }) - .done(function () { - FnDisplayAlert({ status: "success", title: "File System successfully unmounted", description: filesystem.name, breakword: false }, { name: "filesystem-unmount", id: filesystem.id, timeout: 4 }); - - FnConsole.log[1]("File Systems, Unmount: Success, Pool: " + pool.name + ", File System: " + filesystem.name); - - if (display.refresh) { - $("#modal-storagepool-filesystem-unmount-" + filesystem.id).modal("hide"); - - setTimeout(function () { - FnStoragePoolRefresh({ name: pool.name, id: pool.id }, { storagepool: true, filesystems: true, snapshots: true, status: false }); - }, 200); - } - }) - .fail(function (message, data) { - FnDisplayAlert({ status: "danger", title: "File System could not be unmounted", description: filesystem.name, breakword: false }, { name: "filesystem-unmount", id: filesystem.id, timeout: 4 }); - - FnConsole.warn("File Systems, Unmount: Failed, Pool: " + pool.name + ", File System: " + filesystem.name + ", Message: " + (data ? data : message)); - - $("#modal-storagepool-filesystem-unmount-" + filesystem.id).modal("hide"); - - setTimeout(function () { - FnStoragePoolRefresh({ name: pool.name, id: pool.id }, { storagepool: true, filesystems: true, snapshots: true, status: false }); - }, 200); - }); -} - -//#endregion - -//#region Snapshots - -function FnSnapshotsGet(pool = { name, id }) { - let process = { - command: ["/sbin/zfs", "list", "-H", "-o", "name,creation,used,refer,encryption,encryptionroot,keystatus,clones", "-r", "-p", "-t", "snapshot", pool.name] - }; - let snapshots = { - empty: true - }; - - pool.altroot = (($("#tr-storagepool-" + pool.id).attr("data-pool-altroot") == "true") ? true : false); - pool.readonly = (($("#tr-storagepool-" + pool.id).attr("data-pool-readonly") == "true") ? true : false); - - FnConsole.log[2]("Snapshots, Get: In Progress, Pool: " + pool.name); - FnConsole.log[3](FnConsoleCommand({ command: process.command })); - - return cockpit.spawn(process.command, { err: "out" }) - .done(function (data, message) { - FnConsole.log[4](FnConsoleVerbose({ data: data, message: "Snapshots, Get:" })); - - if (data) { - snapshots.empty = false; - - FnSnapshotsGetCommand({ name: pool.name, id: pool.id, altroot: pool.altroot, readonly: pool.readonly }, { data: data, message: message }); - } - - FnConsole.log[1]("Snapshots, Get: Success, Pool: " + pool.name); - }) - .fail(function (message, data) { - FnConsole.warn("Snapshots, Get: Failed, Pool: " + pool.name + ", Message: " + (data ? data : message)); - }) - .finally(function () { - if (snapshots.empty) { - $("#tbody-storagepool-snapshots-" + pool.id).empty(); - $("#tbody-storagepool-snapshots-" + pool.id).append(`No snapshots found.`); - $("#modals-storagepool-snapshots-" + pool.id).remove(); - $("#modals-storagepool-snapshot-" + pool.id).remove(); - $("#modals").append(`
    `); - - //Register snapshots modals - if (!pool.readonly) { - FnModalSnaphshotsCreate({ name: pool.name, id: pool.id }); - } - - $("#tr-storagepool-" + pool.id).attr("data-pool-refresh-snapshots", "true"); - - $("#spinner-storagepool-snapshots-" + pool.id).addClass("hidden"); - $("#paneltitle-storagepool-snapshots-" + pool.id).removeClass("hidden").text(FnDateTime()); - $("#btn-storagepool-snapshots-create-" + pool.id).prop("disabled", false); - $("#btn-storagepool-snapshots-refresh-" + pool.id).prop("disabled", false); - } - - FnStoragePoolSpinnerHide({ name: pool.name, id: pool.id }); - FnCockpitElementsUpdate(); - }); -} - -function FnSnapshotsGetCommand(pool = { name, id, altroot: false, readonly: false }, process = { data, message }) { - let snapshots = process.data.split(/\n/g).filter(v => v); - - $("#tbody-storagepool-snapshots-" + pool.id).empty(); - $("#modals-storagepool-snapshots-" + pool.id).remove(); - $("#modals-storagepool-snapshot-" + pool.id).remove(); - $("#modals").append(`
    `); - $("#modals").append(`
    `); - - snapshots.forEach((_value, _index) => { - let snapshot = { - properties: _value.split(/\t/g).filter(v => v), - clones: [], - creation: "", - encryption: false, - encryptionroot: "", - id: "", - keystatus: "", - name: "", - actionsmenu: { - register: {} - } - }; - - if (!snapshot.properties[7]) { //Append clones property if not included after split - snapshot.properties[7] = ""; - } - - snapshot.output = ``; - - snapshot.properties.forEach((__value, __index) => { - //0=name, 1=creation, 2=used, 3=refer, 4=encryption, 5=encryptionroot, 6=keystatus, 7=clones - - switch (__index) { - case 0: //0=name - snapshot.name = __value; - snapshot.id = FnGenerateId({ at: true, colon: true, forwardslash: true, period: true, underscore: true, whitespace: true }, { name: snapshot.name, attribute: true }); - - snapshot.output += `Name:` + __value + ``; - break; - case 1: //1=creation - snapshot.creation = __value; - - snapshot.output += `Creation:` + FnDateTimeEpoch({ date: __value }) + ``; - break; - case 2: //2=used - snapshot.output += `Used:` + FnFormatBytes({ base2: true, decimals: 2, value: __value }) + ``; - break; - case 3: //3=refer - snapshot.output += `Name:` + FnFormatBytes({ base2: true, decimals: 2, value: __value }) + ``; - break; - case 4: //4=encryption - if (__value.toLowerCase() != "off") { - snapshot.encryption = true; - } else { - snapshot.encryption = false; - } - break; - case 5: //5=encryptionroot - snapshot.encryptionroot = __value; - break; - case 6: //6=keystatus - snapshot.keystatus = __value; - break; - case 7: //7=clones - snapshot.clones = __value.split(",").filter(v => v).sort(); - - snapshot.output += `Clones:` + (snapshot.clones.length > 0 ? snapshot.clones.join(", ") : `None`) + ``; - break; - } - - //Add action menu at end of array - if (__index >= (snapshot.properties.length - 1)) { - snapshot.icons = { - keystatus: { - locked: ``, - unlocked: `` - } - }; - - snapshot.output += `Encrypted:` + (/available|unavailable/.test(snapshot.keystatus) ? `Yes` : `No`) + ``; - - if (snapshot.keystatus == "unavailable") { - snapshot.output += snapshot.icons.keystatus.locked; - } else if (snapshot.keystatus == "available") { - snapshot.output += snapshot.icons.keystatus.unlocked; - } - - snapshot.output += ``; - - //Actions menu - snapshot.actionsmenu.items = { - item: [], - itemdivider: function () { - if (this.item.length > 0 && this.itemdestroy.length > 0) { - this.item.push(this.divider); - } - }, - itemdestroy: [], - divider: `` - }; - snapshot.actionsmenu.display = function () { - if ((this.items.item.length + this.items.itemdestroy.length) > 0 || pool.readonly) { - this.items.itemdivider(); - - return this.header + this.items.item.join("\n") + this.items.itemdestroy.join("\n") + this.footer; - } else { - return ""; - } - }; - snapshot.actionsmenu.header = ` - - `; - - //Clone Snapshot - if (!pool.readonly) { - snapshot.actionsmenu.items.item.push(`
  • Clone Snapshot
  • `); - - snapshot.actionsmenu.register.clone = true; - } - - //Rename Snapshot - if (!pool.readonly && snapshot.name != pool.name) { - snapshot.actionsmenu.items.item.push(`
  • Rename Snapshot
  • `); - - snapshot.actionsmenu.register.rename = true; - } - - //Roll Back Snapshot - if (!pool.readonly) { - snapshot.actionsmenu.items.item.push(`
  • Roll Back Snapshot
  • `); - - snapshot.actionsmenu.register.rollback = true; - } - - //Destroy Snapshot - if (!pool.readonly) { - snapshot.actionsmenu.items.itemdestroy.push(`
  • Destroy Snapshot
  • `); - - snapshot.actionsmenu.register.destroy = true; - } - - snapshot.output += `` + snapshot.actionsmenu.display() + ``; - } - - }); - - snapshot.output += ``; - - $("#tbody-storagepool-snapshots-" + pool.id).append(snapshot.output); - - //Register snapshot modals - if (snapshot.actionsmenu.register.clone) { - FnModalSnapshotClone({ name: pool.name, id: pool.id, altroot: pool.altroot }, { name: snapshot.name, id: snapshot.id, encryption: snapshot.encryption, encryptionroot: snapshot.encryptionroot }); - } - if (snapshot.actionsmenu.register.destroy) { - FnModalSnapshotDestroy({ name: pool.name, id: pool.id, altroot: pool.altroot, readonly: pool.readonly }, { name: snapshot.name, id: snapshot.id, clones: snapshot.clones }); - } - if (snapshot.actionsmenu.register.rename) { - FnModalSnapshotRename({ name: pool.name, id: pool.id }, { name: snapshot.name, id: snapshot.id, creation: snapshot.creation }); - } - if (snapshot.actionsmenu.register.rollback) { - FnModalSnapshotRollBack({ name: pool.name, id: pool.id, altroot: pool.altroot, readonly: pool.readonly }, { name: snapshot.name, id: snapshot.id, creation: snapshot.creation }); - } - }); - - //Register snapshots modals - if (!pool.readonly) { - FnModalSnaphshotsCreate({ name: pool.name, id: pool.id }); - } - - $("#tr-storagepool-" + pool.id).attr("data-pool-refresh-snapshots", "true"); - - $("#spinner-storagepool-snapshots-" + pool.id).addClass("hidden"); - $("#paneltitle-storagepool-snapshots-" + pool.id).removeClass("hidden").text(FnDateTime()); - $("#btn-storagepool-snapshots-create-" + pool.id).prop("disabled", false); - $("#btn-storagepool-snapshots-refresh-" + pool.id).prop("disabled", false); - - FnStoragePoolSpinnerHide({ name: pool.name, id: pool.id }); - FnCockpitElementsUpdate(); -} - -//#endregion - -//#region Snapshot - -function FnSnapshotChildFileSystemsGet(pool = { name, id }, snapshot = { name, id }, filesystems = { id: [] }, modal = { name, id }) { - let process = { - command: ["/sbin/zfs", "list", "-H", "-o", "name", "-r", "-t", "filesystem"] - }; - - filesystems.id.forEach(_value => _value && process.command.push(_value)); - - FnConsole.log[2]("Snapshots, Child, File Systems, Get: In Progress, Pool: " + pool.name + ", Snapshot: " + snapshot.name); - FnConsole.log[3](FnConsoleCommand({ command: process.command })); - - return cockpit.spawn(process.command, { err: "out" }) - .done(function (data) { - FnConsole.log[4](FnConsoleVerbose({ data: data, message: "Snapshots, Child, File Systems, Get:" })); - - let filesystems = { - id: data.split(/\n/g).filter(v => v), - count: { - filesystems: 0 - } - }; - - if (filesystems.id.length > 0) { - filesystems.id.forEach((_value, _index) => { - if (_value != snapshot.name.replace(/^(.*)\@.*$/, "$1")) { - filesystems.count.filesystems++; - - $("#ul-" + modal.name + "-child-filesystems-" + modal.id).append("
  • " + _value + "
  • \n"); - } - }); - - $("#panelgroup-" + modal.name + "-" + modal.id).attr("data-snapshot-child-filesystems", filesystems.count.filesystems); - } - - FnConsole.log[1]("Snapshots, Child, File Systems, Get: Success, Pool: " + pool.name + ", Snapshot: " + snapshot.name); - }) - .fail(function (message, data) { - FnConsole.warn("Snapshots, Child, File Systems, Get: Failed, Pool: " + pool.name + ", Snapshot: " + snapshot.name + ", Message: " + (data ? data : message)); - }); -} - -function FnSnapshotChildSnapshotsGet(pool = { name, id }, snapshot = { name, id, exclude: false }, filesystems = { id: [] }, modal = { name, id }) { - let process = { - command: ["/sbin/zfs", "list", "-H", "-o", "name", "-r", "-t", "snapshot"] - }; - - if (!snapshot.exclude) { - process.command.push(snapshot.name.replace(/^(.*)\@.*$/, "$1")); - } - - filesystems.id.forEach(_value => _value && process.command.push(_value)); - - FnConsole.log[2]("Snapshots, Child, Snapshots, Get: In Progress, Pool: " + pool.name + ", Snapshot: " + snapshot.name); - FnConsole.log[3](FnConsoleCommand({ command: process.command })); - - return cockpit.spawn(process.command, { err: "out" }) - .done(function (data) { - FnConsole.log[4](FnConsoleVerbose({ data: data, message: "Snapshots, Child, Snapshots, Get:" })); - - let snapshots = { - id: data.split(/\n/g).filter(v => v), - count: { - snapshots: 0, - snapshotswithclones: (snapshot.exclude ? $("#panelgroup-" + modal.name + "-" + modal.id).attr("data-snapshot-child-snapshotswithclones") : 0) //Exclude for Roll Back and append - } - }; - - if (snapshots.id.length > 0) { - snapshots.id.forEach((_value, _index) => { - if (_value != snapshot.name) { - //Recursive all will delete child file system snapshots with same name only. If clones are also found, all clone snapshots will be deleted - if (new RegExp("^" + snapshot.name.replace(/^(.*)\@.*$/, "$1") + "/.*@" + snapshot.name.replace(/^.*\@(.*)$/, "$1") + "$").test(_value)) { //Child file system snapshots with same name - if (!snapshot.exclude) { - snapshots.count.snapshots++; - - $("#ul-" + modal.name + "-child-snapshots-" + modal.id).append("
  • " + _value + "
  • \n"); - } - - snapshots.count.snapshotswithclones++; - - $("#ul-" + modal.name + "-child-snapshotswithclones-" + modal.id).append("
  • " + _value + "
  • \n"); - } else { - filesystems.id.forEach((__value, __index) => { - if (new RegExp("^" + __value.replace(/^(.*)\@.*$/, "$1") + "@").test(_value) || new RegExp("^" + __value.replace(/^(.*)\@.*$/, "$1") + "/.*@").test(_value)) { //Snapshots of clone file system - snapshots.count.snapshotswithclones++; - - $("#ul-" + modal.name + "-child-snapshotswithclones-" + modal.id).append("
  • " + _value + "
  • \n"); - } - }); - } - } - }); - - if (!snapshot.exclude) { - $("#panelgroup-" + modal.name + "-" + modal.id).attr("data-snapshot-child-snapshots", snapshots.count.snapshots); - } - $("#panelgroup-" + modal.name + "-" + modal.id).attr("data-snapshot-child-snapshotswithclones", snapshots.count.snapshotswithclones); - } - - FnConsole.log[1]("Snapshots, Child, Snapshots, Get: Success, Pool: " + pool.name + ", Snapshot: " + snapshot.name); - }) - .fail(function (message, data) { - FnConsole.warn("Snapshots, Child, Snapshots, Get: Failed, Pool: " + pool.name + ", Snapshot: " + snapshot.name + ", Message: " + (data ? data : message)); - }); -} - -function FnSnapshotClone(pool = { name, id, altroot: false }, snapshot = { name, id, clone: { name, createnonexistparents: false, parent } }) { - let process = { - command: [((zfsmanager.user.admin || !zfsmanager.user.name) ? "pkexec" : ""), "/sbin/zfs", "clone", "-o", "sharenfs=off", "-o", "sharesmb=off", snapshot.name, snapshot.clone.name] - }; - - if (snapshot.clone.createnonexistparents) { - process.command.splice(3, 0, "-p"); - } - - FnConsole.log[2]("Snapshots, Clone: In Progress, Pool: " + pool.name + ", Snapshot: " + snapshot.name); - FnConsole.log[3](FnConsoleCommand({ command: process.command })); - - $("#spinner-storagepool-snapshot-clone-" + snapshot.id + " span").text("Cloning snapshot..."); - - return cockpit.spawn(process.command, { err: "out" }) - .done(function (data, message) { - FnConsole.log[4](FnConsoleVerbose({ data: data, message: "Snapshots, Clone:" })); - - if (/dataset already exists/i.test(data)) { - FnSnapshotCloneFail({ name: pool.name, id: pool.id }, { name: snapshot.name, id: snapshot.id }, { data: data, message: message }); - return; - } - - FnDisplayAlert({ status: "success", title: "Snapshot successfully cloned", description: snapshot.name, breakword: false }, { name: "snapshot-clone", id: snapshot.id, timeout: 4 }); - - FnConsole.log[1]("Snapshots, Clone: Success, Pool: " + pool.name + ", Snapshot: " + snapshot.name); - - if (snapshot.clone.createnonexistparents && zfsmanager.configuration.samba.manage) { - $("#spinner-storagepool-snapshot-clone-" + snapshot.id + " span").text("Disabling Samba share inheritance..."); - - FnFileSystemShareSmbInheritedDisable({ name: pool.name, id: pool.id, altroot: pool.altroot }, { name: snapshot.clone.parent }, { disable: true }) - .finally(function () { - $("#modal-storagepool-snapshot-clone-" + snapshot.id).modal("hide"); - - setTimeout(function () { - FnStoragePoolRefresh({ name: pool.name, id: pool.id }, { storagepool: true, filesystems: true, snapshots: true, status: false }); - }, 200); - }); - } else { - $("#modal-storagepool-snapshot-clone-" + snapshot.id).modal("hide"); - - setTimeout(function () { - FnStoragePoolRefresh({ name: pool.name, id: pool.id }, { storagepool: true, filesystems: true, snapshots: true, status: false }); - }, 200); - } - }) - .fail(function (message, data) { - FnSnapshotCloneFail({ name: pool.name, id: pool.id }, { name: snapshot.name, id: snapshot.id }, { data: data, message: message }); - }); -} - -function FnSnapshotCloneFail(pool = { name, id }, snapshot = { name, id }, process = { data, message }) { - let modal = { - hide: true - }; - - if (/filesystem successfully created/gi.test(process.data)) { - FnDisplayAlert({ status: "warning", title: "Snapshot cloned with errors", description: snapshot.name, breakword: false }, { name: "snapshot-clone", id: snapshot.id, timeout: 4 }); - - FnConsole.warn("Snapshots, Clone: Warning, Pool: " + pool.name + ", Snapshot: " + snapshot.name + ", Message: " + (process.data ? process.data : process.message)); - } else { - if (/dataset already exists/i.test(process.data)) { - modal.hide = false; - - $("#validationwrapper-storagepool-snapshot-clone-name-" + snapshot.id).addClass("has-error"); - $("#helpblock-storagepool-snapshot-clone-name-" + snapshot.id).addClass("has-error").removeClass("hidden").text("Name already exists."); - $("#input-storagepool-snapshot-clone-name-" + snapshot.id).focus(); - } else if (/parent does not exist/i.test(process.data)) { - modal.hide = false; - - $("#validationwrapper-storagepool-snapshot-clone-name-" + snapshot.id).addClass("has-error"); - $("#helpblock-storagepool-snapshot-clone-name-" + snapshot.id).addClass("has-error").removeClass("hidden").text("Parent file system does not exist."); - $("#input-storagepool-snapshot-clone-name-" + snapshot.id).focus(); - } - - if (modal.hide) { - FnDisplayAlert({ status: "danger", title: "Snapshot could not be cloned", description: snapshot.name, breakword: false }, { name: "snapshot-clone", id: snapshot.id, timeout: 4 }); - } - - FnConsole.warn("Snapshots, Clone: Failed, Pool: " + pool.name + ", Snapshot: " + snapshot.name + ", Message: " + (process.data ? process.data : process.message)); - } - - if (!modal.hide) { - $("#spinner-storagepool-snapshot-clone-" + snapshot.id).addClass("hidden"); - $("#spinner-storagepool-snapshot-clone-" + snapshot.id + " span").text(""); - $("#btn-storagepool-snapshot-clone-apply-" + snapshot.id).prop("disabled", false); - } - - if (modal.hide) { - $("#modal-storagepool-snapshot-clone-" + snapshot.id).modal("hide"); - - setTimeout(function () { - FnStoragePoolRefresh({ name: pool.name, id: pool.id }, { storagepool: true, filesystems: true, snapshots: true, status: false }); - }, 200); - } -} - -function FnSnapshotCreate(pool = { name, id }, snapshot = { name, id, recursive: false }, modal = { name, id }) { - let process = { - command: [((zfsmanager.user.admin || !zfsmanager.user.name) ? "pkexec" : ""), "/sbin/zfs", "snapshot", snapshot.name] - }; - - modal.hide = true; - - if (snapshot.recursive) { - process.command.splice(3, 0, "-r"); - } - - FnConsole.log[2]("Snapshots, Create: In Progress, Pool: " + pool.name + ", Snapshot: " + snapshot.name); - FnConsole.log[3](FnConsoleCommand({ command: process.command })); - - $("#spinner-" + modal.name + "-" + modal.id + " span").text("Creating snapshot" + (snapshot.recursive ? "s" : "") + "..."); - - return cockpit.spawn(process.command, { err: "out"}) - .done(function () { - FnDisplayAlert({ status: "success", title: "Snapshot successfully created", description: snapshot.name, breakword: false }, { name: "snapshot-create", id: snapshot.id, timeout: 4 }); - - FnConsole.log[1]("Snapshots, Create: Success, Pool: " + pool.name + ", Snapshot: " + snapshot.name); - }) - .fail(function (message, data) { - if (/dataset already exists/gi.test(data)) { - modal.hide = false; - - $("#validationwrapper-" + modal.name + "-name-" + modal.id).addClass("has-error"); - $("#helpblock-" + modal.name + "-name-" + modal.id).addClass("has-error").removeClass("hidden").text("Name already exists."); - $("#input-" + modal.name + "-name-" + modal.id).focus(); - } - - if (!modal.hide) { - $("#spinner-" + modal.name + "-" + modal.id).addClass("hidden"); - $("#spinner-" + modal.name + "-" + modal.id + " span").text(""); - $("#btn-" + modal.name + "-apply-" + modal.id).prop("disabled", false); - } - - if (modal.hide) { - FnDisplayAlert({ status: "danger", title: "Snapshot could not be created", description: snapshot.name, breakword: false }, { name: "snapshot-create", id: snapshot.id, timeout: 4 }); - } - - FnConsole.warn("Snapshots, Create: Failed, Pool: " + pool.name + ", Snapshot: " + snapshot.name + ", Message: " + (data ? data : message)); - }) - .finally(function () { - if (modal.hide) { - setTimeout(function () { - $("#modal-" + modal.name + "-" + modal.id).modal("hide"); - - setTimeout(function () { - FnStoragePoolRefresh({ name: pool.name, id: pool.id }, { storagepool: true, filesystems: true, snapshots: true, status: false }); - }, 200); - }, 700); - } - }); -} - -function FnSnapshotCreateDateGet(pool = { name, id }, snapshot = { name, id, recursive: false }, modal = { name, id }) { - let process = { - command: ["/bin/date", "\+\%Y.\%m.\%d-\%H.\%M.\%S"] - }; - - snapshot.date = ""; - - FnConsole.log[3](FnConsoleCommand({ command: process.command })); - - $("#spinner-" + modal.name + "-" + modal.id + " span").text("Creating snapshot" + (snapshot.recursive ? "s" : "") + "..."); - - return cockpit.spawn(process.command, { err: "out" }) - .done(function (data) { - FnConsole.log[4](FnConsoleVerbose({ data: data, message: "Snapshots, Create, Date, Get:" })); - - snapshot.date = data.replace(/[ \t\n]+/g, ""); - }) - .fail(function () { - snapshot.date = FnDateTimeSnapshot({ date: null }); - }) - .finally(function () { - snapshot.name = snapshot.name.replace(/^(.*)\@.*$/, "$1") + "@" + snapshot.date; - snapshot.id = FnGenerateId({ at: true, colon: true, forwardslash: true, period: true, underscore: true, whitespace: true }, { name: snapshot.name, attribute: true }); - - $("#input-" + modal.name + "-name-" + modal.id).val(snapshot.date); - - FnSnapshotCreate({ name: pool.name, id: pool.id }, { name: snapshot.name, id: snapshot.id, recursive: snapshot.recursive }, { name: modal.name, id: modal.id }); - }); -} - -function FnSnapshotDestroy(pool = { name, id, altroot: false, readonly: false }, snapshot = { name, id, clones: [], recursive: false, recursiveall: false }, samba = { restart: false }) { - if (samba.restart) { - FnSambaStop() - .finally(function () { - if (snapshot.recursiveall && snapshot.clones.length > 0 && zfsmanager.configuration.samba.manage) { - $("#spinner-storagepool-snapshot-destroy-" + snapshot.id + " span").text("Retrieving Samba shares..."); - - FnSambaSharesGet({ name: pool.name, id: pool.id }, { name: null, clones: snapshot.clones }) - .done(function (data) { - FnConsole.log[4](FnConsoleVerbose({ data: data, message: "Samba, Shares, Get:" })); - - let filesystems = { - id: data.split(/\n/g).filter(v => v && /\ton$/i.test(v)) - }; - - $("#spinner-storagepool-snapshot-destroy-" + snapshot.id + " span").text("Destroying snapshot..."); - - if (filesystems.id.length > 0) { - FnSnapshotDestroyCommand({ name: pool.name, id: pool.id }, { name: snapshot.name, id: snapshot.id, recursive: snapshot.recursive, recursiveall: snapshot.recursiveall }, { refresh: false }) - .done(function () { - $("#spinner-storagepool-snapshot-destroy-" + snapshot.id + " span").text("Destroying Samba shares..."); - - FnSambaSharesDestroy({ name: pool.name, id: pool.id, altroot: pool.altroot, readonly: false }, { id: filesystems.id }, { restart: samba.restart }, { silent: false }) - .finally(function () { - $("#modal-storagepool-snapshot-destroy-" + snapshot.id).modal("hide"); - - setTimeout(function () { - FnStoragePoolRefresh({ name: pool.name, id: pool.id }, { storagepool: true, filesystems: true, snapshots: true, status: false }); - }, 200); - }); - }); - } else { - $("#spinner-storagepool-snapshot-destroy-" + snapshot.id + " span").text("Destroying snapshot..."); - - FnSnapshotDestroyCommand({ name: pool.name, id: pool.id }, { name: snapshot.name, id: snapshot.id, recursive: snapshot.recursive, recursiveall: snapshot.recursiveall }, { refresh: true }) - .finally(function () { - FnSambaStart(); - }); - } - }) - .fail(function (message, data) { - FnSnapshotDestroyFail({ name: pool.name, id: pool.id }, { name: snapshot.name, id: snapshot.id }, { data: data, message: message }, { refresh: true }); - FnSambaStart(); - }); - } else { - $("#spinner-storagepool-snapshot-destroy-" + snapshot.id + " span").text("Destroying snapshot..."); - - FnSnapshotDestroyCommand({ name: pool.name, id: pool.id }, { name: snapshot.name, id: snapshot.id, recursive: snapshot.recursive, recursiveall: snapshot.recursiveall }, { refresh: true }) - .finally(function () { - FnSambaStart(); - }); - } - }); - } else { - if (snapshot.recursiveall && snapshot.clones.length > 0 && zfsmanager.configuration.samba.manage) { - $("#spinner-storagepool-snapshot-destroy-" + snapshot.id + " span").text("Retrieving Samba shares..."); - - FnSambaSharesGet({ name: pool.name, id: pool.id }, { name: null, clones: snapshot.clones }) - .done(function (data) { - FnConsole.log[4](FnConsoleVerbose({ data: data, message: "Samba, Shares, Get:" })); - - let filesystems = { - id: data.split(/\n/g).filter(v => v && /\ton$/i.test(v)) - }; - - $("#spinner-storagepool-snapshot-destroy-" + snapshot.id + " span").text("Destroying snapshot..."); - - if (filesystems.id.length > 0) { - FnSnapshotDestroyCommand({ name: pool.name, id: pool.id }, { name: snapshot.name, id: snapshot.id, recursive: snapshot.recursive, recursiveall: snapshot.recursiveall }, { refresh: false }) - .done(function () { - $("#spinner-storagepool-snapshot-destroy-" + snapshot.id + " span").text("Destroying Samba shares..."); - - FnSambaSharesDestroy({ name: pool.name, id: pool.id, altroot: pool.altroot, readonly: false }, { id: filesystems.id }, { restart: samba.restart }, { silent: false }) - .finally(function () { - $("#modal-storagepool-snapshot-destroy-" + snapshot.id).modal("hide"); - - setTimeout(function () { - FnStoragePoolRefresh({ name: pool.name, id: pool.id }, { storagepool: true, filesystems: true, snapshots: true, status: false }); - }, 200); - }); - }); - } else { - $("#spinner-storagepool-snapshot-destroy-" + snapshot.id + " span").text("Destroying snapshot..."); - - FnSnapshotDestroyCommand({ name: pool.name, id: pool.id }, { name: snapshot.name, id: snapshot.id, recursive: snapshot.recursive, recursiveall: snapshot.recursiveall }, { refresh: true }); - } - }) - .fail(function (message, data) { - FnSnapshotDestroyFail({ name: pool.name, id: pool.id }, { name: snapshot.name, id: snapshot.id }, { data: data, message: message }, { refresh: true }); - }); - } else { - $("#spinner-storagepool-snapshot-destroy-" + snapshot.id + " span").text("Destroying snapshot..."); - - FnSnapshotDestroyCommand({ name: pool.name, id: pool.id }, { name: snapshot.name, id: snapshot.id, recursive: snapshot.recursive, recursiveall: snapshot.recursiveall }, { refresh: true }); - } - } -} - -function FnSnapshotDestroyCommand(pool = { name, id }, snapshot = { name, id, recursive: false, recursiveall: false }, display = { refresh: true }) { - let process = { - command: [((zfsmanager.user.admin || !zfsmanager.user.name) ? "pkexec" : ""), "/sbin/zfs", "destroy", snapshot.name] - }; - - if (snapshot.recursive) { - process.command.splice(3, 0, "-r"); - } - if (snapshot.recursiveall) { - process.command.splice(3, 0, "-R"); - } - - FnConsole.log[1]("Snapshots, Destroy: In Progress, Pool: " + pool.name + ", Snapshot: " + snapshot.name); - FnConsole.log[3](FnConsoleCommand({ command: process.command })); - - return cockpit.spawn(process.command, { err: "out" }) - .done(function () { - FnDisplayAlert({ status: "success", title: "Snapshot successfully destroyed", description: snapshot.name, breakword: false }, { name: "snapshot-destroy", id: snapshot.id, timeout: 4 }); - - FnConsole.log[1]("Snapshots, Destroy: Success, Pool: " + pool.name + ", Snapshot: " + snapshot.name); - }) - .fail(function (message, data) { - FnSnapshotDestroyFail({ name: pool.name, id: pool.id }, { name: snapshot.name, id: snapshot.id }, { data: data, message: message }, { refresh: false }); - - display.refresh = true; - }) - .finally(function () { - if (display.refresh) { - $("#modal-storagepool-snapshot-destroy-" + snapshot.id).modal("hide"); - - setTimeout(function () { - FnStoragePoolRefresh({ name: pool.name, id: pool.id }, { storagepool: true, filesystems: true, snapshots: true, status: false }); - }, 200); - } - }); -} - -function FnSnapshotDestroyFail(pool = { name, id }, snapshot = { name, id }, process = { data, message }, display = { refresh: true }) { - FnDisplayAlert({ status: "danger", title: "Snapshot could not be destroyed", description: snapshot.name, breakword: false }, { name: "snapshot-destroy", id: snapshot.id, timeout: 4 }); - - FnConsole.warn("Snapshots, Destroy: Failed, Pool: " + pool.name + ", Snapshot: " + snapshot.name + ", Message: " + (process.data ? process.data : process.message)); - - if (display.refresh) { - $("#modal-storagepool-snapshot-destroy-" + snapshot.id).modal("hide"); - - setTimeout(function () { - FnStoragePoolRefresh({ name: pool.name, id: pool.id }, { storagepool: true, filesystems: true, snapshots: true, status: false }); - }, 200); - } -} - -function FnSnapshotRename(pool = { name, id }, snapshot = { name, id, namenew, recursive: false }) { - let process = { - command: [((zfsmanager.user.admin || !zfsmanager.user.name) ? "pkexec" : ""), "/sbin/zfs", "rename", snapshot.name, snapshot.namenew] - }; - let modal = { - hide: true - }; - - if (snapshot.recursive) { - process.command.splice(3, 0, "-r"); - } - - FnConsole.log[1]("Snapshots, Rename: In Progress, Pool: " + pool.name + ", Snapshot: " + snapshot.name); - FnConsole.log[3](FnConsoleCommand({ command: process.command })); - - $("#spinner-storagepool-snapshot-rename-" + snapshot.id + " span").text("Renaming snapshot..."); - - return cockpit.spawn(process.command, { err: "out" }) - .done(function () { - FnDisplayAlert({ status: "success", title: "Snapshot successfully renamed", description: snapshot.name, breakword: false }, { name: "snapshot-rename", id: snapshot.id, timeout: 4 }); - - FnConsole.log[1]("Snapshots, Rename: Success, Pool: " + pool.name + ", Snapshot: " + snapshot.name); - }) - .fail(function (message, data) { - if (/dataset already exists|child dataset already has a snapshot with the new name/gi.test(data)) { - modal.hide = false; - - $("#validationwrapper-storagepool-snapshot-rename-name-" + snapshot.id).addClass("has-error"); - $("#helpblock-storagepool-snapshot-rename-name-" + snapshot.id).addClass("has-error").removeClass("hidden").text("Name already exists."); - $("#input-storagepool-snapshot-rename-name-" + snapshot.id).focus(); - } - - if (!modal.hide) { - $("#spinner-storagepool-snapshot-rename-" + snapshot.id).addClass("hidden"); - $("#spinner-storagepool-snapshot-rename-" + snapshot.id + " span").text(""); - $("#btn-storagepool-snapshot-rename-apply-" + snapshot.id).prop("disabled", false); - } - - FnConsole.warn("Snapshots, Rename: Failed, Pool: " + pool.name + ", Snapshot: " + snapshot.name + ", Message: " + (data ? data : message)); - - if (modal.hide) { - FnDisplayAlert({ status: "danger", title: "Snapshot could not be renamed", description: snapshot.name, breakword: false }, { name: "snapshot-rename", id: snapshot.id, timeout: 4 }); - } - }) - .finally(function () { - if (modal.hide) { - $("#modal-storagepool-snapshot-rename-" + snapshot.id).modal("hide"); - - setTimeout(function () { - FnStoragePoolRefresh({ name: pool.name, id: pool.id }, { storagepool: true, filesystems: true, snapshots: true, status: false }); - }, 200); - } - }); -} - -function FnSnapshotRollBack(pool = { name, id, altroot: false, readonly: false }, snapshot = { name, id, creation, force: false, recursive: false, recursiveall: false }, samba = { restart: false }) { - if (samba.restart) { - FnSambaStop() - .finally(function () { - if (snapshot.recursiveall && zfsmanager.configuration.samba.manage) { - FnSnapshotRollBackSnapshotsGet({ name: pool.name, id: pool.id }, { name: snapshot.name, id: snapshot.id, creation: snapshot.creation }, { name: null, id: null }) - .done(function (data) { - let snapshots = { - id: data.split(/\n/g).filter(v => v), - clones: [] - }; - - if (snapshots.id.length > 0) { - snapshots.id.forEach((_value, _index) => { - _value = _value.split(/\t/g).filter(v => v); - - snapshots.properties = { - clones: (_value[2] ? _value[2].split(",").filter(v => v) : []), - creation: _value[1], - name: _value[0] - }; - - if (snapshots.properties.name != snapshot.name && snapshots.properties.creation > snapshot.creation && snapshots.properties.clones.length > 0) { - snapshots.properties.clones.forEach((_value, _index) => { - snapshots.clones.push(_value); - }); - } - }); - } - - if (snapshots.clones.length > 0) { - $("#spinner-storagepool-snapshot-rollback-" + snapshot.id + " span").text("Retrieving Samba shares..."); - - FnSambaSharesGet({ name: pool.name, id: pool.id }, { name: null, clones: snapshots.clones }) - .done(function (_data) { - FnConsole.log[4](FnConsoleVerbose({ data: _data, message: "Samba, Shares, Get:" })); - - let filesystems = { - id: _data.split(/\n/g).filter(v => v && /\ton$/i.test(v)) - }; - - $("#spinner-storagepool-snapshot-rollback-" + snapshot.id + " span").text("Rolling back snapshot..."); - - if (filesystems.id.length > 0) { - FnSnapshotRollBackCommand({ name: pool.name, id: pool.id }, { name: snapshot.name, id: snapshot.id, force: snapshot.force, recursive: snapshot.recursive, recursiveall: snapshot.recursiveall }, { refresh: false }) - .done(function () { - $("#spinner-storagepool-snapshot-rollback-" + snapshot.id + " span").text("Destroying Samba shares..."); - - FnSambaSharesDestroy({ name: pool.name, id: pool.id, altroot: pool.altroot, readonly: false }, { id: filesystems.id }, { restart: samba.restart }, { silent: false }) - .finally(function () { - $("#modal-storagepool-snapshot-rollback-" + snapshot.id).modal("hide"); - - setTimeout(function () { - FnStoragePoolRefresh({ name: pool.name, id: pool.id }, { storagepool: true, filesystems: true, snapshots: true, status: false }); - }, 200); - }); - }); - } else { - $("#spinner-storagepool-snapshot-rollback-" + snapshot.id + " span").text("Rolling back snapshot..."); - - FnSnapshotRollBackCommand({ name: pool.name, id: pool.id }, { name: snapshot.name, id: snapshot.id, force: snapshot.force, recursive: snapshot.recursive, recursiveall: snapshot.recursiveall }, { refresh: true }) - .finally(function () { - FnSambaStart(); - }); - } - }) - .fail(function (_message, _data) { - FnSnapshotRollBackCommandFail({ name: pool.name, id: pool.id }, { name: snapshot.name, id: snapshot.id }, { data: _data, message: _message }, { refresh: true }); - FnSambaStart(); - }); - } else { - $("#spinner-storagepool-snapshot-rollback-" + snapshot.id + " span").text("Rolling back snapshot..."); - - FnSnapshotRollBackCommand({ name: pool.name, id: pool.id }, { name: snapshot.name, id: snapshot.id, force: snapshot.force, recursive: snapshot.recursive, recursiveall: snapshot.recursiveall }, { refresh: true }) - .finally(function () { - FnSambaStart(); - }); - } - }); - } else { - $("#spinner-storagepool-snapshot-rollback-" + snapshot.id + " span").text("Rolling back snapshot..."); - - FnSnapshotRollBackCommand({ name: pool.name, id: pool.id }, { name: snapshot.name, id: snapshot.id, force: snapshot.force, recursive: snapshot.recursive, recursiveall: snapshot.recursiveall }, { refresh: true }) - .finally(function () { - FnSambaStart(); - }); - } - }); - } else { - if (snapshot.recursiveall && zfsmanager.configuration.samba.manage) { - FnSnapshotRollBackSnapshotsGet({ name: pool.name, id: pool.id }, { name: snapshot.name, id: snapshot.id, creation: snapshot.creation }, { name: null, id: null }) - .done(function (data) { - let snapshots = { - id: data.split(/\n/g).filter(v => v), - clones: [] - }; - - if (snapshots.id.length > 0) { - snapshots.id.forEach((_value, _index) => { - _value = _value.split(/\t/g).filter(v => v); - - snapshots.properties = { - clones: (_value[2] ? _value[2].split(",").filter(v => v) : []), - creation: _value[1], - name: _value[0] - }; - - if (snapshots.properties.name != snapshot.name && snapshots.properties.creation > snapshot.creation && snapshots.properties.clones.length > 0) { - snapshots.properties.clones.forEach((_value, _index) => { - snapshots.clones.push(_value); - }); - } - }); - } - - if (snapshots.clones.length > 0) { - $("#spinner-storagepool-snapshot-rollback-" + snapshot.id + " span").text("Retrieving Samba shares..."); - - FnSambaSharesGet({ name: pool.name, id: pool.id }, { name: null, clones: snapshots.clones }) - .done(function (_data) { - FnConsole.log[4](FnConsoleVerbose({ data: _data, message: "Samba, Shares, Get:" })); - - let filesystems = { - id: _data.split(/\n/g).filter(v => v && /\ton$/i.test(v)) - }; - - $("#spinner-storagepool-snapshot-rollback-" + snapshot.id + " span").text("Rolling back snapshot..."); - - if (filesystems.id.length > 0) { - FnSnapshotRollBackCommand({ name: pool.name, id: pool.id }, { name: snapshot.name, id: snapshot.id, force: snapshot.force, recursive: snapshot.recursive, recursiveall: snapshot.recursiveall }, { refresh: false }) - .done(function () { - $("#spinner-storagepool-snapshot-rollback-" + snapshot.id + " span").text("Destroying Samba shares..."); - - FnSambaSharesDestroy({ name: pool.name, id: pool.id, altroot: pool.altroot, readonly: false }, { id: filesystems.id }, { restart: samba.restart }, { silent: false }) - .finally(function () { - $("#modal-storagepool-snapshot-rollback-" + snapshot.id).modal("hide"); - - setTimeout(function () { - FnStoragePoolRefresh({ name: pool.name, id: pool.id }, { storagepool: true, filesystems: true, snapshots: true, status: false }); - }, 200); - }); - }); - } else { - $("#spinner-storagepool-snapshot-rollback-" + snapshot.id + " span").text("Rolling back snapshot..."); - - FnSnapshotRollBackCommand({ name: pool.name, id: pool.id }, { name: snapshot.name, id: snapshot.id, force: snapshot.force, recursive: snapshot.recursive, recursiveall: snapshot.recursiveall }, { refresh: true }); - } - }) - .fail(function (_message, _data) { - FnSnapshotRollBackCommandFail({ name: pool.name, id: pool.id }, { name: snapshot.name, id: snapshot.id }, { data: _data, message: _message }, { refresh: true }); - }); - } else { - $("#spinner-storagepool-snapshot-rollback-" + snapshot.id + " span").text("Rolling back snapshot..."); - - FnSnapshotRollBackCommand({ name: pool.name, id: pool.id }, { name: snapshot.name, id: snapshot.id, force: snapshot.force, recursive: snapshot.recursive, recursiveall: snapshot.recursiveall }, { refresh: true }); - } - }); - } else { - $("#spinner-storagepool-snapshot-rollback-" + snapshot.id + " span").text("Rolling back snapshot..."); - - FnSnapshotRollBackCommand({ name: pool.name, id: pool.id }, { name: snapshot.name, id: snapshot.id, force: snapshot.force, recursive: snapshot.recursive, recursiveall: snapshot.recursiveall }, { refresh: true }); - } - } -} - -function FnSnapshotRollBackCommand(pool = { name, id }, snapshot = { name, id, force: false, recursive: false, recursiveall: false }, display = { refresh: true }) { - let process = { - command: [((zfsmanager.user.admin || !zfsmanager.user.name) ? "pkexec" : ""), "/sbin/zfs", "rollback", snapshot.name] - }; - - if (snapshot.force) { - process.command.splice(3, 0, "-f"); - } - if (snapshot.recursive) { - process.command.splice(3, 0, "-r"); - } - if (snapshot.recursiveall) { - process.command.splice(3, 0, "-R"); - } - - FnConsole.log[1]("Snapshots, Roll Back: In Progress, Pool: " + pool.name + ", Snapshot: " + snapshot.name); - FnConsole.log[3](FnConsoleCommand({ command: process.command })); - - return cockpit.spawn(process.command, { err: "out" }) - .done(function () { - FnDisplayAlert({ status: "success", title: "Snapshot successfully rolled back", description: snapshot.name, breakword: false }, { name: "snapshot-rollback", id: snapshot.id, timeout: 4 }); - - FnConsole.log[1]("Snapshots, Roll Back: Success, Pool: " + pool.name + ", Snapshot: " + snapshot.name); - }) - .fail(function (message, data) { - FnSnapshotRollBackCommandFail({ name: pool.name, id: pool.id }, { name: snapshot.name, id: snapshot.id }, { data: data, message: message }, { refresh: false }); - - display.refresh = true; - }) - .finally(function () { - if (display.refresh) { - $("#modal-storagepool-snapshot-rollback-" + snapshot.id).modal("hide"); - - setTimeout(function () { - FnStoragePoolRefresh({ name: pool.name, id: pool.id }, { storagepool: true, filesystems: true, snapshots: true, status: false }); - }, 200); - } - }); -} - -function FnSnapshotRollBackCommandFail(pool = { name, id }, snapshot = { name, id }, process = { data, message }, display = { refresh: true }) { - FnDisplayAlert({ status: "danger", title: "Snapshot could not be rolled back", description: snapshot.name, breakword: false }, { name: "snapshot-rollback", id: snapshot.id, timeout: 4 }); - - FnConsole.warn("Snapshots, Roll Back: Failed, Pool: " + pool.name + ", Snapshot: " + snapshot.name + ", Message: " + (process.data ? process.data : process.message)); - - if (display.refresh) { - $("#modal-storagepool-snapshot-rollback-" + snapshot.id).modal("hide"); - - setTimeout(function () { - FnStoragePoolRefresh({ name: pool.name, id: pool.id }, { storagepool: true, filesystems: true, snapshots: true, status: false }); - }, 200); - } -} - -function FnSnapshotRollBackSnapshotsGet(pool = { name, id }, snapshot = { name, id, creation }, modal = { name, id }) { - let process = { - command: ["/sbin/zfs", "list", "-H", "-o", "name,creation,clones", "-p", "-t", "snapshot"] - }; - - process.command.push(snapshot.name.replace(/^(.*)\@.*$/, "$1")); - - FnConsole.log[2]("Snapshots, Roll Back, Snapshots, Get: In Progress, Pool: " + pool.name + ", Snapshot: " + snapshot.name); - FnConsole.log[3](FnConsoleCommand({ command: process.command })); - - return cockpit.spawn(process.command, { err: "out" }) - .done(function (data) { - FnConsole.log[4](FnConsoleVerbose({ data: data, message: "Snapshots, Roll Back, Snapshots, Get:" })); - - if (modal.name && modal.id) { - let snapshots = { - id: data.split(/\n/g).filter(v => v), - clones: [], - count: { - snapshots: 0, - snapshotswithclones: 0 - } - }; - - if (snapshots.id.length > 0) { - snapshots.id.forEach((_value, _index) => { - _value = _value.split(/\t/g).filter(v => v); - - snapshots.properties = { - clones: (_value[2] ? _value[2].split(",").filter(v => v) : []), - creation: _value[1], - name: _value[0] - }; - - if (snapshots.properties.name != snapshot.name && snapshots.properties.creation > snapshot.creation) { - snapshots.count.snapshots++; - snapshots.count.snapshotswithclones++; - - if (snapshots.properties.clones.length > 0) { - snapshots.properties.clones.forEach((_value, _index) => { - snapshots.clones.push(_value); - }); - } - - $("#ul-" + modal.name + "-snapshots-" + modal.id).append("
  • " + snapshots.properties.name + "
  • \n"); - $("#ul-" + modal.name + "-child-snapshotswithclones-" + modal.id).append("
  • " + snapshots.properties.name + "
  • \n"); - } - }); - - $("#panelgroup-" + modal.name + "-" + modal.id).attr("data-snapshot-snapshots", snapshots.count.snapshots); - $("#panelgroup-" + modal.name + "-" + modal.id).attr("data-snapshot-child-snapshotswithclones", snapshots.count.snapshotswithclones); - } - - if (snapshots.clones.length > 0) { - FnSnapshotChildFileSystemsGet({ name: pool.name, id: pool.id }, { name: snapshot.name, id: snapshot.id }, filesystems = { id: snapshots.clones }, { name: modal.name, id: modal.id }); - FnSnapshotChildSnapshotsGet({ name: pool.name, id: pool.id }, { name: snapshot.name, id: snapshot.id, exclude: true }, { id: snapshots.clones }, { name: modal.name, id: modal.id }); - } - } - - FnConsole.log[1]("Snapshots, Roll Back, Snapshots, Get: Success, Pool: " + pool.name + ", Snapshot: " + snapshot.name); - }) - .fail(function (message, data) { - FnConsole.warn("Snapshots, Roll Back, Snapshots, Get: Failed, Pool: " + pool.name + ", Snapshot: " + snapshot.name + ", Message: " + (data ? data : message)); - }); -} - -//#endregion - -//#region Status - -function FnStatusErrorColors(status = { count }) { - if (!$.isNumeric(status.count)) { - return status.count; - } - - if (status.count >= 5 && status.count <= 20) { - return (`` + status.count + ``); - } else if (status.count >= 21) { - return (`` + status.count + ``); - } else { - return status.count; - } -} - -function FnStatusGet(pool = { name, id }) { - let process = { - command: ["/bin/sh", "-c", ((zfsmanager.user.name == "root" || !zfsmanager.user.name) ? "ZPOOL_SCRIPTS_AS_ROOT=1 " : "") + `/sbin/zpool status -p -t -c upath "` + pool.name + `"`] - }; - - pool.autotrim = ($("#tr-storagepool-" + pool.id).attr("data-pool-autotrim") == "true" ? true : false); - pool.boot = ($("#tr-storagepool-" + pool.id).attr("data-pool-boot") == "true" ? true : false); - pool.feature = { - allocation_classes: ($("#tr-storagepool-" + pool.id).attr("data-pool-feature-allocation_classes") == "true" ? true : false), - device_removal: ($("#tr-storagepool-" + pool.id).attr("data-pool-feature-device_removal") == "true" ? true : false), - resilver_defer: ($("#tr-storagepool-" + pool.id).attr("data-pool-feature-resilver_defer") == "true" ? true : false) - }; - pool.guid = $("#tr-storagepool-" + pool.id).attr("data-pool-guid"); - pool.readonly = ($("#tr-storagepool-" + pool.id).attr("data-pool-readonly") == "true" ? true : false); - pool.root = ($("#tr-storagepool-" + pool.id).attr("data-pool-root") == "true" ? true : false); - pool.status = { - empty: true - }; - pool.upgrade = ($("#tr-storagepool-" + pool.id).attr("data-pool-upgrade") == "true" ? true : false); - pool.version = $("#tr-storagepool-" + pool.id).attr("data-pool-version"); - - FnConsole.log[2]("Status, Get: In Progress, Pool: " + pool.name); - FnConsole.log[3](FnConsoleCommand({ command: process.command })); - - return cockpit.spawn(process.command, { err: "out" }) - .done(function (data, message) { - FnConsole.log[4](FnConsoleVerbose({ data: data, message: "Status, Get:" })); - - FnDisksLsblkGet({ sizeraw: true }) - .done(function (_data) { - FnConsole.log[4](FnConsoleVerbose({ data: _data, message: "Disks, Lsblk, Get:" })); - - if (data) { - pool.status.empty = false; - - let disks = { - lsblkjson: JSON.parse(_data) - }; - - FnStatusGetCommand({ name: pool.name, id: pool.id, autotrim: pool.autotrim, boot: pool.boot, feature: { allocation_classes: pool.feature.allocation_classes, device_removal: pool.feature.device_removal, resilver_defer: pool.feature.resilver_defer }, guid: pool.guid, readonly: pool.readonly, root: pool.root, upgrade: pool.upgrade, version: pool.version }, { lsblk: disks.lsblkjson }, { data: data, message: message }); - } - - FnConsole.log[1]("Status, Get: Success, Pool: " + pool.name); - - if (pool.status.empty) { - $("#tbody-storagepool-status-messages-" + pool.id).empty(); - $("#tbody-storagepool-status-config-" + pool.id).empty(); - $("#tbody-storagepool-status-messages-" + pool.id).append(`Status not available`); - $("#modals-storagepool-status-" + pool.id).remove(); - $("#dynamics-storagepool-status-" + pool.id).remove(); - - $("#tr-storagepool-" + pool.id).attr("data-pool-refresh-status", "true"); - - $("#spinner-storagepool-status-" + pool.id).addClass("hidden"); - $("#paneltitle-storagepool-status-" + pool.id).removeClass("hidden").text(FnDateTime()); - $("#btn-storagepool-status-refresh-" + pool.id).prop("disabled", false); - $("#btn-storagepool-status-refresh-auto-" + pool.id).prop("disabled", false); - } - - FnStoragePoolSpinnerHide({ name: pool.name, id: pool.id }); - FnCockpitElementsUpdate(); - }) - .fail(function (_message, _data) { - FnConsole.warn("Status, Get: Failed, Pool: " + pool.name + ", Message: " + (_data ? _data : _message)); - - FnStatusGetFail({ name: pool.name, id: pool.id, status: { empty: pool.status.empty } }); - }); - }) - .fail(function (message, data) { - FnConsole.warn("Status, Get: Failed, Pool: " + pool.name + ", Message: " + (data ? data : message)); - - FnStatusGetFail({ name: pool.name, id: pool.id, status: { empty: pool.status.empty } }); - }); -} - -function FnStatusGetCommand(pool = { name, id, autotrim: false, boot: false, feature: { allocation_classes: true, device_removal: true, resilver_defer: true }, guid, readonly: false, root: false, upgrade: false, version }, disks = { lsblk: {} }, process = { data, message }) { - process.data = process.data.replace(/\n\t+/g, "[TAB1]").split(/\n/g).filter(v => v); //Replace new line with [TAB1] for multi line messages and config - - pool.status = { - state: "", - status: "", - action: "", - see: "", - scan: "", - remove: "", - memory: "", - errors: "", - upgrade: false, - resilver: { - started: false - }, - scrub: { - started: false, - paused: false - }, - trim: { - started: false, - suspended: false - }, - disks: { - count: 0, - ssd: false, - trim: { - unsupportedcount: 0 - } - }, - config: { - items: [], - regexp: {}, - replacement: {}, - tier: { - count: 0, - nametier0: "", - nametier1: "", - nametier2: "", - nametier3: "" - }, - virtualdevice: { - count: 0 - } - } - }; - - $("#modals-storagepool-status-" + pool.id).remove(); - $("#modals").append(`
    `); - $("#dynamics-storagepool-status-" + pool.id).remove(); - $("#dynamics").append(`
    `); - - pool.status.output = `Pool: ` + pool.name + ``; - - process.data.forEach((_value, _index) => { - if (/^(?: )+pool:/g.test(_value)) { - _value = ""; - } - if (/^(?: )+state:/g.test(_value)) { - pool.status.state = _value.replace(/\[TAB1\]/g, " ").replace(/^(?: )+state:/g, "").trim(); - _value = ""; - - pool.status.output += `State: ` + (pool.status.state ? ` ` + pool.status.state : ``) + ``; - } - if (/^status:/g.test(_value)) { - pool.status.status = _value.replace(/\[TAB1\]/g, " ").replace(/^status:/g, "").trim(); - _value = ""; - - if (/currently being resilvered/gi.test(pool.status.status)) { - pool.status.resilver.started = true; - } - - pool.status.output += `Status: ` + pool.status.status + ``; - } - if (/^action:/g.test(_value)) { - pool.status.action = _value.replace(/\[TAB1\]/g, " ").replace(/^action:/g, "").trim(); - pool.status.upgrade = ((pool.upgrade || /Upgrade the pool|zpool upgrade/gi.test(pool.status.action)) && !pool.boot ? true : false); - _value = ""; - - if (/Upgrade the pool|zpool upgrade/gi.test(pool.status.action) && !pool.boot) { //Hide upgrade message for boot pool. Upgrading version may cause an unbootable system - pool.status.output += `Action: ` + pool.status.action + ``; - } - } - if (/^(?: )+see:/g.test(_value)) { - pool.status.see = _value.replace(/\[TAB1\]/g, " ").replace(/^(?: )+see:(?: )+/g, "").trim(); - _value = ""; - - if (/http/g.test(pool.status.see)) { - pool.status.see = `` + pool.status.see + ``; - } - - pool.status.output += `See: ` + pool.status.see + ``; - } - if (/^(?: )+scan:/g.test(_value)) { - pool.status.scan = _value.replace(/\[TAB1\]/g, " ").replace(/^(?: )+scan:/g, "").trim(); - _value = ""; - - if (/scrub in progress/gi.test(pool.status.scan)) { - pool.status.scrub.started = true; - } else if (/scrub paused/gi.test(pool.status.scan)) { - pool.status.scrub.paused = true; - } - - if (/resilver in progress/gi.test(pool.status.scan)) { - pool.status.resilver.started = true; - } - - pool.status.output += `Scan: ` + pool.status.scan + ``; - } - if (/^remove:/g.test(_value)) { - pool.status.remove = _value.replace(/\[TAB1\]/g, " ").replace(/^remove:/g, "").trim(); - _value = ""; - - pool.status.output += `Remove: ` + pool.status.remove + ``; - } - if (/memory used for/g.test(_value)) { - pool.status.memory = ". " + _value.replace(/\[TAB1\]/g, " ").trim(); - _value = ""; - } - if (/^config:/g.test(_value)) { - _value = ""; - } - if (/^errors:/g.test(_value)) { - pool.status.errors = _value.replace(/\[TAB1\]/g, " ").replace(/^errors:/g, "").trim(); - _value = ""; - - pool.status.output += `Errors: ` + pool.status.errors + ``; - } - if (/\[TAB1\]NAME/g.test(_value)) { //Config header row - _value = _value.split("upath").slice(1).join("."); //Remove config header row (and any previous text if exists) - - pool.status.config.regexp.tabspace = new RegExp("^\\[TAB1\\]" + pool.name); - - if (pool.status.config.regexp.tabspace.test(_value)) { //Confirm config rows - pool.status.config.items = _value.split("[TAB1]").filter(v => v); - } - - if (/trimmed, started|trimmed started/i.test(pool.status.config.items.join(" "))) { //Storage pool contains a disk with TRIM started - pool.status.trim.started = true; - } else if (/trimmed, suspended|trimmed suspended/i.test(pool.status.config.items.join(" "))) { //Storage pool contains a disk with TRIM suspended - pool.status.trim.suspended = true; - } - } - }); - - pool.status.output += ``; - pool.status.output += ``; - - $("#tbody-storagepool-status-messages-" + pool.id).html(pool.status.output); - $("#td-storagepool-status-messages-remove-" + pool.id).append(pool.status.memory); - - pool.status.config.output = ` - - Name - State - Read - Write - Checksum - Message - Product - - - - `; - - $("#tbody-storagepool-status-config-" + pool.id).html(pool.status.config.output); - - pool.status.config.items.forEach((_value, _index) => { - pool.status.config.disk = false; - pool.status.config.tier.level = (_value.match(/^\s*/g)[0].length / 2); - pool.status.config.tier.cache = false; - pool.status.config.tier.dedup = false; - pool.status.config.tier.logs = false; - pool.status.config.tier.pool = false; - pool.status.config.tier.spares = false; - pool.status.config.tier.special = false; - pool.status.config.tier.replacing = false; - pool.status.config.output = ""; - - pool.status.disks.disk = { - ssd: false, - trim: { - started: false, - suspended: false, - unsupported: false - }, - replacing: false, - messages: [], - upath: "" - } - - if (_index == 0 && /[ ]/g.test(pool.name)) { //Fix for storage pool name if it contains whitespace - pool.status.config.regexp.poolname = new RegExp("^" + pool.name, "g"); - _value = _value.replace(pool.status.config.regexp.poolname, "[POOLNAME]"); - } - - _value = _value.replace(/ +/g, "\u22C5").replace(/^\u22C5/, "").split("\u22C5").filter(v => v); - - if (_index == 0 && _value[0] == "[POOLNAME]") { - _value[0] = pool.name; - } - - switch (pool.status.config.tier.level) { - case 0: //Pool / Cache / Dedup / Log / Spares / Special tier - pool.status.config.tier.nametier0 = _value[0].trim(); - break; - case 1: //Virtual device tier - pool.status.config.tier.nametier1 = _value[0]; - - if (pool.status.config.tier.nametier0 == pool.name) { - pool.status.config.virtualdevice.count++; - } - break; - case 2: //Drive tier - pool.status.config.tier.nametier2 = _value[0]; - break; - case 3: //Action tier - pool.status.config.tier.nametier3 = _value[0]; - break; - case 4: //Action Drive tier - break; - } - - if (pool.status.config.tier.level == 0) { //1= Pool, 2+= / Cache / Dedup / Log / Spares / Special - pool.status.config.tier.count++; - } - - if (pool.status.config.tier.level > 0) { - if (pool.status.config.tier.nametier0 == pool.name && pool.status.config.tier.count == 1) { //Virtual Device / Disk is member of pool - pool.status.config.tier.pool = true; - } - if (/^cache/g.test(pool.status.config.tier.nametier0) && pool.status.config.tier.count > 1) { //Virtual Device / Disk is member of cache - pool.status.config.tier.cache = true; - } - if (/^dedup/g.test(pool.status.config.tier.nametier0) && pool.status.config.tier.count > 1) { //Virtual Device / Disk is member of dedup - pool.status.config.tier.dedup = true; - } - if (/^logs/g.test(pool.status.config.tier.nametier0) && pool.status.config.tier.count > 1) { //Virtual Device / Disk is member of logs - pool.status.config.tier.logs = true; - } - if (/^spares/g.test(pool.status.config.tier.nametier0) && pool.status.config.tier.count > 1) { //Virtual Device / Disk is member of spares - pool.status.config.tier.spares = true; - } - if (/^special/g.test(pool.status.config.tier.nametier0) && pool.status.config.tier.count > 1) { //Virtual Device / Disk is member of special - pool.status.config.tier.special = true; - } - } - - pool.status.config.tier.virtualdevice = ((pool.status.config.tier.level == 0 && /^cache|^dedup|^logs|^spares|^special/g.test(pool.status.config.tier.nametier0) && pool.status.config.tier.count > 1) ? true : false); - - if (pool.status.config.tier.level == 0 && /^special/g.test(pool.status.config.tier.nametier0) && pool.status.config.tier.count > 1) { - $("#tr-storagepool-" + pool.id).attr("data-pool-special", true); - } - - if (/^\/dev\/nvme|^\/dev\/sd/gi.test(_value[5])) { //upath - pool.status.disks.disk.upath = _value[5]; - _value[5] = ""; - } else if ($.isNumeric(_value[0]) && _value[5] == "was") { //upath appears after was device path message - pool.status.disks.disk.upath = _value[7]; - _value[7] = ""; - } else if (!$.isNumeric(_value[0]) && _value[5] != "was") { //upath appears after error messages and before trim messages - for (let i = 5; i < _value.length; i++) { //Collect messages - if (/^\/dev\/nvme|^\/dev\/sd/gi.test(_value[i])) { - pool.status.disks.disk.upath = _value[i]; - _value[i] = ""; - } - } - } - - if ((/^\/dev\/nvme|^\/dev\/sd/gi.test(pool.status.disks.disk.upath) || /^nvme-nvme/gi.test(_value[0]) || /^wwn-/gi.test(_value[0]) || $.isNumeric(_value[0])) && pool.status.config.tier.level > 0) { - pool.status.config.disk = true; - pool.status.disks.count++; - } - - if (pool.status.config.disk && (pool.status.config.tier.level == 2 && /^replacing-/g.test(pool.status.config.tier.nametier1) || pool.status.config.tier.level == 3 && /^replacing-/g.test(pool.status.config.tier.nametier2) || pool.status.config.tier.level == 4 && /^replacing-/g.test(pool.status.config.tier.nametier3))) { - pool.status.disks.disk.replacing = true; - } - - if (pool.status.config.tier.level > 0 && /^replacing-/g.test(_value[0])) { - pool.status.config.tier.replacing = true; - } - - pool.status.config.output += ``; - pool.status.config.output += `` + (pool.status.config.tier.level == 0 && pool.status.config.tier.count == 1 && _value[0] == pool.name ? `Pool` : (pool.status.config.disk ? `Disk` : `Virtual Device`)) + `:` + _value[0] + ``; //Pool / Virtual Device / Disk - pool.status.config.output += `State:` + (_value[1] ? ` ` + _value[1] : ``) + ``; //State - - if (_value[2] && /^spares/g.test(pool.status.config.tier.nametier0)) { //Read - pool.status.disks.disk.messages.push(_value[2]); - - pool.status.config.output += ``; - } else { - pool.status.config.output += `` + (_value[2] ? `Read:` + (zfsmanager.configuration.zfs.status.errorcolors ? FnStatusErrorColors({ count: _value[2] }) : _value[2]) : ``) + ``; - } - - if (_value[3] && /^spares/g.test(pool.status.config.tier.nametier0)) { //Write - pool.status.disks.disk.messages.push(_value[3]); - - pool.status.config.output += ``; - } else { - pool.status.config.output += `` + (_value[3] ? `Write:` + (zfsmanager.configuration.zfs.status.errorcolors ? FnStatusErrorColors({ count: _value[3] }) : _value[3]) : ``) + ``; - } - - if (/^spares/g.test(pool.status.config.tier.nametier0)) { //Checksum - if (_value[4]) { - pool.status.disks.disk.messages.push(_value[4]); - } - - pool.status.config.output += ``; - } else { - pool.status.config.output += `` + (_value[4] ? `Checksum:` + (zfsmanager.configuration.zfs.status.errorcolors ? FnStatusErrorColors({ count: _value[4] }) : _value[4]) : ``) + ``; - } - - for (let i = 5; i < _value.length; i++) { //Collect messages - if (_value[i]) { - pool.status.disks.disk.messages.push(_value[i]); - } - } - - pool.status.disks.disk.messages = pool.status.disks.disk.messages.join(" "); //Join Messages for output - - if (pool.status.config.disk && /\(trim unsupported\)/gi.test(pool.status.disks.disk.messages)) { - pool.status.disks.disk.trim.unsupported = true; - pool.status.disks.trim.unsupportedcount++; - } - - if (!zfsmanager.configuration.zfs.status.trimunsupported) { - pool.status.disks.disk.messages = pool.status.disks.disk.messages.replace(/\(trim unsupported\)/gi, ""); - } - if (pool.status.config.tier.cache || pool.status.config.tier.spares) { //Cache and spare disks can not be trimmed - pool.status.disks.disk.messages = pool.status.disks.disk.messages.replace(/\(untrimmed\)/gi, ""); - } - - pool.status.config.replacement.messages = [ - { pattern: /^\(/g, replacement: "" }, - { pattern: /\)$/g, replacement: "" }, - { pattern: / \(/g, replacement: ", " }, - { pattern: /\),/g, replacement: "," }, - { pattern: /\) /g, replacement: " " } - ]; - - pool.status.config.output += `Message:` + pool.status.config.replacement.messages.reduce((m, r) => m.replace(r.pattern, r.replacement), pool.status.disks.disk.messages) + ``; //Message - - if (pool.status.config.disk) { - if (/trimmed, started|trimmed started/i.test(pool.status.disks.disk.messages)) { - pool.status.disks.disk.trim.started = true; - - if (!pool.status.trim.started) { //Storage pool contains a disk with TRIM started - pool.status.trim.started = true; - } - } else if (/trimmed, suspended|trimmed suspended/i.test(pool.status.disks.disk.messages)) { - pool.status.disks.disk.trim.suspended = true; - - if (!pool.status.trim.suspended) { //Storage pool contains a disk with TRIM suspended - pool.status.trim.suspended = true; - } - } - } - - pool.status.config.output += `Product:`; //Product - - if (pool.status.config.disk) { - disks.lsblk.blockdevices.forEach((__value, __index) => { - if (__value.type == "disk") { - if (pool.status.disks.disk.upath.replace(/^\/dev\//gi, "") == __value.name || "nvme-" + __value.wwn == _value[0] || "wwn-" + __value.wwn == _value[0]) { - if (__value.rota == 0 || __value.rota === "false") { - pool.status.disks.disk.ssd = true; - - if (!pool.status.ssd) { //Storage pool contains an SSD - pool.status.disks.ssd = true; - } - } - - pool.status.config.output += FnFormatBytes({ base2: zfsmanager.configuration.disks.base2, decimals: 2, value: __value.size }) + " " + __value.model + (__value.serial ? " (" + __value.serial + ")" : ""); - } - } - }); - } - - pool.status.config.output += ``; - - //Actions Menu - pool.status.config.actionsmenu = { - items: { - storagepool: [], - storagepooldivider: function () { - if (this.storagepool.length > 0 && (this.virtualdevice.length > 0 || this.disk.length > 0)) { - this.storagepool.push(this.divider); - } - }, - virtualdevice: [], - virtualdevicedivider: function () { - if (this.virtualdevice.length > 0 && this.disk.length > 0) { - this.virtualdevice.push(this.divider); - } - }, - disk: [], - divider: `` - }, - display: function () { - if ((this.items.virtualdevice.length + this.items.virtualdevice.length + this.items.disk.length) > 0 || pool.readonly) { - this.items.storagepooldivider(); - this.items.virtualdevicedivider(); - return this.header + this.items.storagepool.join("\n") + this.items.virtualdevice.join("\n") + this.items.disk.join("\n") + this.footer; - } else { - return ""; - } - } - } - pool.status.config.actionsmenu.header = ` - - `; - pool.status.config.actionsmenu.register = { - storagepool: { - scrub: {}, - trim: {} - }, - virtualdevice: {}, - disk: { - trim: {} - } - }; - - //Clear storage pool errors - if (!pool.readonly && pool.status.config.tier.level == 0 && pool.status.config.tier.count == 1 && _value[0] == pool.name) { - pool.status.config.actionsmenu.items.storagepool.push(`
  • Clear Storage Pool Errors
  • `); - - pool.status.config.actionsmenu.register.storagepool.clear = true; - } - - //Resilver Storage Pool - if (!pool.readonly && pool.status.config.tier.level == 0 && pool.status.config.tier.count == 1 && _value[0] == pool.name && pool.feature.resilver_defer) { - pool.status.config.actionsmenu.items.storagepool.push(`
  • Resilver Storage Pool
  • `); - - pool.status.config.actionsmenu.register.storagepool.resilver = true; - } - - //Start Storage Pool Scrub - if (!pool.readonly && pool.status.config.tier.level == 0 && pool.status.config.tier.count == 1 && _value[0] == pool.name && !pool.status.scrub.started && !pool.status.scrub.paused) { - pool.status.config.actionsmenu.items.storagepool.push(`
  • Scrub Storage Pool
  • `); - - pool.status.config.actionsmenu.register.storagepool.scrub.start = true; - } - - //Resume Storage Pool Scrub - if (!pool.readonly && pool.status.config.tier.level == 0 && pool.status.config.tier.count == 1 && _value[0] == pool.name && pool.status.scrub.paused) { - pool.status.config.actionsmenu.items.storagepool.push(`
  • Resume Storage Pool Scrub
  • `); - - pool.status.config.actionsmenu.register.storagepool.scrub.resume = true; - } - - //Pause Storage Pool Scrub - if (!pool.readonly && pool.status.config.tier.level == 0 && pool.status.config.tier.count == 1 && _value[0] == pool.name && pool.status.scrub.started) { - pool.status.config.actionsmenu.items.storagepool.push(`
  • Pause Storage Pool Scrub
  • `); - - pool.status.config.actionsmenu.register.storagepool.scrub.pause = true; - } - - //Stop Storage Pool Scrub - if (!pool.readonly && pool.status.config.tier.level == 0 && pool.status.config.tier.count == 1 && _value[0] == pool.name && (pool.status.scrub.started || pool.status.scrub.paused)) { - pool.status.config.actionsmenu.items.storagepool.push(`
  • Stop Storage Pool Scrub
  • `); - - pool.status.config.actionsmenu.register.storagepool.scrub.stop = true; - } - - //TRIM Storage Pool - if (!pool.readonly && pool.status.config.tier.level == 0 && pool.status.config.tier.count == 1 && _value[0] == pool.name && !pool.status.trim.started && !pool.status.trim.suspended) { - pool.status.config.actionsmenu.items.storagepool.push(`
  • TRIM Storage Pool
  • `); - - pool.status.config.actionsmenu.register.storagepool.trim.start = true; - } - - //Resume Storage Pool TRIM - if (!pool.readonly && pool.status.config.tier.level == 0 && pool.status.config.tier.count == 1 && _value[0] == pool.name && pool.status.trim.suspended) { - pool.status.config.actionsmenu.items.storagepool.push(`
  • Resume Storage Pool TRIM
  • `); - - pool.status.config.actionsmenu.register.storagepool.trim.resume = true; - } - - //Suspend Storage Pool TRIM - if (!pool.readonly && pool.status.config.tier.level == 0 && pool.status.config.tier.count == 1 && _value[0] == pool.name && pool.status.trim.started) { - pool.status.config.actionsmenu.items.storagepool.push(`
  • Suspend Storage Pool TRIM
  • `); - - pool.status.config.actionsmenu.register.storagepool.trim.suspend = true; - } - - //Cancel Storage Pool TRIM - if (!pool.readonly && pool.status.config.tier.level == 0 && pool.status.config.tier.count == 1 && _value[0] == pool.name && (pool.status.trim.started || pool.status.trim.suspended)) { - pool.status.config.actionsmenu.items.storagepool.push(`
  • Cancel Storage Pool TRIM
  • `); - - pool.status.config.actionsmenu.register.storagepool.trim.cancel = true; - } - - //Upgrade Storage Pool - if (!pool.readonly && pool.status.config.tier.level == 0 && pool.status.config.tier.count == 1 && _value[0] == pool.name && pool.status.upgrade) { - pool.status.config.actionsmenu.items.storagepool.push(`
  • Upgrade Storage Pool
  • `); - - pool.status.config.actionsmenu.register.storagepool.upgrade = true; - } - - //Regenerate Storage Pool GUID - if (!pool.readonly && pool.status.config.tier.level == 0 && pool.status.config.tier.count == 1 && _value[0] == pool.name) { - pool.status.config.actionsmenu.items.storagepool.push(`
  • Regenerate Storage Pool GUID
  • `); - - pool.status.config.actionsmenu.register.storagepool.regenerateguid = true; - } - - //Clear Virtual Device Errors - if (!pool.readonly && pool.status.config.tier.level > 0 && !pool.status.config.disk) { - pool.status.config.actionsmenu.items.virtualdevice.push(`
  • Clear Virtual Device Errors
  • `); - - pool.status.config.actionsmenu.register.virtualdevice.clear = true; - } - - //Add Virtual Device - if (!pool.readonly && pool.status.config.tier.level == 0 && pool.status.config.tier.count == 1 && _value[0] == pool.name) { - pool.status.config.actionsmenu.items.virtualdevice.push(`
  • Add Virtual Device
  • `); - - pool.status.config.actionsmenu.register.virtualdevice.add = true; - } - - //Remove Virtual Device - if (!pool.readonly && pool.status.config.tier.level == 1 && !pool.status.config.tier.replacing && (pool.feature.device_removal || pool.status.config.tier.spares)) { - pool.status.config.actionsmenu.items.virtualdevice.push(`
  • Remove Virtual Device
  • `); - - pool.status.config.actionsmenu.register.virtualdevice.remove = true; - } - - //Clear Disk Errors - if (!pool.readonly && pool.status.config.tier.level > 0 && !pool.status.config.tier.spares && pool.status.config.disk) { - pool.status.config.actionsmenu.items.disk.push(`
  • Clear Disk Errors
  • `); - - pool.status.config.actionsmenu.register.disk.clear = true; - } - - //Attach Disk: Disk and Mirror virtual devices only - if (!pool.readonly && pool.status.config.tier.level == 1 && !pool.status.config.tier.cache && !pool.status.config.tier.spares && (/^mirror-/g.test(_value[0]) || pool.status.config.disk)) { - pool.status.config.actionsmenu.items.disk.push(`
  • Attach Disk
  • `); - - pool.status.config.actionsmenu.register.disk.attach = true; - } - - //Detach Disk: Disk and Mirror virtual devices only - if (!pool.readonly && (pool.status.config.tier.level == 2 && /^spare-/g.test(_value[0]) == false || pool.status.config.tier.level == 3) && /^mirror-/g.test(pool.status.config.tier.nametier1) && pool.status.config.disk) { - pool.status.config.actionsmenu.items.disk.push(`
  • Detach Disk
  • `); - - pool.status.config.actionsmenu.register.disk.detach = true; - } - - if (!pool.readonly && pool.status.config.tier.level > 0 && pool.status.config.disk) { - //Online Disk / Offline Disk - if (_value[1] == "OFFLINE" || _value[1] == "UNAVAIL" || _value[1] == "FAULTED") { - pool.status.config.actionsmenu.items.disk.push(`
  • Online Disk
  • `); - - pool.status.config.actionsmenu.register.disk.online = true; - } else if ((_value[1] == "ONLINE" || _value[1] == "DEGRADED") && (pool.status.config.tier.level > 1 || pool.status.config.tier.level == 1 && (pool.status.config.tier.cache || pool.status.config.tier.logs))) { //Do not show offline disk if virtual device is Disk in Pool and Dedup - pool.status.config.actionsmenu.items.disk.push(`
  • Offline Disk
  • `); - - pool.status.config.actionsmenu.register.disk.offline = true; - } - - //Replace Disk - if (!pool.status.config.tier.spares) { - pool.status.config.actionsmenu.items.disk.push(`
  • Replace Disk
  • `); - - pool.status.config.actionsmenu.register.disk.replace = true; - } - - if (pool.status.disks.disk.ssd && !pool.status.disks.disk.trim.unsupported && !pool.status.config.tier.cache && !pool.status.config.tier.spares) { - //TRIM Disk - if (!pool.status.disks.disk.trim.started && !pool.status.disks.disk.trim.suspended) { - pool.status.config.actionsmenu.items.disk.push(`
  • TRIM Disk
  • `); - - pool.status.config.actionsmenu.register.disk.trim.start = true; - } - - //Resume Disk TRIM - if (pool.status.disks.disk.trim.suspended) { - pool.status.config.actionsmenu.items.disk.push(`
  • Resume Disk TRIM
  • `); - - pool.status.config.actionsmenu.register.disk.trim.resume = true; - } - - //Suspend Disk TRIM - if (pool.status.disks.disk.trim.started) { - pool.status.config.actionsmenu.items.disk.push(`
  • Suspend Disk TRIM
  • `); - - pool.status.config.actionsmenu.register.disk.trim.suspend = true; - } - - //Cancel Disk TRIM - if (pool.status.disks.disk.trim.started || pool.status.disks.disk.trim.suspended) { - pool.status.config.actionsmenu.items.disk.push(`
  • Cancel Disk TRIM
  • `); - - pool.status.config.actionsmenu.register.disk.trim.cancel = true; - } - } - } - - pool.status.config.output += ``; - pool.status.config.output += `` + pool.status.config.actionsmenu.display() + ``; - pool.status.config.output += ``; - - $("#tbody-storagepool-status-config-" + pool.id).append(pool.status.config.output); - - //Register status modals - if (pool.status.config.actionsmenu.register.disk.attach) { - FnModalStatusDiskAttach({ name: pool.name, id: pool.id, status: { config: { items: { index: _index }, tier: { name: pool.status.config.tier.nametier0, dedup: pool.status.config.tier.dedup, logs: pool.status.config.tier.logs, special: pool.status.config.tier.special } } } }, { id: _value[0], disk: pool.status.config.disk }); - } - if (pool.status.config.actionsmenu.register.disk.clear) { - FnModalStatusDiskClear({ name: pool.name, id: pool.id, status: { config: { items: { index: _index } } } }, { id: _value[0] }); - } - if (pool.status.config.actionsmenu.register.disk.detach) { - FnModalStatusDiskDetach({ name: pool.name, id: pool.id, status: { config: { items: { index: _index } } } }, { id: _value[0] }); - } - if (pool.status.config.actionsmenu.register.disk.offline) { - FnModalStatusDiskOffline({ name: pool.name, id: pool.id, status: { config: { items: { index: _index } } } }, { id: _value[0] }); - } - if (pool.status.config.actionsmenu.register.disk.online) { - FnModalStatusDiskOnline({ name: pool.name, id: pool.id, status: { config: { items: { index: _index } } } }, { id: _value[0] }); - } - if (pool.status.config.actionsmenu.register.disk.replace) { - FnModalStatusDiskReplace({ name: pool.name, id: pool.id, status: { config: { items: { index: _index } } } }, { id: _value[0] }); - } - if (pool.status.config.actionsmenu.register.storagepool.clear) { - FnModalStatusStoragePoolClear({ name: pool.name, id: pool.id, status: { config: { items: { index: _index } } } }); - } - if (pool.status.config.actionsmenu.register.storagepool.regenerateguid) { - FnModalStatusStoragePoolRegenerateGuid({ name: pool.name, id: pool.id, guid: pool.guid, status: { config: { items: { index: _index } } } }); - } - if (pool.status.config.actionsmenu.register.storagepool.resilver) { - FnModalStatusStoragePoolResilver({ name: pool.name, id: pool.id, status: { config: { items: { index: _index } }, resilver: { started: pool.status.resilver.started } } }); - } - if (pool.status.config.actionsmenu.register.storagepool.trim.start) { - FnModalStatusStoragePoolTrimStart({ name: pool.name, id: pool.id, autotrim: pool.autotrim, status: { config: { items: { index: _index } } } }); - } - if (pool.status.config.actionsmenu.register.storagepool.upgrade) { - FnModalStatusStoragePoolUpgrade({ name: pool.name, id: pool.id, status: { config: { items: { index: _index } } }, version: pool.version }); - } - if (pool.status.config.actionsmenu.register.virtualdevice.add) { - FnModalStatusVirtualDeviceAdd({ name: pool.name, id: pool.id, feature: { allocation_classes: pool.feature.allocation_classes }, status: { config: { items: { index: _index } } } }); - } - if (pool.status.config.actionsmenu.register.virtualdevice.clear) { - FnModalStatusVirtualDeviceClear({ name: pool.name, id: pool.id, status: { config: { items: { index: _index } } } }, { id: _value[0] }); - } - if (pool.status.config.actionsmenu.register.virtualdevice.remove) { - FnModalStatusVirtualDeviceRemove({ name: pool.name, id: pool.id, status: { config: { items: { index: _index } } } }, { id: _value[0], disk: pool.status.config.disk }); - } - - //Register status dynamics - if (pool.status.config.actionsmenu.register.disk.trim.cancel) { - FnDynamicStatusDiskTrimCancel({ name: pool.name, id: pool.id, status: { config: { items: { index: _index } } } }, { id: _value[0] }); - } - if (pool.status.config.actionsmenu.register.disk.trim.resume) { - FnDynamicStatusDiskTrimResume({ name: pool.name, id: pool.id, status: { config: { items: { index: _index } } } }, { id: _value[0] }); - } - if (pool.status.config.actionsmenu.register.disk.trim.start) { - FnModalStatusDiskTrimStart({ name: pool.name, id: pool.id, status: { config: { items: { index: _index } } } }, { id: _value[0] }); - } - if (pool.status.config.actionsmenu.register.disk.trim.suspend) { - FnDynamicStatusDiskTrimSuspend({ name: pool.name, id: pool.id, status: { config: { items: { index: _index } } } }, { id: _value[0] }); - } - if (pool.status.config.actionsmenu.register.storagepool.scrub.pause) { - FnDynamicStatusStoragePoolScrubPause({ name: pool.name, id: pool.id, status: { config: { items: { index: _index } } } }); - } - if (pool.status.config.actionsmenu.register.storagepool.scrub.resume) { - FnDynamicStatusStoragePoolScrubResume({ name: pool.name, id: pool.id, status: { config: { items: { index: _index } } } }); - } - if (pool.status.config.actionsmenu.register.storagepool.scrub.start) { - FnDynamicStatusStoragePoolScrubStart({ name: pool.name, id: pool.id, status: { config: { items: { index: _index } } } }); - } - if (pool.status.config.actionsmenu.register.storagepool.scrub.stop) { - FnDynamicStatusStoragePoolScrubStop({ name: pool.name, id: pool.id, status: { config: { items: { index: _index } } } }); - } - if (pool.status.config.actionsmenu.register.storagepool.trim.cancel) { - FnDynamicStatusStoragePoolTrimCancel({ name: pool.name, id: pool.id, status: { config: { items: { index: _index } } } }); - } - if (pool.status.config.actionsmenu.register.storagepool.trim.resume) { - FnDynamicStatusStoragePoolTrimResume({ name: pool.name, id: pool.id, status: { config: { items: { index: _index } } } }); - } - if (pool.status.config.actionsmenu.register.storagepool.trim.suspend) { - FnDynamicStatusStoragePoolTrimSuspend({ name: pool.name, id: pool.id, status: { config: { items: { index: _index } } } }); - } - }); - - //Hide Storage Pool TRIM actions menu items if there is no SSD in the storage pool or all disks are TRIM unsupported - if (!pool.status.disks.ssd || pool.status.disks.trim.unsupportedcount == pool.status.disks.count) { - $("#btn-storagepool-status-trim-start-0-" + pool.id).addClass("hidden"); - $("#btn-storagepool-status-trim-resume-0-" + pool.id).addClass("hidden"); - $("#btn-storagepool-status-trim-suspend-0-" + pool.id).addClass("hidden"); - $("#btn-storagepool-status-trim-cancel-0-" + pool.id).addClass("hidden"); - } - - //Hide Remove Virtual Device actions menu item is there is only one in the storage pool - if (pool.status.config.virtualdevice.count < 2) { - $("[id^=btn-storagepool-status-virtualdevice-remove-][id$='" + pool.id + "'].pool-virtualdevice").addClass("hidden"); - $("[id^=divider-storagepool-status-][id$=" + pool.id + "].pool-virtualdevice").addClass("hidden"); - } - - $("#tr-storagepool-" + pool.id).attr("data-pool-refresh-status", "true"); - - $("#spinner-storagepool-status-" + pool.id).addClass("hidden"); - $("#paneltitle-storagepool-status-" + pool.id).removeClass("hidden").text(FnDateTime()); - $("#btn-storagepool-status-refresh-" + pool.id).prop("disabled", false); - $("#btn-storagepool-status-refresh-auto-" + pool.id).prop("disabled", false); - - FnStoragePoolSpinnerHide({ name: pool.name, id: pool.id }); - FnCockpitElementsUpdate(); -} - -function FnStatusGetFail(pool = { name, id, status: { empty: true } }) { - if (pool.status.empty) { - $("#tbody-storagepool-status-messages-" + pool.id).empty(); - $("#tbody-storagepool-status-config-" + pool.id).empty(); - $("#tbody-storagepool-status-messages-" + pool.id).append(`Status not available`); - $("#modals-storagepool-status-" + pool.id).remove(); - $("#dynamics-storagepool-status-" + pool.id).remove(); - - $("#tr-storagepool-" + pool.id).attr("data-pool-refresh-status", "true"); - - $("#spinner-storagepool-status-" + pool.id).addClass("hidden"); - $("#paneltitle-storagepool-status-" + pool.id).removeClass("hidden").text(FnDateTime()); - $("#btn-storagepool-status-refresh-" + pool.id).prop("disabled", false); - $("#btn-storagepool-status-refresh-auto-" + pool.id).prop("disabled", false); - } - - FnStoragePoolSpinnerHide({ name: pool.name, id: pool.id }); - FnCockpitElementsUpdate(); -} - -//#endregion - -//#region System - -function FnSystemHostIdGet(modal = { name, id }) { - let process = { - command: ["/bin/sh", "-c", "/bin/cat /etc/hostid 2> /dev/null && echo response true || echo response false"] - }; - - FnConsole.log[2]("System, Host ID, Get: In Progress"); - FnConsole.log[3](FnConsoleCommand({ command: process.command })); - - return cockpit.spawn(process.command, { err: "out" }) - .done(function (data) { - FnConsole.log[4](FnConsoleVerbose({ data: data, message: "System, Host ID, Get:" })); - - data = data.replace(/\n+/g, "").replace(/^.+response /, "").replace("response ", ""); - - if (data == "false") { - if (modal.name) { - if ($("#switch-" + modal.name + "-multihost-" + modal.id + " input").prop("checked")) { - $("#btnspan-" + modal.name + "-hostid-" + modal.id).text("Use Lib C Generated Host ID").attr("data-field-value", "libc"); - $("#dropdown-" + modal.name + "-hostid-" + modal.id + " li").siblings().removeClass("active"); - $("#dropdown-" + modal.name + "-hostid-" + modal.id + " li[value='libc']").addClass("active"); - - $("#controllabel-" + modal.name + "-hostid-" + modal.id).removeClass("hidden"); - $("#validationwrapper-" + modal.name + "-hostid-" + modal.id).removeClass("hidden"); - } else { - $("#btnspan-" + modal.name + "-hostid-" + modal.id).text("Use Lib C Generated Host ID").attr("data-field-value", "missing"); - $("#dropdown-" + modal.name + "-hostid-" + modal.id + " li").siblings().removeClass("active"); - $("#dropdown-" + modal.name + "-hostid-" + modal.id + " li[value='libc']").addClass("active"); - } - } - - FnConsole.warn("System, Host ID, Get: Warning, Message: Host ID does not exist"); - } else { - FnConsole.log[1]("System, Host ID, Get: Success"); - } - }) - .fail(function (message, data) { - FnConsole.warn("System, Host ID, Get: Failed, Message: " + (data ? data : message)); - }); -} - -function FnSystemHostIdSet(system = { hostid }) { - let process = { - command: ["/bin/sh", "-c", "[ -x /usr/" + (/Debian/.test(zfsmanager.system.operatingsystem) ? "s" : "") + "bin/zgenhostid ] && /usr/" + (/Debian/.test(zfsmanager.system.operatingsystem) ? "s" : "") + "bin/zgenhostid" + (system.hostid ? " " + system.hostid : "") + " || zgenhostid " + (system.hostid ? " " + system.hostid : "")] - }; - - FnConsole.log[2]("System, Host ID, Set: In Progress"); - FnConsole.log[3](FnConsoleCommand({ command: process.command })); - - return cockpit.spawn(process.command, { err: "out", superuser: "require" }) - .done(function () { - FnDisplayAlert({ status: "success", title: "System Host ID successfully configured", description: null, breakword: false }, { name: "system-hostid-set", id: null, timeout: 4 }); - - FnConsole.log[1]("System, Host ID, Set: Success"); - }) - .fail(function (message, data) { - FnConsole.warn("System, Host ID, Set: Failed, Message: " + (data ? data : message)); - }); -} - -function FnSystemNfsVersionGet(modal = { alert: { id } }) { - let process = { - command: ["/usr/sbin/nfsstat", "--version"] - }; - - FnConsole.log[2]("System, NFS, Version, Get: In Progress"); - FnConsole.log[3](FnConsoleCommand({ command: process.command })); - - return cockpit.spawn(process.command, { err: "out" }) - .done(function (data) { - FnConsole.log[4](FnConsoleVerbose({ data: data, message: "System, NFS, Version, Get:" })); - - modal.alert.id.addClass("hidden"); - - FnConsole.log[1]("System, NFS, Version, Get: Success"); - }) - .fail(function () { - modal.alert.id.removeClass("hidden"); - - FnConsole.warn("System, NFS, Version, Get: Failed, Message: NFS is not installed."); - }); -} - -function FnSystemOperatingSystemGet() { - let process = { - command: ["/bin/sh", "-c", "/usr/bin/hostnamectl status | /bin/grep 'Operating System'"] - }; - - FnConsole.log[2]("System, Operating System, Get: In Progress"); - FnConsole.log[3](FnConsoleCommand({ command: process.command })); - - return cockpit.spawn(process.command, { err: "out" }) - .done(function (data) { - FnConsole.log[4](FnConsoleVerbose({ data: data, message: "System, Operating System, Get:" })); - - data = data.replace(/\n+/g, "").replace(/^(?: +)Operating System: /, ""); - - if (data) { - zfsmanager.system.operatingsystem = data; - } - - FnConsole.log[2]("System, Operating System, Get: Success"); - }) - .fail(function (message, data) { - FnConsole.warn("System, Operating System, Get: Failed, Message: " + (data ? data : message)); - }); -} - -//#endregion - -//#region Disks - -function FnDisksAvailableGet(modal = { name, id, default: true }) { - disks = { - attached: [], - id: { - device: [], - path: [], - vdev: [] - }, - importable: [], - importableconfig: [], - importableconfigok: false, - storagepools: [], - storagepoolsconfig: [] - - }; - modal.id = (modal.id ? "-" + modal.id : ""); - - $("#listgroup-" + modal.name + modal.id).empty(); - $("#listgroup-" + modal.name + modal.id).append(`
  • `); - - FnDisksStoragePoolsAttachedGet({ name: null, id: null }, { id: { blockdevice: true } }) - .done(function (data) { - FnConsole.log[4](FnConsoleVerbose({ data: data, message: "Disks, Storage Pools, Attached, Get:" })); - - disks.storagepools = data.replace(/\n\t+/g, "[TAB1]").split(/\n/g).filter(v => v); - - disks.storagepools.forEach((_value, _index) => { - if (/\[TAB1\]NAME/g.test(_value)) { //Config header row - _value = _value.split("upath").slice(1).join("."); //Remove config header row (and any previous text if exists) - - if (new RegExp("^\\[TAB1\\]").test(_value)) { //Confirm config rows - _value.split("[TAB1]").filter(v => v && disks.storagepoolsconfig.push(v)); - } - } - }); - - disks.storagepoolsconfig.forEach((_value, _index) => { - let config = { - disk: { - upath: "" - }, - tier: { - level: (_value.match(/^\s*/g)[0].length / 2) - } - }; - - _value = _value.replace(/ +/g, "\u22C5").replace(/^\u22C5/, "").split("\u22C5").filter(v => v); - - if (/^\/dev\/nvme|^\/dev\/sd/gi.test(_value[5])) { //upath - config.disk.upath = _value[5]; - } else if (!$.isNumeric(_value[0]) && _value[5] != "was") { //upath appears after error messages and before trim messages - for (let i = 5; i < _value.length; i++) { - if (/^\/dev\/nvme|^\/dev\/sd/gi.test(_value[i])) { - config.disk.upath = _value[i]; - } - } - } - - if (config.tier.level > 0) { - if (/^\/dev\/nvme|^\/dev\/sd/gi.test(config.disk.upath)) { //Block Device via upath - disks.attached.push(config.disk.upath.replace(/^\/dev\//gi, "")); - } else if (/^\/dev\/nvme|^\/dev\/sd/gi.test(_value[0])) { //Block Device - if (/^\/dev\/nvme\d+n\d+p\d+$/gi.test(_value[0])) { - disks.attached.push(_value[0].replace(/^\/dev\//gi, "").replace(/p\d+$/, "")); - } else if (/^\/dev\/sd.*\d+$/gi.test(_value[0])) { - disks.attached.push(_value[0].replace(/^\/dev\//gi, "").replace(/\d+$/, "")); - } else { - disks.attached.push(_value[0]); - } - } else if (/^nvme-nvme/gi.test(_value[0]) || /^wwn-/gi.test(_value[0])) { //WWN - if (/^nvme-nvme.*-part\d+$/gi.test(_value[0])) { - disks.attached.push(_value[0].replace(/-part\d+$/, "")); - } else if (/^wwn-.*-part\d+$/gi.test(_value[0])) { - disks.attached.push(_value[0].replace(/-part\d+$/, "")); - } else { - disks.attached.push(_value[0]); - } - } - } - }); - - disks.attached.sort(); - - FnDisksStoragePoolsImportableAttachedGet() - .done(function (_data) { - FnConsole.log[4](FnConsoleVerbose({ data: _data, message: "Disks, Storage Pools, Importable, Attached, Get:" })); - - disks.importable = _data.replace(/\n\t+/g, "[TAB1]").split(/\n/g).filter(v => v); - - disks.importable.forEach((_value, _index) => { - if (/config:/g.test(_value)) { //Config header row - disks.importableconfigok = true; - } - - if (new RegExp("^\\[TAB1\\]").test(_value) && disks.importableconfigok) { //Confirm config rows - _value.split("[TAB1]").filter(v => v && disks.importableconfig.push(v)); - } - }); - - disks.importableconfig.forEach((_value, _index) => { - let config = { - tier: { - level: (_value.match(/^\s*/g)[0].length / 2) - } - }; - - _value = _value.replace(/ +/g, "\u22C5").replace(/^\u22C5/, "").split("\u22C5").filter(v => v); - - if (config.tier.level > 0) { - if (/^nvme|^sd/gi.test(_value[0])) { //Block Device - if (/^nvme\d+n\d+p\d+$/gi.test(_value[0])) { - disks.attached.push(_value[0].replace(/p\d+$/, "")); - } else if (/^sd.*\d+$/gi.test(_value[0])) { - disks.attached.push(_value[0].replace(/\d+$/, "")); - } else { - disks.attached.push(_value[0]); - } - } else if (/^\/dev\/nvme|^\/dev\/sd/gi.test(_value[0])) { //Block Device - if (/^\/dev\/nvme\d+n\d+p\d+$/gi.test(_value[0])) { - disks.attached.push(_value[0].replace(/^\/dev\//gi, "").replace(/p\d+$/, "")); - } else if (/^\/dev\/sd.*\d+$/gi.test(_value[0])) { - disks.attached.push(_value[0].replace(/^\/dev\//gi, "").replace(/\d+$/, "")); - } else { - disks.attached.push(_value[0]); - } - } else if (/^nvme-nvme/gi.test(_value[0]) || /^wwn-/gi.test(_value[0])) { //WWN - if (/^nvme-nvme.*-part\d+$/gi.test(_value[0])) { - disks.attached.push(_value[0].replace(/-part\d+$/, "")); - } else if (/^wwn-.*-part\d+$/gi.test(_value[0])) { - disks.attached.push(_value[0].replace(/-part\d+$/, "")); - } else { - disks.attached.push(_value[0]); - } - } - } - }); - - disks.attached.sort(); - - FnDisksLsblkGet({ sizeraw: true }) - .done(function (__data) { - FnConsole.log[4](FnConsoleVerbose({ data: __data, message: "Disks, Lsblk, Get:" })); - - disks.lsblkjson = __data; - - FnDisksBlkidGet() - .done(function (___data) { - FnConsole.log[4](FnConsoleVerbose({ data: ___data, message: "Disks, Blkid, Get:" })); - - let replacement = { - regexp: [ - { pattern: /"/g, replacement: "" }, - { pattern: /: LABEL=/g, replacement: ",LABEL=" }, - { pattern: / UUID=/g, replacement: ",UUID=" }, - { pattern: / UUID_SUB=/g, replacement: ",UUID_SUB=" }, - { pattern: / TYPE=/g, replacement: ",TYPE=" }, - { pattern: / PARTLABEL=/g, replacement: ",PARTLABEL=" }, - { pattern: / PARTUUID=/g, replacement: ",PARTUUID=" } - ] - }; - - disks.blkid = replacement.regexp.reduce((d, r) => d.replace(r.pattern, r.replacement), ___data).split(/\n/g).filter(v => v); - - FnDisksIdentifierDiskGet() - .done(function (____data) { - FnConsole.log[4](FnConsoleVerbose({ data: ____data, message: "Disks, Identifier, Disk / WWN, Get:" })); - - disks.id.device = ____data.replace(/\t+/g, "\u22C5").replace(/..\/..\//g, "").split(/\n/g).filter(v => v && v != "\u22C5"); - - FnDisksIdentifierHardwarePathGet() - .done(function (_____data) { - FnConsole.log[4](FnConsoleVerbose({ data: _____data, message: "Disks, Identifier, Hardware Path, Get:" })); - - disks.id.path = _____data.replace(/\t+/g, "\u22C5").replace(/..\/..\//g, "").split(/\n/g).filter(v => v && v != "\u22C5"); - - FnDisksIdentifierVirtualDeviceMappingGet() - .done(function (______data) { - FnConsole.log[4](FnConsoleVerbose({ data: ______data, message: "Disks, Identifier, Virtual Device Mapping, Get:" })); - - disks.id.vdev = ______data.replace(/\t+/g, "\u22C5").replace(/..\/..\//g, "").split(/\n/g).filter(v => v && v != "\u22C5"); - - FnDisksAvailableGetCommand({ attached: disks.attached, blkid: disks.blkid, id: { device: disks.id.device, path: disks.id.path, vdev: disks.id.vdev }, lsblkjson: disks.lsblkjson }, { name: modal.name, id: modal.id, default: modal.default }); - }) - .fail(function (______message, ______data) { - FnConsole.warn("Disks, Available, Get: Failed, Message: " + (______data ? ______data : ______message)); - - FnDisksAvailableGetFail({ name: modal.name, id: modal.id }, { data: ______data, message: ______message }); - }); - }) - .fail(function (_____message, _____data) { - FnConsole.warn("Disks, Available, Get: Failed, Message: " + (_____data ? _____data : _____message)); - - FnDisksAvailableGetFail({ name: modal.name, id: modal.id }, { data: _____data, message: _____message }); - }); - }) - .fail(function (____message, ____data) { - FnConsole.warn("Disks, Available, Get: Failed, Message: " + (____data ? ____data : ____message)); - - FnDisksAvailableGetFail({ name: modal.name, id: modal.id }, { data: ____data, message: ____message }); - }); - }) - .fail(function (___message, ___data) { - FnConsole.warn("Disks, Available, Get: Failed, Message: " + (___data ? ___data : ___message)); - - FnDisksAvailableGetFail({ name: modal.name, id: modal.id }, { data: ___data, message: ___message }); - }); - }) - .fail(function (__message, __data) { - FnConsole.warn("Disks, Available, Get: Failed, Message: " + (__data ? __data : __message)); - - FnDisksAvailableGetFail({ name: modal.name, id: modal.id }, { data: __data, message: __message }); - }); - }) - .fail(function (_message, _data) { - FnConsole.warn("Disks, Available, Get: Failed, Message: " + (_data ? _data : _message)); - - FnDisksAvailableGetFail({ name: modal.name, id: modal.id }, { data: _data, message: _message }); - }); - }) - .fail(function (message, data) { - FnConsole.warn("Disks, Available, Get: Failed, Message: " + (data ? data : message)); - - FnDisksAvailableGetFail({ name: modal.name, id: modal.id }, { data: data, message: message }); - }); -} - -function FnDisksAvailableGetCommand(disks = { attached: [], blkid: [], id: { device: [], path: [], vdev: [] }, lsblkjson }, modal = { name, id, default: true }) { - disks.lsblk = JSON.parse(disks.lsblkjson); - disks.regexp = {}; - - disks.lsblk.blockdevices.forEach((_value, _index) => { - if (_value.type == "disk") { - let disk = { - id: { - blockdevice: "", - disk: "", - path: "", - vdev: "", - wwn: "" - }, - allow: true, - zfsmember: false, - warning: "", - warningicon: "", - }; - - disks.attached.forEach((__value, __index) => { - if (_value.name == __value || _value.wwn == __value || "nvme-" + _value.wwn == __value || "wwn-" + _value.wwn == __value) { //Do not allow if block device or WWN identifier match - disk.allow = false; - return; - } - }); - - if (_value.children && disk.allow) { - _value.children.forEach((__value, __index) => { - if (__value.mountpoint) { //Do not allow if partition of disk is mounted - disk.allow = false; - return; - } - }); - } - - if (disk.allow) { - disks.blkid.forEach((__value, __index) => { - disks.regexp.name = new RegExp("^\/dev\/" + _value.name, "gi"); - - if (disks.regexp.name.test(__value)) { - if (/,TYPE=zfs_member/gi.test(__value)) { - disk.zfsmember = true; - return; - } - } - }); - - if (disk.zfsmember) { - disk.warningicon = ` `; - - $("#helpblock-" + modal.name + "-zfsmemberwarning" + modal.id).html("One or more disks used to be a member of a Storage Pool." + disk.warningicon); - } - - disk.id.blockdevice = _value.name; - - if (!_value.wwn) { - disk.id.wwn = ""; - disk.warning = "One or more disks is missing a WWN identifier."; - - $("#helpblock-" + modal.name + "-identifierwarning" + modal.id).removeClass("hidden").text(disk.warning); - } else { - if (/^nvme/gi.test(_value.wwn)) { - disk.id.wwn = "nvme-" + _value.wwn; - } else { - disk.id.wwn = "wwn-" + _value.wwn; - } - } - - disks.id.device.forEach((_value, _index) => { - _value = _value.split("\u22C5"); - - if (_value[1] == disk.id.blockdevice) { - if (/^nvme-nvme|^wwn-/gi.test(_value[0])) { - return; - } else { - disk.id.disk = _value[0]; - return; - } - } - }); - - disks.id.path.forEach((_value, _index) => { - _value = _value.split("\u22C5"); - - if (_value[1] == disk.id.blockdevice) { - disk.id.path = _value[0]; - - return; - } - }); - - disks.id.vdev.forEach((_value, _index) => { - _value = _value.split("\u22C5"); - - if (_value[1] == disk.id.blockdevice) { - disk.id.vdev = _value[0]; - - return; - } - }); - - disks.output = ` - - `; - - $("#listgroup-" + modal.name + modal.id).append(disks.output); - } - } - }); - - setTimeout(function () { - $("#spinner-" + modal.name + modal.id).remove(); - $("#listgroup-" + modal.name + modal.id + " > li").removeClass("hidden"); - - if ($("#helpblock-" + modal.name + "-identifierwarning" + modal.id).text) { - $("#helpblock-" + modal.name + "-identifierwarning" + modal.id).removeClass("hidden"); - } - if ($("#helpblock-" + modal.name + "-zfsmemberwarning" + modal.id).text()) { - $("#helpblock-" + modal.name + "-zfsmemberwarning" + modal.id).removeClass("hidden"); - } - - if ($("#listgroup-" + modal.name + modal.id + " > li").length == 1 && modal.default) { //Change Virtual Device dropdown to Disk if there is only 1 disk available - if (modal.name == "storagepools-create-disks") { - $("#btnspan-storagepools-create-virtualdevice").text("Disk").attr("data-field-value", "disk"); - $("#dropdown-storagepools-create-virtualdevice li").siblings().removeClass("active"); - $("#dropdown-storagepools-create-virtualdevice li[value='disk']").addClass("active"); - } else if (modal.name == "storagepool-status-virtualdevice-add-disks") { - $("#btnspan-storagepool-status-virtualdevice-add-virtualdevice" + modal.id).text("Disk").attr("data-field-value", "disk"); - $("#dropdown-storagepool-status-virtualdevice-add-virtualdevice" + modal.id + " li").siblings().removeClass("active"); - $("#dropdown-storagepool-status-virtualdevice-add-virtualdevice" + modal.id + " li[value='disk']").addClass("active"); - } - } - - if ($("#listgroup-" + modal.name + modal.id + " > li").length == 0) { - disks.output = ` -
  • - -
  • - `; - - $("#listgroup-" + modal.name + modal.id).append(disks.output); - } - }, 200); - - FnConsole.log[1]("Disks, Available, Get: Success"); -} - -function FnDisksAvailableGetFail(modal = { name, id }, process = { data, message }) { - setTimeout(function () { - $("#spinner-" + modal.name + modal.id).remove(); - $("#listgroup-" + modal.name + modal.id + " > li").removeClass("hidden"); - - if ($("#listgroup-" + modal.name + modal.id + " > li").length == 0) { - let disks = { - output: "" - }; - - disks.output = ` -
  • - -
  • - `; - - $("#listgroup-" + modal.name + modal.id).append(disks.output); - } - }, 200); -} - -function FnDisksBlkidGet() { - let process = { - command: ["/bin/sh", "-c", "/sbin/blkid -o full | /bin/grep -E '/dev/nvme\|/dev/sd'"] - }; - - FnConsole.log[2]("Disks, Blkid, Get: In Progress"); - FnConsole.log[2](FnConsoleCommand({ command: process.command })); - - return cockpit.spawn(process.command, { err: "out" }) - .done(function () { - FnConsole.log[2]("Disks, Blkid, Get: Success"); - }) - .fail(function (message, data) { - FnConsole.warn("Disks, Blkid, Get: Failed, Message: " + (data ? data : message)); - }); -} - -function FnDisksIdentifierDiskGet() { - let process = { - command: ["/bin/sh", "-c", `ls -lF /dev/disk/by-id | awk '{ print $9"\t"$11 }'`] - }; - - FnConsole.log[2]("Disks, Identifier, Disk / WWN, Get: In Progress"); - FnConsole.log[2](FnConsoleCommand({ command: process.command })); - - return cockpit.spawn(process.command, { err: "out" }) - .done(function () { - FnConsole.log[2]("Disks, Identifier, Disk / WWN, Get: Success"); - }) - .fail(function (message, data) { - FnConsole.warn("Disks, Identifier, Disk / WWN, Get: Failed, Message: " + (data ? data : message)); - }); -} - -function FnDisksIdentifierHardwarePathGet() { - let process = { - command: ["/bin/sh", "-c", `ls -lF /dev/disk/by-path | awk '{ print $9"\t"$11 }'`] - }; - - FnConsole.log[2]("Disks, Identifier, Hardware Path, Get: In Progress"); - FnConsole.log[2](FnConsoleCommand({ command: process.command })); - - return cockpit.spawn(process.command, { err: "out" }) - .done(function () { - FnConsole.log[2]("Disks, Identifier, Hardware Path, Get: Success"); - }) - .fail(function (message, data) { - FnConsole.warn("Disks, Identifier, Hardware Path, Get: Failed, Message: " + (data ? data : message)); - }); -} - -function FnDisksIdentifierVirtualDeviceMappingGet() { - let process = { - command: ["/bin/sh", "-c", `[ -d /dev/disk/by-vdev ] && ls -lF /dev/disk/by-vdev | awk '{ print $9"\t"$11 }' || printf ""`] - }; - - FnConsole.log[2]("Disks, Identifier, Virtual Device Mapping, Get: In Progress"); - FnConsole.log[3](FnConsoleCommand({ command: process.command })); - - return cockpit.spawn(process.command, { err: "out" }) - .done(function () { - FnConsole.log[2]("Disks, Identifier, Virtual Device Mapping, Get: Success"); - }) - .fail(function (message, data) { - FnConsole.warn("Disks, Identifier, Virtual Device Mapping, Get: Failed, Message: " + (data ? data : message)); - }); -} - -function FnDisksLsblkGet(disks = { sizeraw: true }) { - let process = { - command: ["/bin/sh", "-c", "/bin/lsblk -o label,model,mountpoint,name,partuuid,phy-sec,rota,serial,size,type,uuid,vendor,wwn -J" + (disks.sizeraw ? " -b" : "")] - }; - - FnConsole.log[2]("Disks, Lsblk, Get: In Progress"); - FnConsole.log[3](FnConsoleCommand({ command: process.command })); - - return cockpit.spawn(process.command, { err: "out" }) - .done(function () { - FnConsole.log[2]("Disks, Lsblk, Get: Success"); - }) - .fail(function (message, data) { - FnConsole.warn("Disks, Lsblk, Get: Failed, Message: " + (data ? data : message)); - }); -} - -function FnDisksStoragePoolsAttachedGet(pool = { name, id }, disks = { id: { blockdevice: true } }) { - let process = { - command: ["/bin/sh", "-c", ((zfsmanager.user.admin || !zfsmanager.user.name) ? "ZPOOL_SCRIPTS_AS_ROOT=1 " : "") + "/sbin/zpool status -P " + (disks.id.blockdevice ? "-L " : "") + "-c upath" + (pool.name ? ` "` + pool.name + `"` : "")] - }; - - FnConsole.log[2]("Disks, Storage Pools, Attached, Get: In Progress"); - FnConsole.log[2](FnConsoleCommand({ command: process.command })); - - return cockpit.spawn(process.command, { err: "out" }) - .done(function () { - FnConsole.log[2]("Disks, Storage Pools, Attached, Get: Success"); - }) - .fail(function (message, data) { - FnConsole.warn("Disks, Storage Pools, Attached, Get: Failed, Message: " + (data ? data : message)); - }); -} - -function FnDisksStoragePoolsImportableAttachedGet() { - let process = { - command: [((zfsmanager.user.admin || !zfsmanager.user.name) ? "pkexec" : ""), "/sbin/zpool", "import", "-d", "/dev"] - }; - - FnConsole.log[2]("Disks, Storage Pools, Importable, Attached, Get: In Progress"); - FnConsole.log[2](FnConsoleCommand({ command: process.command })); - - return cockpit.spawn(process.command, { err: "out" }) - .done(function () { - FnConsole.log[2]("Disks, Storage Pools, Importable, Attached, Get: Success"); - }) - .fail(function (message, data) { - FnConsole.warn("Disks, Storage Pools, Importable, Attached, Get: Failed, Message: " + (data ? data : message)); - }); -} - -function FnDisksStoragePoolsImportableGet() { - let process = { - command: ["/bin/sh", "-c", "/sbin/zpool import | /bin/grep -E 'pool:\| id:' | tr '\\\n' ','"] - }; - - FnConsole.log[2]("Disks, Importable Storage Pools, Get: In Progress"); - FnConsole.log[3](FnConsoleCommand({ command: process.command })); - - return cockpit.spawn(process.command, { err: "out" }) - .done(function () { - FnConsole.log[2]("Disks, Importable Storage Pools, Get: Success"); - }) - .fail(function (message, data) { - if (/no pools available to import/gi.test(data) == false) { - FnConsole.warn("Disks, Importable Storage Pools, Get: Failed, Message: " + (data ? data : message)); - } - }); -} - -//#endregion - -//#region Samba - -function FnSambaConfigurationReload() { - let process = { - command: [((zfsmanager.user.admin || !zfsmanager.user.name) ? "pkexec" : ""), "/usr/bin/smbcontrol", "all", "reload-config"] - }; - - FnConsole.log[2]("Samba, Configuration, Reload: In Progress"); - FnConsole.log[3](FnConsoleCommand({ command: process.command })); - - return cockpit.spawn(process.command, { err: "out" }) - .done(function () { - FnConsole.log[1]("Samba, Configuration, Reload: Success"); - }) - .fail(function (message, data) { - FnConsole.warn("Samba, Configuration, Reload: Failed, Message: " + (data ? data : message)); - }); -} - -function FnSambaConfigurationZfsSharesEnable() { - let process = { - command: ["/bin/sh", "-c", `[ -s /etc/samba/smb.conf ] && /usr/bin/awk -v k='\n\t# COCKPIT ZFS MANAGER\n\t# WARNING: DO NOT EDIT, AUTO-GENERATED CONFIGURATION\n\tinclude = /etc/cockpit/zfs/shares.conf\n\tinclude = /run/cockpit/zfs/shares.conf\n' '($1=="[global]"||x&&/^\\[/)&&!(x=!x){print k} END{if(x)print k}1' /etc/samba/smb.conf > /etc/samba/smb.tmp && /bin/mv -f /etc/samba/smb.tmp /etc/samba/smb.conf \|\| { echo '/etc/samba/smb.conf file does not exist or is empty.' ; exit 1; }`] - }; - - FnConsole.log[2]("Samba, Configuration, ZFS Shares, Enable: In Progress"); - FnConsole.log[3](FnConsoleCommand({ command: process.command })); - - return cockpit.spawn(process.command, { err: "out", superuser: "require" }) - .done(function () { - FnConsole.log[1]("Samba, Configuration, ZFS Shares, Enable: Success"); - - FnSambaConfigurationReload(); - }) - .fail(function (message, data) { - FnConsole.warn("Samba, Configuration, ZFS Shares, Enable: Failed, Message: " + (data ? data : message)); - }); -} - -function FnSambaConfigurationZfsSharesGet() { - let process = { - command: ["/bin/sh", "-c", "/bin/grep -Pzoq '(?s)include = /etc/cockpit/zfs/shares.conf.*/run/cockpit/zfs/shares.conf' /etc/samba/smb.conf && echo true || echo false"] - }; - - FnConsole.log[2]("Samba, Configuration, ZFS Shares, Get: In Progress"); - FnConsole.log[3](FnConsoleCommand({ command: process.command })); - - return cockpit.spawn(process.command, { err: "out" }) - .done(function (data, message) { - FnConsole.log[4](FnConsoleVerbose({ data: data, message: "Samba, Configuration, ZFS Shares, Get:" })); - - data = data.replace(/\n+/g, ""); - - if (data == "false") { - FnSambaConfigurationZfsSharesEnable(); - } else if (data == "true") { - FnConsole.log[2]("Samba, Configuration, ZFS Shares, Get: Success"); - } else { - FnConsole.warn("Samba, Configuration, ZFS Shares, Get: Failed, Message: " + (data ? data : message)); - } - }) - .fail(function (message, data) { - FnConsole.warn("Samba, Configuration, ZFS Shares, Get: Failed, Message: " + (data ? data : message)); - }); -} - -function FnSambaManage() { - if (zfsmanager.user.admin) { - FnSambaConfigurationZfsSharesGet(); - } -} - -function FnSambaRestart() { - let process = { - command: ["/bin/systemctl", "restart"] - }; - - if (/Debian|Ubuntu/i.test(zfsmanager.system.operatingsystem)) { - process.command.splice(2, 0, "smbd"); - } else { - process.command.splice(2, 0, "smb"); - } - - FnConsole.log[2]("Samba, Restart: In Progress"); - FnConsole.log[3](FnConsoleCommand({ command: process.command })); - - return cockpit.spawn(process.command, { err: "out", superuser: "require" }) - .done(function () { - FnConsole.log[1]("Samba, Restart: Success"); - }) - .fail(function (message, data) { - FnConsole.warn("Samba, Restart: Failed, Message: " + (data ? data : message)); - }); -} - -function FnSambaShareDestroy(pool = { name, id, altroot: false, readonly: false }, filesystem = { name, id }, samba = { restart: false }, display = { silent: false }) { - let process = { - promise: cockpit.defer() - }; - - FnSambaZfsShareDisable({ name: pool.name, id: pool.id, altroot: pool.altroot, readonly: pool.readonly }, { name: filesystem.name, id: filesystem.id }) - .done(function () { - FnSambaZfsSharesConfigurationReload() - .done(function () { - setTimeout(function () { - if (samba.restart) { - FnSambaRestart() - .finally(function () { - if (!display.silent) { - FnDisplayAlert({ status: "success", title: "Samba share successfully destroyed", description: filesystem.name, breakword: false }, { name: "samba-destroy", id: filesystem.id, timeout: 4 }); - } - - FnConsole.log[1]("Samba, Share, Destroy: Success, Pool: " + pool.name + ", File System: " + filesystem.name); - - process.promise.resolve(); - }); - } else { - FnSambaConfigurationReload() - .finally(function () { - if (!display.silent) { - FnDisplayAlert({ status: "success", title: "Samba share successfully destroyed", description: filesystem.name, breakword: false }, { name: "samba-destroy", id: filesystem.id, timeout: 4 }); - } - - FnConsole.log[1]("Samba, Share, Destroy: Success, Pool: " + pool.name + ", File System: " + filesystem.name); - - process.promise.resolve(); - }); - } - }, 500); - }) - }) - .fail(function () { - process.promise.resolve(); - }); - - return process.promise.promise(); -} - -function FnSambaShareDisable(pool = { name, id, altroot: false, readonly: false }, filesystem = { name, id }, samba = { restart: false }, display = { modal: true, silent: false }) { - if (display.modal) { - $("#spinner-storagepool-filesystem-samba-disable-" + filesystem.id + " span").text("Disabling Samba share..."); - } - - if (!pool.readonly) { - FnFileSystemShareSmbDisable({ name: pool.name, id: pool.id }, { name: filesystem.name, id: filesystem.id }) - .done(function () { - FnSambaShareDisableCommand({ name: pool.name, id: pool.id, altroot: pool.altroot, readonly: pool.readonly }, { name: filesystem.name, id: filesystem.id }, { restart: samba.restart }, { modal: display.modal, silent: display.silent }); - }) - .fail(function (message, data) { - if (/property may be set/gi.test(data)) { //False error is generated when configuring filesystem - FnSambaShareDisableCommand({ name: pool.name, id: pool.id, altroot: pool.altroot, readonly: pool.readonly }, { name: filesystem.name, id: filesystem.id }, { restart: samba.restart }, { modal: display.modal, silent: display.silent }); - } else { - if (!display.silent) { - FnDisplayAlert({ status: "danger", title: "Samba share could not be disabled", description: filesystem.name, breakword: false }, { name: "samba-disable", id: filesystem.id, timeout: 4 }); - } - - if (display.modal) { - $("#modal-storagepool-filesystem-samba-disable-" + filesystem.id).modal("hide"); - - setTimeout(function () { - FnStoragePoolRefresh({ name: pool.name, id: pool.id }, { storagepool: true, filesystems: true, snapshots: false, status: false }); - }, 200); - } - } - }); - } else { - FnSambaShareDisableCommand({ name: pool.name, id: pool.id, altroot: pool.altroot, readonly: pool.readonly }, { name: filesystem.name, id: filesystem.id }, { restart: samba.restart }, { modal: display.modal, silent: display.silent }); - } -} - -function FnSambaShareDisableCommand(pool = { name, id, altroot: false, readonly: false }, filesystem = { name, id }, samba = { restart: false }, display = { modal: true, silent: false }) { - FnSambaZfsShareDisable({ name: pool.name, id: pool.id, altroot: pool.altroot, readonly: pool.readonly }, { name: filesystem.name, id: filesystem.id }) - .done(function () { - FnSambaZfsSharesConfigurationReload() - .done(function () { - setTimeout(function () { - if (samba.restart) { - FnSambaRestart() - .finally(function () { - if (!display.silent) { - FnDisplayAlert({ status: "success", title: "Samba share successfully disabled", description: filesystem.name, breakword: false }, { name: "samba-disable", id: filesystem.id, timeout: 4 }); - } - - if (display.modal) { - $("#modal-storagepool-filesystem-samba-disable-" + filesystem.id).modal("hide"); - - setTimeout(function () { - FnStoragePoolRefresh({ name: pool.name, id: pool.id }, { storagepool: true, filesystems: true, snapshots: false, status: false }); - }, 200); - } - }); - } else { - FnSambaConfigurationReload() - .finally(function () { - if (!display.silent) { - FnDisplayAlert({ status: "success", title: "Samba share successfully disabled", description: filesystem.name, breakword: false }, { name: "samba-diable", id: filesystem.id, timeout: 4 }); - } - - if (display.modal) { - $("#modal-storagepool-filesystem-samba-disable-" + filesystem.id).modal("hide"); - - setTimeout(function () { - FnStoragePoolRefresh({ name: pool.name, id: pool.id }, { storagepool: true, filesystems: true, snapshots: false, status: false }); - }, 200); - } - }); - } - }, 500); - }) - .fail(function () { - FnFileSystemShareSmbEnable({ name: pool.name, id: pool.id }, { name: filesystem.name, id: filesystem.id }); - }); - }) - .fail(function () { - FnFileSystemShareSmbEnable({ name: pool.name, id: pool.id }, { name: filesystem.name, id: filesystem.id }); - }); -} - -function FnSambaShareEnable(pool = { name, id, readonly: false }, filesystem = { name, id, mounted: false, mountpoint }, samba = { share: { additional: [], administrative: false, browseable: true, guestok: false, name, comment, readonly: false, temporary: false } }, display = { silent: false }) { - let modal = { - hide: true - }; - - $("#spinner-storagepool-filesystem-samba-enable-" + filesystem.id + " span").text("Enabling Samba share..."); - - FnSambaShareNamesGet({ zfsonly: false }) - .done(function (data) { - FnConsole.log[4](FnConsoleVerbose({ data: data, message: "Samba, Share, Names, Get:" })); - - samba.share.nameunique = true; - samba.share.errormessage = "Share name is already in use."; - - if (data.replace(/\n/g, "") != "$empty") { //$empty response is received if share names list is empty - samba.shares = data.split(/\n/g).filter(v => v); - - samba.shares.forEach((_value, _index) => { - if (_value.replace(/^\[/, "").replace(/\]$/, "").toLowerCase() == samba.share.name.toLowerCase() + (samba.share.administrative ? "$" : "")) { - samba.share.nameunique = false; - - return; - } - }); - } - - if (/^global$|^homes$|^printers$/gi.test(samba.share.name)) { - samba.share.nameunique = false; - samba.share.errormessage = "Share name can not be a restricted name."; - } - - if (!samba.share.nameunique) { - modal.hide = false; - - $("#validationwrapper-storagepool-filesystem-samba-enable-name-" + filesystem.id).addClass("has-error"); - $("#helpblock-storagepool-filesystem-samba-enable-name-" + filesystem.id).addClass("has-error").removeClass("hidden").text(samba.share.errormessage); - $("#input-storagepool-filesystem-samba-enable-name-" + filesystem.id).focus(); - - if (!modal.hide) { - $("#spinner-storagepool-filesystem-samba-enable-" + filesystem.id).addClass("hidden"); - $("#spinner-storagepool-filesystem-samba-enable-" + filesystem.id + " span").text(""); - $("#btn-storagepool-filesystem-samba-enable-apply-" + filesystem.id).prop("disabled", false); - - FnConsole.warn("Samba, Share, Enable: Failed, Pool: " + pool.name + ", File System: " + filesystem.name + ", Message: " + samba.share.errormessage); - } - } else { - FnSambaShareEnableCommand({ name: pool.name, id: pool.id, readonly: pool.readonly }, { name: filesystem.name, id: filesystem.id, force: false, mounted: filesystem.mounted, mountpoint: filesystem.mountpoint, sharesmb: false }, { reload: true, share: { additional: samba.share.additional, administrative: samba.share.administrative, browseable: samba.share.browseable, guestok: samba.share.guestok, name: samba.share.name, comment: samba.share.comment, readonly: samba.share.readonly, temporary: samba.share.temporary } }, { refresh: true, silent: display.silent }); - - $("#modal-storagepool-filesystem-samba-enable-" + filesystem.id).modal("hide"); - } - }); -} - -function FnSambaShareEnableAutoGenerateName(pool = { name, id, altroot: false, readonly: false }, filesystem = { name, id, force: false, mounted: false, mountpoint, sharesmb: false }, samba = { reload: true }, display = { refresh: true, silent: false }) { - FnSambaShareNamesGet({ zfsonly: false }) - .done(function (data) { - FnConsole.log[4](FnConsoleVerbose({ data: data, message: "Samba, Share, Names, Get:" })); - - samba.share = { - name: "", - nameunique: true, - temporary: (pool.altroot || pool.readonly ? true : false) - };; - - if (data.replace(/\n/g, "") != "$empty") { //$empty response is received if share names list is empty - samba.shares = data.split(/\n/g).filter(v => v); - - samba.shares.forEach((_value, _index) => { - if (_value.replace(/^\[/, "").replace(/\]$/, "").toLowerCase() == filesystem.name.replace(/^.*\/(.*)$/, "$1").toLowerCase()) { - samba.share.nameunique = false; - - return; - } - }); - } - - if (/^global$|^homes$|^printers$/gi.test(samba.share.name)) { - samba.share.nameunique = false; - } - - if (!samba.share.nameunique) { - samba.share.name = FnGenerateShareName({ at: false, colon: false, period: false, whitespace: false }, { name: filesystem.name }); - - if (filesystem.name == pool.name) { - samba.share.name = "StoragePool-" + samba.share.name; - } - - FnSambaShareEnableCommand({ name: pool.name, id: pool.id, readonly: pool.readonly }, { name: filesystem.name, id: filesystem.id, force: false, mounted: filesystem.mounted, mountpoint: filesystem.mountpoint, sharesmb: filesystem.sharesmb }, { reload: samba.reload, share: { additional: [], administrative: false, browseable: true, guestok: false, name: samba.share.name, comment: null, readonly: null, temporary: samba.share.temporary } }, { refresh: display.refresh, silent: display.silent }); - } else { - FnSambaShareEnableCommand({ name: pool.name, id: pool.id, readonly: pool.readonly }, { name: filesystem.name, id: filesystem.id, force: false, mounted: filesystem.mounted, mountpoint: filesystem.mountpoint, sharesmb: filesystem.sharesmb }, { reload: samba.reload, share: { additional: [], administrative: false, browseable: true, guestok: false, name: null, comment: null, readonly: null, temporary: samba.share.temporary } }, { refresh: display.refresh, silent: display.silent }); - } - }); -} - -function FnSambaShareEnableCommand(pool = { name, id, readonly: false }, filesystem = { name, force: false, id, mounted: false, mountpoint, sharesmb: false }, samba = { reload: true, share: { additional: [], administrative: false, browseable: true, guestok: false, name, comment, readonly: false, temporary: false } }, display = { refresh: true, silent: false }) { - if (!pool.readonly && (!filesystem.sharesmb || filesystem.sharesmb && filesystem.force)) { //Force to disable inheritance - FnFileSystemShareSmbEnable({ name: pool.name, id: pool.id }, { name: filesystem.name, id: filesystem.id }) - .done(function () { - FnSambaShareEnableCommandFinally({ name: pool.name, id: pool.id }, { name: filesystem.name, id: filesystem.id, mounted: filesystem.mounted, mountpoint: filesystem.mountpoint }, { reload: samba.reload, share: { additional: samba.share.additional, administrative: samba.share.administrative, browseable: samba.share.browseable, guestok: samba.share.guestok, name: samba.share.name, comment: samba.share.comment, readonly: samba.share.readonly, temporary: samba.share.temporary } }, { refresh: display.refresh, silent: display.silent }); - }) - .fail(function (message, data) { - if (/property may be set/gi.test(data)) { //False error is generated when configuring filesystem - FnSambaShareEnableCommandFinally({ name: pool.name, id: pool.id }, { name: filesystem.name, id: filesystem.id, mounted: filesystem.mounted, mountpoint: filesystem.mountpoint }, { share: { additional: samba.share.additional, administrative: samba.share.administrative, browseable: samba.share.browseable, guestok: samba.share.guestok, name: samba.share.name, comment: samba.share.comment, readonly: samba.share.readonly, temporary: samba.share.temporary } }, { refresh: display.refresh, silent: display.silent }); - } else { - if (!display.silent) { - FnDisplayAlert({ status: "danger", title: "Samba share could not be enabled", description: filesystem.name, breakword: false }, { name: "samba-enable", id: filesystem.id, timeout: 4 }); - } - - setTimeout(function () { - FnStoragePoolRefresh({ name: pool.name, id: pool.id }, { storagepool: true, filesystems: true, snapshots: false, status: false }); - }, 200); - } - }); - } else { - FnSambaShareEnableCommandFinally({ name: pool.name, id: pool.id }, { name: filesystem.name, id: filesystem.id, mounted: filesystem.mounted, mountpoint: filesystem.mountpoint }, { reload: samba.reload, share: { additional: samba.share.additional, administrative: samba.share.administrative, browseable: samba.share.browseable, guestok: samba.share.guestok, name: samba.share.name, comment: samba.share.comment, readonly: samba.share.readonly, temporary: samba.share.temporary } }, { refresh: display.refresh, silent: display.silent }); - } -} - -function FnSambaShareEnableCommandFinally(pool = { name, id }, filesystem = { name, id, mounted: false, mountpoint }, samba = { reload: true, share: { additional: [], administrative: false, browseable: true, guestok: false, name, comment, readonly: false, temporary: false } }, display = { refresh: true, silent: false }) { - FnSambaZfsShareEnable({ name: pool.name, id: pool.id }, { name: filesystem.name, id: filesystem.id, mountpoint: filesystem.mountpoint }, { share: { additional: samba.share.additional, administrative: samba.share.administrative, browseable: samba.share.browseable, guestok: samba.share.guestok, name: samba.share.name, comment: samba.share.comment, readonly: samba.share.readonly, temporary: samba.share.temporary } }) - .done(function () { - if (!display.silent) { - FnDisplayAlert({ status: "success", title: "Samba share successfully enabled", description: filesystem.name, breakword: false }, { name: "samba-enable", id: filesystem.id, timeout: 4 }); - } - - if (samba.reload) { - FnSambaZfsSharesConfigurationReload() - .done(function () { - setTimeout(function () { - FnSambaConfigurationReload() - .finally(function () { - if (display.refresh) { - setTimeout(function () { - FnStoragePoolRefresh({ name: pool.name, id: pool.id }, { storagepool: true, filesystems: true, snapshots: false, status: false }); - }, 200); - } - }); - }, 500); - }) - .fail(function () { - FnFileSystemShareSmbDisable({ name: pool.name, id: pool.id }, { name: filesystem.name, id: filesystem.id }); - }); - } else { - if (display.refresh) { - setTimeout(function () { - FnStoragePoolRefresh({ name: pool.name, id: pool.id }, { storagepool: true, filesystems: true, snapshots: false, status: false }); - }, 200); - } - } - }) - .fail(function () { - FnFileSystemShareSmbDisable({ name: pool.name, id: pool.id }, { name: filesystem.name, id: filesystem.id }); - }); -} - -function FnSambaShareEnableMountpointGet(pool = { name, id, altroot: false, readonly: false }, filesystem = { name, id, sharesmb: false }, display = { silent: false }) { - let process = { - command: ["/sbin/zfs", "list", "-H", "-o", "mounted,mountpoint", "-t", "filesystem", filesystem.name] - }; - - FnConsole.log[2]("File Systems, Mountpoint, Get: In Progress, Pool: " + pool.name + ", File System: " + filesystem.name); - FnConsole.log[3](FnConsoleCommand({ command: process.command })); - - return cockpit.spawn(process.command, { err: "out" }) - .done(function (data, message) { - FnConsole.log[4](FnConsoleVerbose({ data: data, message: "File Systems, Mountpoint, Get:" })); - - data = data.replace(/\n/g, "").replace(/\t/g, "\u22C5").split("\u22C5"); - - filesystem.mounted = data[0]; - filesystem.mountpoint = data[1]; - - if (/^\//.test(filesystem.mountpoint)) { - FnConsole.log[1]("File Systems, Mountpoint, Get: Success, Pool: " + pool.name + ", File System: " + filesystem.name); - - FnSambaShareEnableAutoGenerateName({ name: pool.name, id: pool.id, altroot: pool.altroot, readonly: pool.readonly }, { name: filesystem.name, id: filesystem.id, force: false, mounted: filesystem.mounted, mountpoint: filesystem.mountpoint, sharesmb: filesystem.sharesmb }, { reload: true }, { refresh: true, silent: display.silent }); - } else { - FnConsole.warn("File Systems, Mountpoint, Get: Failed, Pool: " + pool.name + ", File System: " + filesystem.name + ", Message: " + (data ? data : message)); - } - }) - .fail(function (message, data) { - FnConsole.warn("File Systems, Mountpoint, Get: Failed, Pool: " + pool.name + ", File System: " + filesystem.name + ", Message: " + (data ? data : message)); - - FnFileSystemShareSmbDisable({ name: pool.name, id: pool.id }, { name: filesystem.name, id: filesystem.id }); - }); -} - -function FnSambaShareNamesGet(samba = { zfsonly: false }) { - let process = { - command: ["/bin/sh", "-c", `/bin/cat /etc/cockpit/zfs/shares/*.conf /run/cockpit/zfs/shares/*.conf ` + (!samba.zfsonly ? `/etc/samba/smb.conf ` : ``) + `2> /dev/null | /bin/grep "^\\\[.*\\\]$" || echo \\\$empty`] - }; - - FnConsole.log[2]("Samba, Share, Names, Get: In Progress"); - FnConsole.log[3](FnConsoleCommand({ command: process.command })); - - return cockpit.spawn(process.command, { err: "out" }) - .done(function () { - FnConsole.log[1]("Samba, Share, Names, Get: Success"); - }) - .fail(function (message, data) { - FnConsole.warn("Samba, Share, Names, Get: Failed, Message: " + (data ? data : message)); - }); -} - -function FnSambaSharesDestroy(pool = { name, id, altroot: false, readonly: false }, filesystems = { id: [] }, samba = { restart: false }, display = { silent: true }) { - let process = { - promise: cockpit.defer() - }; - let promise = Promise.resolve(); - - FnConsole.log[1]("Samba, Shares, Destroy: In Progress, Pool: " + pool.name); - - if (filesystems.id.length > 0) { - filesystems.id.forEach((_value, _index) => { - let filesystem = { - properties: _value.split(/\t/g).filter(v => v) - }; - - filesystem.name = filesystem.properties[0]; - filesystem.id = FnGenerateId({ at: true, colon: true, forwardslash: true, period: true, underscore: true, whitespace: true }, { name: filesystem.properties[0], attribute: true }); - filesystem.mounted = filesystem.properties[1]; - filesystem.mountpoint = filesystem.properties[2]; - filesystem.sharesmb = filesystem.properties[3]; - - promise = promise.then(_ => new Promise(resolve => - setTimeout(function () { - if (_index <= (filesystems.id.length - 1)) { - if (filesystem.sharesmb == "on") { - FnSambaZfsShareDisable({ name: pool.name, id: pool.id, altroot: pool.altroot, readonly: pool.readonly }, { name: filesystem.name, id: filesystem.id }); - } - } - - if (_index == (filesystems.id.length - 1)) { - setTimeout(function () { - if (!display.silent) { - FnDisplayAlert({ status: "success", title: "Samba shares successfully destroyed", description: pool.name, breakword: false }, { name: "samba-destroy", id: pool.id, timeout: 4 }); - } - - FnConsole.log[1]("Samba, Shares, Destroy: Success, Pool: " + pool.name); - - FnSambaZfsSharesConfigurationReload() - .done(function () { - setTimeout(function () { - if (samba.restart) { - FnSambaRestart() - .finally(function () { - process.promise.resolve(); - }); - } else { - FnSambaConfigurationReload() - .finally(function () { - process.promise.resolve(); - }); - } - }, 300); - }); - }, 500); - } - - resolve(); - }, 500) - )); - }); - } else { - if (!display.silent) { - FnDisplayAlert({ status: "success", title: "Samba shares successfully destroyed", description: pool.name, breakword: false }, { name: "samba-destroy", id: pool.id, timeout: 4 }); - } - - FnConsole.log[1]("Samba, Shares, Destroy: Success, Pool: " + pool.name); - - process.promise.resolve(); - } - - return process.promise.promise(); -} - -function FnSambaSharesDestroyAll(samba = { restart: false }, display = { silent: false }, modal = { name }) { - let process = { - command: ["/bin/sh", "-c", "echo '# COCKPIT ZFS MANAGER\n# WARNING: DO NOT EDIT, AUTO-GENERATED CONFIGURATION' > /etc/cockpit/zfs/shares.conf && echo '# COCKPIT ZFS MANAGER\n# WARNING: DO NOT EDIT, AUTO-GENERATED CONFIGURATION' > /run/cockpit/zfs/shares.conf && /bin/rm -rf /etc/cockpit/zfs/shares/*.conf && /bin/rm -rf /run/cockpit/zfs/shares/*.conf"], - promise: cockpit.defer() - }; - - FnConsole.log[1]("Samba, Shares, Destroy All: In Progress"); - FnConsole.log[3](FnConsoleCommand({ command: process.command })); - - $("#spinner-" + modal.name + " span").text("Destroying Samba shares..."); - - cockpit.spawn(process.command, { err: "out", superuser: "require" }) - .done(function () { - if (!display.silent) { - FnDisplayAlert({ status: "success", title: "Samba shares successfully destroyed", description: null, breakword: false }, { name: "samba-destroy-all", id: null, timeout: 4 }); - } - - FnConsole.log[1]("Samba, Shares, Destroy All: Success"); - - if (samba.restart) { - FnSambaRestart() - .finally(function () { - process.promise.resolve(); - }); - } else { - FnSambaConfigurationReload() - .finally(function () { - process.promise.resolve(); - }); - } - }) - .fail(function (message, data) { - if (!display.silent) { - FnDisplayAlert({ status: "danger", title: "Samba shares could not be destroyed", description: null, breakword: false }, { name: "samba-destroy-all", id: null, timeout: 4 }); - } - - FnConsole.warn("Samba, Shares, Destroy All: Failed, Message: " + (data ? data : message)); - - process.promise.resolve(); - }); - - return process.promise.promise(); -} - -function FnSambaSharesEnable(pool = { name, id, altroot: false, readonly: false }, filesystem = { name, force: false }, samba = { restart: false }, display = { refresh: false, silent: true }) { - let process = { - command: ["/sbin/zfs", "list", "-H", "-o", "name,mounted,mountpoint,sharesmb", "-r", "-t", "filesystem"], - promise: cockpit.defer() - }; - - if (filesystem.name) { - process.command.push(filesystem.name); - } else { - process.command.push(pool.name); - } - - FnConsole.log[1]("Samba, Shares, Enable: In Progress, Pool: " + pool.name); - FnConsole.log[3](FnConsoleCommand({ command: process.command })); - - cockpit.spawn(process.command, { err: "out" }) - .done(function (data) { - FnConsole.log[4](FnConsoleVerbose({ data: data, message: "Samba, Shares, Enable:" })); - - let filesystems = { - id: data.split(/\n/g).filter(v => v && /\ton$/i.test(v)) - }; - let promise = Promise.resolve(); - - if (filesystems.id.length > 0) { - filesystems.id.forEach((_value, _index) => { - let filesystem = { - properties: _value.split(/\t/g).filter(v => v) - }; - - filesystem.name = filesystem.properties[0]; - filesystem.id = FnGenerateId({ at: true, colon: true, forwardslash: true, period: true, underscore: true, whitespace: true }, { name: filesystem.properties[0], attribute: true }); - filesystem.mounted = filesystem.properties[1]; - filesystem.mountpoint = filesystem.properties[2]; - filesystem.sharesmb = filesystem.properties[3]; - - promise = promise.then(_ => new Promise(resolve => - setTimeout(function () { - if (_index <= (filesystems.id.length - 1)) { - if (filesystem.sharesmb == "on") { - FnSambaShareEnableAutoGenerateName({ name: pool.name, id: pool.id, altroot: pool.altroot, readonly: pool.readonly }, { name: filesystem.name, id: filesystem.id, force: filesystem.force, mounted: filesystem.mounted, mountpoint: filesystem.mountpoint, sharesmb: true }, { reload: false }, { refresh: false, silent: true }); - } - } - - if (_index == (filesystems.id.length - 1)) { - setTimeout(function () { - if (!display.silent) { - FnDisplayAlert({ status: "success", title: "Samba shares successfully enabled", description: pool.name, breakword: false }, { name: "samba-enable", id: pool.id, timeout: 4 }); - } - - FnConsole.log[1]("Samba, Shares, Enable: Success, Pool: " + pool.name); - - FnSambaZfsSharesConfigurationReload() - .done(function () { - setTimeout(function () { - if (samba.restart) { - FnSambaRestart() - .finally(function () { - if (display.refresh) { - setTimeout(function () { - FnStoragePoolRefresh({ name: pool.name, id: pool.id }, { storagepool: true, filesystems: true, snapshots: true, status: false }); - }, 500); - } - - process.promise.resolve(); - }); - } else { - FnSambaConfigurationReload() - .finally(function () { - if (display.refresh) { - setTimeout(function () { - FnStoragePoolRefresh({ name: pool.name, id: pool.id }, { storagepool: true, filesystems: true, snapshots: true, status: false }); - }, 500); - } - - process.promise.resolve(); - }); - } - }, 300); - }); - }, 500); - } - - resolve(); - }, 500) - )); - }); - } else { - if (!display.silent) { - FnDisplayAlert({ status: "success", title: "Samba shares successfully enabled", description: pool.name, breakword: false }, { name: "samba-enable", id: pool.id, timeout: 4 }); - } - - FnConsole.log[1]("Samba, Shares, Enable: Success, Pool: " + pool.name); - - process.promise.resolve(); - } - }) - .fail(function (message, data) { - if (!display.silent) { - FnDisplayAlert({ status: "danger", title: "Samba shares could not enabled", description: pool.name, breakword: false }, { name: "samba-enable", id: pool.id, timeout: 4 }); - } - - FnConsole.warn("Samba, Shares, Enable: Failed, Pool: " + pool.name + ", Message: " + (data ? data : message)); - - if (display.refresh) { - setTimeout(function () { - FnStoragePoolRefresh({ name: pool.name, id: pool.id }, { storagepool: true, filesystems: true, snapshots: true, status: false }); - }, 500); - } - - process.promise.resolve(); - }); - - return process.promise.promise(); -} - -function FnSambaSharesEnableAll(samba = { restart: false }, display = { silent: false }, modal = { name }) { - let process = { - command: ["/sbin/zfs", "list", "-H", "-o", "name,mounted,mountpoint,sharesmb", "-r", "-t", "filesystem"], - promise: cockpit.defer() - }; - - FnConsole.log[1]("Samba, Shares, Enable All: In Progress"); - FnConsole.log[3](FnConsoleCommand({ command: process.command })); - - FnStoragePoolsTemporaryGet() - .done(function (data) { - FnConsole.log[4](FnConsoleVerbose({ data: data, message: "Storage Pools, Temporary, Get:" })); - - $("#spinner-" + modal.name + " span").text("Disabling Samba share inheritance..."); - - FnFileSystemShareSmbInheritedDisable({ name: null, id: null, altroot: null }, { name: null }, { disable: false }) - .finally(function () { - $("#spinner-" + modal.name + " span").text("Creating Samba shares..."); - - cockpit.spawn(process.command, { err: "out" }) - .done(function (_data) { - FnConsole.log[4](FnConsoleVerbose({ data: _data, message: "Samba, Shares, Enable All:" })); - - let filesystems = { - id: _data.split(/\n/g).filter(v => v && /\ton$/i.test(v)) - }; - let promise = Promise.resolve(); - - if (filesystems.id.length > 0) { - filesystems.id.forEach((_value, _index) => { - let filesystem = { - properties: _value.split(/\t/g).filter(v => v) - }; - let pool = { - name: filesystem.properties[0].replace(/\/.*$/, ""), - id: FnGenerateId({ at: true, colon: true, forwardslash: true, period: true, underscore: true, whitespace: true }, { name: filesystem.properties[0].replace(/\/.*$/, ""), attribute: true }) - }; - - filesystem.name = filesystem.properties[0]; - filesystem.id = FnGenerateId({ at: true, colon: true, forwardslash: true, period: true, underscore: true, whitespace: true }, { name: filesystem.properties[0], attribute: true }); - filesystem.mounted = filesystem.properties[1]; - filesystem.mountpoint = filesystem.properties[2]; - filesystem.sharesmb = filesystem.properties[3]; - - promise = promise.then(_ => new Promise(resolve => - setTimeout(function () { - if (_index <= (filesystems.id.length - 1)) { - if (filesystem.sharesmb == "on") { - - pool.properties = data.split(/\n/g).filter(v => v && new RegExp("^" + pool.name + "\t").test(v))[0].split(/\t/g).filter(v => v); - - if (pool.properties[0] == pool.name) { - pool.altroot = (pool.properties[2] && pool.properties[2] != "-" ? true : false); - pool.readonly = (pool.properties[1].toLowerCase() == "on" ? true : false); - - FnSambaShareEnableAutoGenerateName({ name: pool.name, id: pool.id, altroot: pool.altroot, readonly: pool.readonly }, { name: filesystem.name, id: filesystem.id, force: false, mounted: filesystem.mounted, mountpoint: filesystem.mountpoint, sharesmb: true }, { reload: false }, { refresh: false, silent: true }); - } - } - } - - if (_index == (filesystems.id.length - 1)) { - setTimeout(function () { - if (!display.silent) { - FnDisplayAlert({ status: "success", title: "Samba shares successfully enabled", description: null, breakword: false }, { name: "samba-enable-all", id: null, timeout: 4 }); - } - - FnConsole.log[1]("Samba, Shares, Enable All: Success"); - - FnSambaZfsSharesConfigurationReload() - .done(function () { - setTimeout(function () { - if (samba.restart) { - FnSambaRestart() - .finally(function () { - process.promise.resolve(); - }); - } else { - FnSambaConfigurationReload() - .finally(function () { - process.promise.resolve(); - }); - } - }, 300); - }); - }, 500); - } - - resolve(); - }, 500) - )); - }); - } else { - if (!display.silent) { - FnDisplayAlert({ status: "success", title: "Samba shares successfully enabled", description: null, breakword: false }, { name: "samba-enable-all", id: null, timeout: 4 }); - } - - FnConsole.log[1]("Samba, Shares, Enable All: Success"); - - process.promise.resolve(); - } - }) - .fail(function (message, data) { - if (!display.silent) { - FnDisplayAlert({ status: "danger", title: "Samba shares could not be enabled", description: null, breakword: false }, { name: "samba-enable-all", id: null, timeout: 4 }); - } - - FnConsole.warn("Samba, Shares, Enable All: Failed, Message: " + (data ? data : message)); - - process.promise.resolve(); - }); - }); - }) - .fail(function (message, data) { - if (!display.silent) { - FnDisplayAlert({ status: "danger", title: "Samba shares could not be enabled", description: null, breakword: false }, { name: "samba-enable-all", id: null, timeout: 4 }); - } - - FnConsole.warn("Samba, Shares, Enable All: Failed, Message: " + (data ? data : message)); - - process.promise.resolve(); - }); - - return process.promise.promise(); -} - -function FnSambaSharesGet(pool = { name, id }, filesystem = { name, clones: [] }) { - let process = { - command: ["/sbin/zfs", "list", "-H", "-o", "name,mounted,mountpoint,sharesmb", "-r", "-t", "filesystem"] - }; - - if (filesystem.name) { - process.command.push(filesystem.name); - } else if (filesystem.clones.length > 0) { - filesystem.clones.forEach(_value => _value && process.command.push(_value)); - } else { - process.command.push(pool.name); - } - - FnConsole.log[2]("Samba, Shares, Get: In Progress, Pool: " + pool.name); - FnConsole.log[3](FnConsoleCommand({ command: process.command })); - - return cockpit.spawn(process.command, { err: "out" }) - .done(function () { - FnConsole.log[1]("Samba, Shares, Get: Success, Pool: " + pool.name); - }) - .fail(function (message, data) { - FnConsole.warn("Samba, Shares, Get: Failed, Pool: " + pool.name + ", Message: " + (data ? data : message)); - }); -} - -function FnSambaSharesRename(pool = { name, id, altroot: false, readonly: false }, filesystems = { id: [], parent: { name, namenew } }, samba = { restart: false }, display = { silent: true }) { - let process = { - promise: cockpit.defer() - }; - let promise = Promise.resolve(); - - FnConsole.log[1]("Samba, Shares, Rename: In Progress, Pool: " + pool.name); - - if (filesystems.id.length > 0) { - filesystems.id.forEach((_value, _index) => { - let filesystem = { - properties: _value.split(/\t/g).filter(v => v) - }; - - filesystem.name = filesystem.properties[0]; - filesystem.id = FnGenerateId({ at: true, colon: true, forwardslash: true, period: true, underscore: true, whitespace: true }, { name: filesystem.properties[0], attribute: true }); - filesystem.mounted = filesystem.properties[1]; - filesystem.mountpoint = filesystem.properties[2]; - filesystem.sharesmb = filesystem.properties[3]; - - filesystem.namenew = filesystem.name.replace(new RegExp("^" + filesystems.parent.name), filesystems.parent.namenew); - filesystem.idnew = FnGenerateId({ at: true, colon: true, forwardslash: true, period: true, underscore: true, whitespace: true }, { name: filesystem.namenew, attribute: true }); - - promise = promise.then(_ => new Promise(resolve => - setTimeout(function () { - if (_index <= (filesystems.id.length - 1)) { - if (filesystem.sharesmb == "on") { - FnFileSystemMountpointGet({ name: pool.name, id: pool.id }, { name: filesystem.namenew, id: filesystem.idnew }) - .done(function (data) { - filesystem.mountpoint = data.replace(/\n$/, ""); - - FnSambaZfsShareConfigurationPathSet({ name: pool.name, id: pool.id, altroot: pool.altroot }, { name: filesystem.name, namenew: filesystem.namenew, id: filesystem.id, mountpoint: filesystem.mountpoint }) - .finally(function () { - FnSambaZfsShareDisable({ name: pool.name, id: pool.id, altroot: pool.altroot, readonly: pool.readonly }, { name: filesystem.name, id: filesystem.id }); - }); - }); - } - } - - if (_index == (filesystems.id.length - 1)) { - setTimeout(function () { - if (!display.silent) { - FnDisplayAlert({ status: "success", title: "Samba shares successfully renamed", description: pool.name, breakword: false }, { name: "samba-rename", id: pool.id, timeout: 4 }); - } - - FnConsole.log[1]("Samba, Shares, Rename: Success, Pool: " + pool.name); - - FnSambaZfsSharesConfigurationReload() - .done(function () { - setTimeout(function () { - if (samba.restart) { - FnSambaRestart() - .finally(function () { - process.promise.resolve(); - }); - } else { - FnSambaConfigurationReload() - .finally(function () { - process.promise.resolve(); - }); - } - }, 300); - }); - }, 800); - } - - resolve(); - }, 800) - )); - }); - } else { - if (!display.silent) { - FnDisplayAlert({ status: "success", title: "Samba shares successfully renamed", description: pool.name, breakword: false }, { name: "samba-rename", id: pool.id, timeout: 4 }); - } - - FnConsole.log[1]("Samba, Shares, Rename: Success, Pool: " + pool.name); - - process.promise.resolve(); - } - - return process.promise.promise(); -} - -function FnSambaStart() { - let process = { - command: ["/bin/systemctl", "start"] - }; - - if (/Debian|Ubuntu/i.test(zfsmanager.system.operatingsystem)) { - process.command.splice(2, 0, "smbd"); - } else { - process.command.splice(2, 0, "smb"); - } - - FnConsole.log[2]("Samba, Start: In Progress"); - FnConsole.log[3](FnConsoleCommand({ command: process.command })); - - return cockpit.spawn(process.command, { err: "out", superuser: "require" }) - .done(function () { - FnConsole.log[1]("Samba, Start: Success"); - }) - .fail(function (message, data) { - FnConsole.warn("Samba, Start: Failed, Message: " + (data ? data : message)); - }); -} - -function FnSambaStop() { - let process = { - command: ["/bin/systemctl", "stop"] - }; - - if (/Debian|Ubuntu/i.test(zfsmanager.system.operatingsystem)) { - process.command.splice(2, 0, "smbd"); - } else { - process.command.splice(2, 0, "smb"); - } - - FnConsole.log[2]("Samba, Stop: In Progress"); - FnConsole.log[3](FnConsoleCommand({ command: process.command })); - - return cockpit.spawn(process.command, { err: "out", superuser: "require" }) - .done(function () { - FnConsole.log[1]("Samba, Stop: Success"); - }) - .fail(function (message, data) { - FnConsole.warn("Samba, Stop: Failed, Message: " + (data ? data : message)); - }); -} - -function FnSambaUsersharesDirectoryCreate() { - let process = { - command: ["/bin/sh", "-c", `[ ! -d /var/lib/samba/usershares ] && /bin/mkdir -p /var/lib/samba/usershares || printf "Skipped"`] - }; - - FnConsole.log[2]("Samba, Usershares Directory, Create: In Progress") - FnConsole.log[3](FnConsoleCommand({ command: process.command })); - - return cockpit.spawn(process.command, { err: "out", superuser: "require" }) - .done(function (data) { - FnConsole.log[4](FnConsoleVerbose({ data: data, message: "Samba, Usershares Directory, Create:" })); - - if (data == "Skipped") { - FnConsole.log[2]("Samba, Usershares Directory, Create: Skipped"); - } else { - FnConsole.log[1]("Samba, Usershares Directory, Create: Success"); - } - }) - .fail(function (message, data) { - FnConsole.warn("Samba, Usershares Directory, Create: Failed, Message: " + (data ? data : message)); - }); -} - -function FnSambaVersionGet() { - let process = { - command: ["/usr/sbin/smbd", "-V"] - }; - let samba = { - message: "" - }; - - FnConsole.log[2]("Samba, Version, Get: In Progress"); - FnConsole.log[3](FnConsoleCommand({ command: process.command })); - - return cockpit.spawn(process.command, { err: "out" }) - .done(function (data, message) { - FnConsole.log[4](FnConsoleVerbose({ data: data, message: "Samba, Version, Get:" })); - - FnConsole.log[1]("Samba, Version, Get: Success, Version: " + (data ? data.replace(/^Version /i, "") : message.replace(/^Version /i, ""))); - - $("#alerts-requirements").empty().addClass("hidden"); - $("#container").removeClass("hidden"); - }) - .fail(function (message, data) { - FnConsole.error("Samba, Version, Get: Failed, Message: " + (data ? data : message)); - - samba.message = ` -
    - -
    -

    This package requires Samba

    -

    Install Samba software via your package manager

    -
    - -
    - `; - - $("#alerts-requirements").removeClass("hidden").html(samba.message); - $("#container").addClass("hidden"); - }); -} - -function FnSambaZfsShareConfigurationGenerate(filesystem = { name, id, mountpoint }, samba = { enable: false, share: { additional: [], administrative: false, browseable: true, guestok: false, name, comment, readonly: false, temporary: false } }) { - samba.share.conf = { - content: "", - path: "/" + (samba.share.temporary ? "run" : "etc") + "/cockpit/zfs/shares/" + FnGenerateShareFileName({ name: filesystem.name }) + ".conf" - } - - if (!samba.share.name) { - samba.share.name = FnGenerateShareName({ at: false, colon: false, period: false, whitespace: false }, { name: filesystem.name.replace(/^.*\/(.*)$/, "$1") }); - } - if (samba.share.administrative) { - samba.share.name = samba.share.name + "$"; - } - if (!samba.share.comment && samba.enable) { - samba.share.comment = "ZFS: " + filesystem.name; - } - - samba.share.additional = samba.share.additional.reduce((a, v) => { - let allow = true; - - if (/[\[\]]/g.test(v)) { //Do not allow section names - allow = false; - } - if (/^[#]/.test(v) == false && /[=]/.test(v)) { //Do not allow modal configurable properties - if (/(path|comment|browseable|read only|guest ok).*=/gi.test(v)) { - allow = false; - } - } - - if (allow) { - v = v.replace(/\\/g, "\\\\\\"); - - a.push((/^[#]/.test(v) == false && /[=]/.test(v) ? "\\t" + v : v)); - } - - return a; - }, []); - - samba.share.conf.content = "\"# COCKPIT ZFS MANAGER\n# WARNING: DO NOT EDIT, AUTO-GENERATED CONFIGURATION\\n\[" + samba.share.name + "\]\\n\\tpath \= " + filesystem.mountpoint + "\\n\\tcomment \= " + samba.share.comment + "\\n\\tbrowseable = " + (samba.share.browseable ? "yes" : "no") + "\\n\\tread only = " + (samba.share.readonly ? "yes" : "no") + "\\n\\tguest ok = " + (samba.share.guestok ? "yes" : "no") + "\\n\\n# ADD ADDITIONAL CONFIGURATION HERE\\n" + samba.share.additional.join("\\n") + "\\n\" > \"" + samba.share.conf.path + "\""; - - return samba.share.conf.content; -} - -function FnSambaZfsShareConfigurationGet(pool = { name, id, altroot: false, readonly: false }, filesystem = { name, id }, modal = { name, id }) { - let process = { - command: ["/bin/cat", "/" + (pool.altroot || pool.readonly ? "run" : "etc") + "/cockpit/zfs/shares/" + FnGenerateShareFileName({ name: filesystem.name }) + ".conf"] - }; - let samba = { - share: { - name: "", - path: "", - comment: "", - administrative: false, - browseable: true, - guestok: false, - readonly: false, - additional: [] - } - }; - - FnConsole.log[2]("Samba, ZFS Share Configuration, Get: In Progress, Pool: " + pool.name + ", File System: " + filesystem.name); - FnConsole.log[3](FnConsoleCommand({ command: process.command })); - - return cockpit.spawn(process.command, { err: "out" }) - .done(function (data) { - FnConsole.log[4](FnConsoleVerbose({ data: data, message: "Samba, ZFS Share Configuration, Get:" })); - - samba.share.conf = data.split(/\n/g).filter(v => v); - - samba.share.conf.forEach((_value, _index) => { - _value = _value.replace(/\t/g, ""); - - //2=name, 3=path, 4=comment, 5=browseable, 6=read only, 7=guest ok - - switch (_index) { - case 2: //2=name - if (/^\[.*\]$/g.test(_value)) { - samba.share.name = _value.replace(/\[/g, "").replace(/\]/g, ""); - - if (/[$]$/.test(samba.share.name)) { - samba.share.administrative = true; - samba.share.name = samba.share.name.replace(/[$]$/, ""); - } - } - - break; - case 3: //3=path - if (/path \=/gi.test(_value)) { - samba.share.path = _value.replace("path = ", "").replace(/["]/g, ""); - } - - break; - case 4: //4=comment - if (/comment \=/gi.test(_value)) { - samba.share.comment = _value.replace("comment = ", "").replace(/["]/g, ""); - } - - break; - case 5: //5=browseable - if (/browseable \=/gi.test(_value)) { - samba.share.browseable = (_value.replace("browseable = ", "").replace(/["]/g, "") == "yes" ? true : false); - } - - break; - case 6: //6=read only - if (/read only \=/gi.test(_value)) { - samba.share.readonly = (_value.replace("read only = ", "").replace(/["]/g, "") == "yes" ? true : false); - } - - break; - case 7: //7=guest ok - if (/guest ok \=/gi.test(_value)) { - samba.share.guestok = (_value.replace("guest ok = ", "").replace(/["]/g, "") == "yes" ? true : false); - } - - break; - } - }); - - samba.share.additional = samba.share.conf.filter((v, i) => i > 8).map(v => v.replace(/^\s+/, "")); - - FnConsole.log[1]("Samba, ZFS Share Configuration, Get: Success, Pool: " + pool.name + ", File System: " + filesystem.name); - }) - .fail(function (message, data) { - FnConsole.warn("Samba, ZFS Share Configuration, Get: Failed, Pool: " + pool.name + ", File System: " + filesystem.name + ", Message: " + (data ? data : message)); - }) - .finally(function () { - $("#input-" + modal.name + "-name-" + modal.id).val(samba.share.name).attr("data-field-value", samba.share.name); - $("#input-" + modal.name + "-comment-" + modal.id).val(samba.share.comment); - $("#textarea-" + modal.name + "-additional-" + modal.id).val(samba.share.additional.join("\n")); - - if (samba.share.administrative && !$("#switch-" + modal.name + "-administrative-" + modal.id + " input").prop("checked")) { - $("#switch-" + modal.name + "-administrative-" + modal.id + " input").click(); - } - if (!samba.share.browseable && $("#switch-" + modal.name + "-browseable-" + modal.id + " input").prop("checked")) { - $("#switch-" + modal.name + "-browseable-" + modal.id + " input").click(); - } - if (samba.share.guestok && !$("#switch-" + modal.name + "-guestok-" + modal.id + " input").prop("checked")) { - $("#switch-" + modal.name + "-guestok-" + modal.id + " input").click(); - } - if (samba.share.readonly && !$("#switch-" + modal.name + "-readonly-" + modal.id + " input").prop("checked")) { - $("#switch-" + modal.name + "-readonly-" + modal.id + " input").click(); - } - - if (!samba.share.name) { - $("#alert-" + modal.name + "-configurationmissing-" + modal.id).removeClass("hidden"); - - $("#input-" + modal.name + "-name-" + modal.id).val(FnGenerateShareName({ at: false, colon: false, period: false, whitespace: false }, { name: filesystem.name.replace(/^.*\/(.*)$/, "$1") })).focus(); - if (!samba.share.comment) { - $("#input-" + modal.name + "-comment-" + modal.id).val("ZFS: " + filesystem.name); - } - } - if (samba.share.additional.length > 0 && !$("#switch-" + modal.name + "-additional-" + modal.id + " input").prop("checked")) { - $("#switch-" + modal.name + "-additional-" + modal.id + " input").click(); - } - }); -} - -function FnSambaZfsShareConfigurationPathSet(pool = { name, id, altroot: false }, filesystem = { name, namenew, id, mountpoint }, display = { silent: true }) { - let process = { - command: ["/bin/cat", "/" + (pool.altroot ? "run" : "etc") + "/cockpit/zfs/shares/" + FnGenerateShareFileName({ name: filesystem.name }) + ".conf"], - promise: cockpit.defer() - }; - let samba = { - share: { - name: "", - path: "", - comment: "", - administrative: false, - browseable: true, - guestok: false, - readonly: false, - temporary: (pool.altroot ? true : false), - additional: [] - } - }; - - FnConsole.log[2]("Samba, ZFS Share Configuration, Get: In Progress, Pool: " + pool.name + ", File System: " + filesystem.name); - FnConsole.log[3](FnConsoleCommand({ command: process.command })); - - cockpit.spawn(process.command, { err: "out" }) - .done(function (data) { - FnConsole.log[4](FnConsoleVerbose({ data: data, message: "Samba, ZFS Share Configuration, Get:" })); - - samba.share.conf = data.split(/\n/g).filter(v => v); - - samba.share.conf.forEach((_value, _index) => { - _value = _value.replace(/\t/g, ""); - - //2=name, 3=path, 4=comment, 5=browseable, 6=read only, 7=guest ok - - switch (_index) { - case 2: //2=name - if (/^\[.*\]$/g.test(_value)) { - samba.share.name = _value.replace(/\[/g, "").replace(/\]/g, ""); - - if (/[$]$/.test(samba.share.name)) { - samba.share.administrative = true; - samba.share.name = samba.share.name.replace(/[$]$/, ""); - } - } - - break; - case 3: //3=path - if (/path \=/gi.test(_value)) { - samba.share.path = _value.replace("path = ", "").replace(/["]/g, ""); - } - - break; - case 4: //4=comment - if (/comment \=/gi.test(_value)) { - samba.share.comment = _value.replace("comment = ", "").replace(/["]/g, ""); - } - - break; - case 5: //5=browseable - if (/browseable \=/gi.test(_value)) { - samba.share.browseable = (_value.replace("browseable = ", "").replace(/["]/g, "") == "yes" ? true : false); - } - - break; - case 6: //6=read only - if (/read only \=/gi.test(_value)) { - samba.share.readonly = (_value.replace("read only = ", "").replace(/["]/g, "") == "yes" ? true : false); - } - - break; - case 7: //7=guest ok - if (/guest ok \=/gi.test(_value)) { - samba.share.guestok = (_value.replace("guest ok = ", "").replace(/["]/g, "") == "yes" ? true : false); - } - - break; - } - }); - - samba.share.additional = samba.share.conf.filter((v, i) => i > 8).map(v => v.replace(/^\s+/, "")); - - FnConsole.log[1]("Samba, ZFS Share Configuration, Get: Success, Pool: " + pool.name + ", File System: " + filesystem.name); - - if (filesystem.mountpoint != samba.share.path || filesystem.namenew) { - if (filesystem.namenew) { - if ((filesystem.name.replace(/^.*\/(.*)$/, "$1") != filesystem.namenew.replace(/^.*\/(.*)$/, "$1") && samba.share.name.toLowerCase() == FnGenerateShareName({ at: false, colon: false, period: false, whitespace: false }, { name: filesystem.name.replace(/^.*\/(.*)$/, "$1") }).toLowerCase()) || samba.share.name.toLowerCase() == FnGenerateShareName({ at: false, colon: false, period: false, whitespace: false }, { name: filesystem.name }).toLowerCase()) { - samba.share.nameunique = true; - - FnSambaShareNamesGet({ zfsonly: false }) - .done(function (data) { - FnConsole.log[4](FnConsoleVerbose({ data: data, message: "Samba, Share, Names, Get:" })); - - if (data.replace(/\n/g, "") != "$empty") { //$empty response is received if share names list is empty - samba.shares = data.split(/\n/g).filter(v => v); - - samba.shares.forEach((_value, _index) => { - if (_value.replace(/^\[/, "").replace(/\]$/, "").toLowerCase() == filesystem.namenew.replace(/^.*\/(.*)$/, "$1").toLowerCase() + (samba.share.administrative ? "$" : "")) { - samba.share.nameunique = false; - - return; - } - }); - } - - if (/^global$|^homes$|^printers$/gi.test(samba.share.name)) { - samba.share.nameunique = false; - } - - if (!samba.share.nameunique) { - samba.share.name = FnGenerateShareName({ at: false, colon: false, period: false, whitespace: false }, { name: filesystem.namenew }); - } else { - samba.share.name = FnGenerateShareName({ at: false, colon: false, period: false, whitespace: false }, { name: filesystem.namenew.replace(/^.*\/(.*)$/, "$1") }); - } - - filesystem.name = filesystem.namenew; - samba.share.comment = "ZFS: " + filesystem.namenew; - - FnSambaZfsShareConfigurationPathSetCommand({ name: pool.name, id: pool.id }, { name: filesystem.name, id: filesystem.id, mountpoint: filesystem.mountpoint }, { share: { additional: samba.share.additional, administrative: samba.share.administrative, browseable: samba.share.browseable, guestok: samba.share.guestok, name: samba.share.name, comment: samba.share.comment, readonly: samba.share.readonly, temporary: samba.share.temporary } }, { silent: display.silent }) - .finally(function () { - process.promise.resolve(); - }); - }) - .fail(function () { - filesystem.name = filesystem.namenew; - samba.share.comment = "ZFS: " + filesystem.namenew; - samba.share.name = FnGenerateShareName({ at: false, colon: false, period: false, whitespace: false }, { name: filesystem.namenew }); - - FnSambaZfsShareConfigurationPathSetCommand({ name: pool.name, id: pool.id }, { name: filesystem.name, id: filesystem.id, mountpoint: filesystem.mountpoint }, { share: { additional: samba.share.additional, administrative: samba.share.administrative, browseable: samba.share.browseable, guestok: samba.share.guestok, name: samba.share.name, comment: samba.share.comment, readonly: samba.share.readonly, temporary: samba.share.temporary } }, { silent: display.silent }) - .finally(function () { - process.promise.resolve(); - }); - }); - } else { - filesystem.name = filesystem.namenew; - samba.share.comment = "ZFS: " + filesystem.namenew; - - FnSambaZfsShareConfigurationPathSetCommand({ name: pool.name, id: pool.id }, { name: filesystem.name, id: filesystem.id, mountpoint: filesystem.mountpoint }, { share: { additional: samba.share.additional, administrative: samba.share.administrative, browseable: samba.share.browseable, guestok: samba.share.guestok, name: samba.share.name, comment: samba.share.comment, readonly: samba.share.readonly, temporary: samba.share.temporary } }, { silent: display.silent }) - .finally(function () { - process.promise.resolve(); - }); - } - } else { - FnSambaZfsShareConfigurationPathSetCommand({ name: pool.name, id: pool.id }, { name: filesystem.name, id: filesystem.id, mountpoint: filesystem.mountpoint }, { share: { additional: samba.share.additional, administrative: samba.share.administrative, browseable: samba.share.browseable, guestok: samba.share.guestok, name: samba.share.name, comment: samba.share.comment, readonly: samba.share.readonly, temporary: samba.share.temporary } }, { silent: display.silent }) - .finally(function () { - process.promise.resolve(); - }); - } - } else { - process.promise.resolve(); - } - }) - .fail(function (message, data) { - FnConsole.warn("Samba, ZFS Share Configuration, Get: Failed, Pool: " + pool.name + ", File System: " + filesystem.name + ", Message: " + (data ? data : message)); - - process.promise.resolve(); - }); - - return process.promise.promise(); -} - -function FnSambaZfsShareConfigurationPathSetCommand(pool = { name, id }, filesystem = { name, id, mountpoint }, samba = { share: { additional: [], administrative: false, browseable: true, guestok: false, name, comment, readonly: false, temporary: false } }, display = { silent: true }) { - let process = { - command: ["/bin/sh", "-c", "printf " + FnSambaZfsShareConfigurationGenerate({ name: filesystem.name, id: filesystem.id, mountpoint: filesystem.mountpoint }, { enable: false, share: { additional: samba.share.additional, administrative: samba.share.administrative, browseable: samba.share.browseable, guestok: samba.share.guestok, name: samba.share.name, comment: samba.share.comment, readonly: samba.share.readonly, temporary: samba.share.temporary } })] - }; - - FnConsole.log[2]("Samba, ZFS Share Configuration, Path, Set: In Progress, Pool: " + pool.name + ", File System: " + filesystem.name); - FnConsole.log[3](FnConsoleCommand({ command: process.command })); - - return cockpit.spawn(process.command, { err: "out", superuser: "require" }) - .done(function () { - if (!display.silent) { - FnDisplayAlert({ status: "success", title: "Samba share configuration successfully updated", description: filesystem.name, breakword: false }, { name: "samba-configure-share", id: filesystem.id, timeout: 4 }); - } - - FnConsole.log[1]("Samba, ZFS Share Configuration, Path, Set: Success, Pool: " + pool.name + ", File System: " + filesystem.name); - }) - .fail(function (message, data) { - if (!display.silent) { - FnDisplayAlert({ status: "danger", title: "Samba share configuration could not be updated", description: filesystem.name, breakword: false }, { name: "samba-configure-share", id: filesystem.id, timeout: 4 }); - } - - FnConsole.warn("Samba, ZFS Share Configuration, Path, Set: Failed, Pool: " + pool.name + ", File System: " + filesystem.name + ", Message: " + (data ? data : message)); - }); -} - -function FnSambaZfsShareConfigurationPathsSet(pool = { name, id, altroot: false }, filesystem = { name }, samba = { restart: false }, display = { refresh: false, silent: true }) { - let process = { - command: ["/sbin/zfs", "list", "-H", "-o", "name,mounted,mountpoint,sharesmb", "-r", "-t", "filesystem", filesystem.name], - promise: cockpit.defer() - }; - - FnConsole.log[2]("Samba, ZFS Share Configuration, Paths, Set: In Progress, Pool: " + pool.name + ", File System: " + filesystem.name); - FnConsole.log[3](FnConsoleCommand({ command: process.command })); - - cockpit.spawn(process.command, { err: "out" }) - .done(function (data) { - FnConsole.log[4](FnConsoleVerbose({ data: data, message: "Samba, ZFS Share Configuration, Paths, Set:" })); - - let filesystems = { - id: data.split(/\n/g).filter(v => v && /\ton$/i.test(v)) - }; - let promise = Promise.resolve(); - - if (filesystems.id.length > 0) { - filesystems.id.forEach((_value, _index) => { - let filesystem = { - properties: _value.split(/\t/g).filter(v => v) - }; - - filesystem.name = filesystem.properties[0]; - filesystem.id = FnGenerateId({ at: true, colon: true, forwardslash: true, period: true, underscore: true, whitespace: true }, { name: filesystem.properties[0], attribute: true }); - filesystem.mounted = filesystem.properties[1]; - filesystem.mountpoint = filesystem.properties[2]; - filesystem.sharesmb = filesystem.properties[3]; - - promise = promise.then(_ => new Promise(resolve => - setTimeout(function () { - if (_index <= (filesystems.id.length - 1)) { - if (filesystem.sharesmb == "on") { - FnSambaZfsShareConfigurationPathSet({ name: pool.name, id: pool.id, altroot: pool.altroot }, { name: filesystem.name, namenew: null, id: filesystem.id, mountpoint: filesystem.mountpoint }) - } - } - - if (_index == (filesystems.id.length - 1)) { - setTimeout(function () { - FnDisplayAlert({ status: "success", title: "Samba share configurations successfully updated", description: pool.name, breakword: false }, { name: "samba-configure-share", id: pool.id, timeout: 4 }); - - FnConsole.log[1]("Samba, ZFS Share Configuration, Paths, Set: Success, Pool: " + pool.name + ", File System: " + filesystem.name); - - FnSambaZfsSharesConfigurationReload() - .done(function () { - setTimeout(function () { - if (samba.restart) { - FnSambaRestart() - .finally(function () { - if (display.refresh) { - setTimeout(function () { - FnStoragePoolRefresh({ name: pool.name, id: pool.id }, { storagepool: true, filesystems: true, snapshots: true, status: false }); - }, 500); - } - - process.promise.resolve(); - }); - } else { - FnSambaConfigurationReload() - .finally(function () { - if (display.refresh) { - setTimeout(function () { - FnStoragePoolRefresh({ name: pool.name, id: pool.id }, { storagepool: true, filesystems: true, snapshots: true, status: false }); - }, 500); - } - - process.promise.resolve(); - }); - } - }, 300); - }); - }, 500); - } - - resolve(); - }, 500) - )); - }); - } else { - FnDisplayAlert({ status: "success", title: "Samba share configurations successfully updated", description: pool.name, breakword: false }, { name: "samba-configure-share", id: pool.id, timeout: 4 }); - - FnConsole.log[1]("Samba, ZFS Share Configuration, Paths, Set: Success, Pool: " + pool.name + ", File System: " + filesystem.name); - - process.promise.resolve(); - } - }) - .fail(function (message, data) { - FnDisplayAlert({ status: "danger", title: "Samba share configurations could not updated", description: pool.name, breakword: false }, { name: "samba-configure-share", id: pool.id, timeout: 4 }); - - FnConsole.warn("Samba, ZFS Share Configuration, Paths, Set: Failed, Pool: " + pool.name + ", File System: " + filesystem.name + ", Message: " + (data ? data : message)); - - if (display.refresh) { - setTimeout(function () { - FnStoragePoolRefresh({ name: pool.name, id: pool.id }, { storagepool: true, filesystems: true, snapshots: true, status: false }); - }, 500); - } - - process.promise.resolve(); - }); - - return process.promise.promise(); -} - -function FnSambaZfsShareConfigure(pool = { name, id }, filesystem = { name, id, mountpoint }, samba = { share: { additional: [], administrative: false, browseable: true, guestok: false, name, comment, nameexisting, readonly: false, temporary: false }, restart: false }) { - $("#spinner-storagepool-filesystem-samba-configure-" + filesystem.id + " span").text("Configuring Samba share..."); - - FnSambaShareNamesGet({ zfsonly: false }) - .done(function (data) { - FnConsole.log[4](FnConsoleVerbose({ data: data, message: "Samba, Share, Names, Get:" })); - - samba.share.nameunique = true; - samba.share.errormessage = "Share name is already in use."; - - if (data.replace(/\n/g, "") != "$empty") { //$empty response is received if share names list is empty - samba.shares = data.split(/\n/g).filter(v => v); - - samba.shares.forEach((_value, _index) => { - if (_value.replace(/^\[/, "").replace(/\]$/, "").toLowerCase() == samba.share.name.toLowerCase() + (samba.share.administrative ? "$" : "")) { - if (samba.share.name != samba.share.nameexisting) { //Allow the name since the share is already enabled with this name - samba.share.nameunique = false; - - return; - } - } - }); - } - - if (/^global$|^homes$|^printers$/gi.test(samba.share.name)) { - samba.share.nameunique = false; - samba.share.errormessage = "Share name can not be a restricted name."; - } - - if (!samba.share.nameunique) { - $("#validationwrapper-storagepool-filesystem-samba-configure-name-" + filesystem.id).addClass("has-error"); - $("#helpblock-storagepool-filesystem-samba-configure-name-" + filesystem.id).addClass("has-error").removeClass("hidden").text(samba.share.errormessage); - $("#input-storagepool-filesystem-samba-configure-name-" + filesystem.id).focus(); - - $("#spinner-storagepool-filesystem-samba-configure-" + filesystem.id).addClass("hidden"); - $("#spinner-storagepool-filesystem-samba-configure-" + filesystem.id + " span").text(""); - $("#btn-storagepool-filesystem-samba-configure-apply-" + filesystem.id).prop("disabled", false); - - FnConsole.warn("Samba, ZFS Share Configuration, Update: Failed, Pool: " + pool.name + ", File System: " + filesystem.name + ", Message: " + samba.share.errormessage); - } else { - FnSambaZfsShareConfigureCommand({ name: pool.name, id: pool.id }, { name: filesystem.name, id: filesystem.id, mountpoint: filesystem.mountpoint }, { share: { additional: samba.share.additional, administrative: samba.share.administrative, browseable: samba.share.browseable, guestok: samba.share.guestok, name: samba.share.name, comment: samba.share.comment, readonly: samba.share.readonly, temporary: samba.share.temporary }, restart: samba.restart }); - } - }); -} - -function FnSambaZfsShareConfigureCommand(pool = { name, id }, filesystem = { name, id, mountpoint }, samba = { share: { additional: [], administrative: false, browseable: true, guestok: false, name, comment, readonly: false, temporary: false }, restart: false }) { - let process = { - command: ["/bin/sh", "-c", "printf " + FnSambaZfsShareConfigurationGenerate({ name: filesystem.name, id: filesystem.id, mountpoint: filesystem.mountpoint }, { enable: false, share: { additional: samba.share.additional, administrative: samba.share.administrative, browseable: samba.share.browseable, guestok: samba.share.guestok, name: samba.share.name, comment: samba.share.comment, readonly: samba.share.readonly, temporary: samba.share.temporary } })] - }; - - FnConsole.log[2]("Samba, ZFS Share Configuration, Update: In Progress, Pool: " + pool.name + ", File System: " + filesystem.name); - FnConsole.log[3](FnConsoleCommand({ command: process.command })); - - return cockpit.spawn(process.command, { err: "out", superuser: "require" }) - .done(function () { - FnDisplayAlert({ status: "success", title: "Samba share configuration successfully updated", description: filesystem.name, breakword: false }, { name: "samba-configure-share", id: filesystem.id, timeout: 4 }); - - FnConsole.log[1]("Samba, ZFS Share Configuration, Update: Success, Pool: " + pool.name + ", File System: " + filesystem.name); - - if (samba.restart) { - FnSambaRestart(); - } else { - FnSambaConfigurationReload(); - } - }) - .fail(function (message, data) { - FnDisplayAlert({ status: "danger", title: "Samba share configuration could not be updated", description: filesystem.name, breakword: false }, { name: "samba-configure-share", id: filesystem.id, timeout: 4 }); - - FnConsole.warn("Samba, ZFS Share Configuration, Update: Failed, Pool: " + pool.name + ", File System: " + filesystem.name + ", Message: " + (data ? data : message)); - }) - .finally(function () { - $("#modal-storagepool-filesystem-samba-configure-" + filesystem.id).modal("hide"); - - setTimeout(function () { - FnStoragePoolRefresh({ name: pool.name, id: pool.id }, { storagepool: true, filesystems: true, snapshots: false, status: false }); - }, 200); - }); -} - -function FnSambaZfsShareDisable(pool = { name, id, altroot: false, readonly: false }, filesystem = { name, id }) { - let process = { - command: ["/bin/rm", "-f", "/" + (pool.altroot || pool.readonly ? "run" : "etc") + "/cockpit/zfs/shares/" + FnGenerateShareFileName({ name: filesystem.name }) + ".conf"] - }; - - FnConsole.log[2]("Samba, Share, Disable: In Progress, Pool: " + pool.name + ", File System: " + filesystem.name); - FnConsole.log[3](FnConsoleCommand({ command: process.command })); - - return cockpit.spawn(process.command, { err: "out" }) - .done(function () { - FnConsole.log[1]("Samba, Share, Disable: Success, Pool: " + pool.name + ", File System: " + filesystem.name); - }) - .fail(function (message, data) { - FnConsole.warn("Samba, Share, Disable: Failed, Pool: " + pool.name + ", File System: " + filesystem.name + ", Message: " + (data ? data : message)); - }); -} - -function FnSambaZfsShareEnable(pool = { name, id }, filesystem = { name, id, mountpoint }, samba = { share: { additional: [], administrative: false, browseable: true, guestok: false, name, comment, readonly: false, temporary: false } }) { - let process = { - command: ["/bin/sh", "-c", "printf " + FnSambaZfsShareConfigurationGenerate({ name: filesystem.name, id: filesystem.id, mountpoint: filesystem.mountpoint }, { enable: true, share: { additional: samba.share.additional, administrative: samba.share.administrative, browseable: samba.share.browseable, guestok: samba.share.guestok, name: samba.share.name, comment: samba.share.comment, readonly: samba.share.readonly, temporary: samba.share.temporary } })] - }; - - FnConsole.log[2]("Samba, Share, Enable: In Progress, Pool: " + pool.name + ", File System: " + filesystem.name); - FnConsole.log[2](FnConsoleCommand({ command: process.command })); - - return cockpit.spawn(process.command, { err: "out" }) - .done(function () { - FnConsole.log[1]("Samba, Share, Enable: Success, Pool: " + pool.name + ", File System: " + filesystem.name); - }) - .fail(function (message, data) { - FnConsole.warn("Samba, Share, Enable: Failed, Pool: " + pool.name + ", File System: " + filesystem.name + ", Message: " + (data ? data : message)); - }); -} - -function FnSambaZfsSharesConfigurationReload() { - let process = { - command: ["/bin/sh", "-c", "echo '# COCKPIT ZFS MANAGER\n# WARNING: DO NOT EDIT, AUTO-GENERATED CONFIGURATION' > /etc/cockpit/zfs/shares.conf && /bin/ls /etc/cockpit/zfs/shares/*.conf 2> /dev/null | /bin/sed -e 's/^/include = /' >> /etc/cockpit/zfs/shares.conf && echo '# COCKPIT ZFS MANAGER\n# WARNING: DO NOT EDIT, AUTO-GENERATED CONFIGURATION' > /run/cockpit/zfs/shares.conf && /bin/ls /run/cockpit/zfs/shares/*.conf 2> /dev/null | /bin/sed -e 's/^/include = /' >> /run/cockpit/zfs/shares.conf"] - }; - - FnConsole.log[2]("Samba, ZFS Shares Configuration, Reload: In Progress"); - FnConsole.log[2](FnConsoleCommand({ command: process.command })); - - return cockpit.spawn(process.command, { err: "out" }) - .done(function () { - FnConsole.log[1]("Samba, ZFS Shares Configuration, Reload: Success"); - }) - .fail(function (message, data) { - FnConsole.warn("Samba, ZFS Shares Configuration, Reload: Failed, Message: " + (data ? data : message)); - }); -} - -//#endregion - -//#region Dynamic Content Click Actions - -function FnDynamicStatusDiskTrimCancel(pool = { name, id, status: { config: { items: { index: 0 } } } }, disk = { id }) { - let dynamic = { - script: "" - }; - - dynamic.script = ` - \x3Cscript nonce="1t55lZ7tzuKTreHVNwE66Ox32Mc="> - $("#btn-storagepool-status-disk-trim-cancel-` + pool.status.config.items.index + `-` + pool.id + `").on("click", function () { - $("[id^=btn-storagepool-status-dropdown-][id$=` + pool.id + `]").addClass("disabled"); - $("#spinner-storagepool-status-` + pool.status.config.items.index + `-` + pool.id + `").removeClass("hidden"); - - FnStoragePoolTrimCancel({ name: "` + pool.name + `", id: "` + pool.id + `" }, { id: "` + disk.id + `" }); - }); - \x3C/script> - `; - - $("#dynamics-storagepool-status-" + pool.id).append(dynamic.script); -} - -function FnDynamicStatusDiskTrimResume(pool = { name, id, status: { config: { items: { index: 0 } } } }, disk = { id }) { - let dynamic = { - script: "" - }; - - dynamic.script = ` - \x3Cscript nonce="1t55lZ7tzuKTreHVNwE66Ox32Mc="> - $("#btn-storagepool-status-disk-trim-resume-` + pool.status.config.items.index + `-` + pool.id + `").on("click", function () { - $("[id^=btn-storagepool-status-dropdown-][id$=` + pool.id + `]").addClass("disabled"); - $("#spinner-storagepool-status-` + pool.status.config.items.index + `-` + pool.id + `").removeClass("hidden"); - - FnStoragePoolTrimStart({ name: "` + pool.name + `", id: "` + pool.id + `" }, { id: "` + disk.id + `" }, { resume: true, secure: false }, { name: null, id: null }); - }); - \x3C/script> - `; - - $("#dynamics-storagepool-status-" + pool.id).append(dynamic.script); -} - -function FnDynamicStatusDiskTrimSuspend(pool = { name, id, status: { config: { items: { index: 0 } } } }, disk = { id }) { - let dynamic = { - script: "" - }; - - dynamic.script = ` - \x3Cscript nonce="1t55lZ7tzuKTreHVNwE66Ox32Mc="> - $("#btn-storagepool-status-disk-trim-suspend-` + pool.status.config.items.index + `-` + pool.id + `").on("click", function () { - $("[id^=btn-storagepool-status-dropdown-][id$=` + pool.id + `]").addClass("disabled"); - $("#spinner-storagepool-status-` + pool.status.config.items.index + `-` + pool.id + `").removeClass("hidden"); - - FnStoragePoolTrimSuspend({ name: "` + pool.name + `", id: "` + pool.id + `" }, { id: "` + disk.id + `" }); - }); - \x3C/script> - `; - - $("#dynamics-storagepool-status-" + pool.id).append(dynamic.script); -} - -function FnDynamicStatusStoragePoolScrubPause(pool = { name, id, status: { config: { items: { index: 0 } } } }) { - let dynamic = { - script: "" - }; - - dynamic.script = ` - \x3Cscript nonce="1t55lZ7tzuKTreHVNwE66Ox32Mc="> - $("#btn-storagepool-status-scrub-pause-` + pool.status.config.items.index + `-` + pool.id + `").on("click", function () { - $("[id^=btn-storagepool-status-dropdown-][id$=` + pool.id + `]").addClass("disabled"); - $("#spinner-storagepool-status-` + pool.status.config.items.index + `-` + pool.id + `").removeClass("hidden"); - - FnStoragePoolScrubPause({ name: "` + pool.name + `", id: "` + pool.id + `" }, { refresh: true }); - }); - \x3C/script> - `; - - $("#dynamics-storagepool-status-" + pool.id).append(dynamic.script); -} - -function FnDynamicStatusStoragePoolScrubResume(pool = { name, id, status: { config: { items: { index: 0 } } } }) { - let dynamic = { - script: "" - }; - - dynamic.script = ` - \x3Cscript nonce="1t55lZ7tzuKTreHVNwE66Ox32Mc="> - $("#btn-storagepool-status-scrub-resume-` + pool.status.config.items.index + `-` + pool.id + `").on("click", function () { - $("[id^=btn-storagepool-status-dropdown-][id$=` + pool.id + `]").addClass("disabled"); - $("#spinner-storagepool-status-` + pool.status.config.items.index + `-` + pool.id + `").removeClass("hidden"); - - FnStoragePoolScrubStart({ name: "` + pool.name + `", id: "` + pool.id + `" }, { resume: true }), { refresh: true }; - }); - \x3C/script> - `; - - $("#dynamics-storagepool-status-" + pool.id).append(dynamic.script); -} - -function FnDynamicStatusStoragePoolScrubStart(pool = { name, id, status: { config: { items: { index: 0 } } } }) { - let dynamic = { - script: "" - }; - - dynamic.script = ` - \x3Cscript nonce="1t55lZ7tzuKTreHVNwE66Ox32Mc="> - $("#btn-storagepool-status-scrub-start-` + pool.status.config.items.index + `-` + pool.id + `").on("click", function () { - $("[id^=btn-storagepool-status-dropdown-][id$=` + pool.id + `]").addClass("disabled"); - $("#spinner-storagepool-status-` + pool.status.config.items.index + `-` + pool.id + `").removeClass("hidden"); - - FnStoragePoolScrubStart({ name: "` + pool.name + `", id: "` + pool.id + `" }, { resume: false }, { refresh: true }); - }); - \x3C/script> - `; - - $("#dynamics-storagepool-status-" + pool.id).append(dynamic.script); -} - -function FnDynamicStatusStoragePoolScrubStop(pool = { name, id, status: { config: { items: { index: 0 } } } }) { - let dynamic = { - script: "" - }; - - dynamic.script = ` - \x3Cscript nonce="1t55lZ7tzuKTreHVNwE66Ox32Mc="> - $("#btn-storagepool-status-scrub-stop-` + pool.status.config.items.index + `-` + pool.id + `").on("click", function () { - $("[id^=btn-storagepool-status-dropdown-][id$=` + pool.id + `]").addClass("disabled"); - $("#spinner-storagepool-status-` + pool.status.config.items.index + `-` + pool.id + `").removeClass("hidden"); - - FnStoragePoolScrubStop({ name: "` + pool.name + `", id: "` + pool.id + `" }, { refresh: true }); - }); - \x3C/script> - `; - - $("#dynamics-storagepool-status-" + pool.id).append(dynamic.script); -} - -function FnDynamicStatusStoragePoolTrimCancel(pool = { name, id, status: { config: { items: { index: 0 } } } }) { - let dynamic = { - script: "" - }; - - dynamic.script = ` - \x3Cscript nonce="1t55lZ7tzuKTreHVNwE66Ox32Mc="> - $("#btn-storagepool-status-trim-cancel-` + pool.status.config.items.index + `-` + pool.id + `").on("click", function () { - $("[id^=btn-storagepool-status-dropdown-][id$=` + pool.id + `]").addClass("disabled"); - $("#spinner-storagepool-status-` + pool.status.config.items.index + `-` + pool.id + `").removeClass("hidden"); - - FnStoragePoolTrimCancel({ name: "` + pool.name + `", id: "` + pool.id + `" }, { id: null }); - }); - \x3C/script> - `; - - $("#dynamics-storagepool-status-" + pool.id).append(dynamic.script); -} - -function FnDynamicStatusStoragePoolTrimResume(pool = { name, id, status: { config: { items: { index: 0 } } } }) { - let dynamic = { - script: "" - }; - - dynamic.script = ` - \x3Cscript nonce="1t55lZ7tzuKTreHVNwE66Ox32Mc="> - $("#btn-storagepool-status-trim-resume-` + pool.status.config.items.index + `-` + pool.id + `").on("click", function () { - $("[id^=btn-storagepool-status-dropdown-][id$=` + pool.id + `]").addClass("disabled"); - $("#spinner-storagepool-status-` + pool.status.config.items.index + `-` + pool.id + `").removeClass("hidden"); - - FnStoragePoolTrimStart({ name: "` + pool.name + `", id: "` + pool.id + `" }, { id: null }, { resume: true, secure: false }, { name: null, id: null }); - }); - \x3C/script> - `; - - $("#dynamics-storagepool-status-" + pool.id).append(dynamic.script); -} - -function FnDynamicStatusStoragePoolTrimSuspend(pool = { name, id, status: { config: { items: { index: 0 } } } }) { - let dynamic = { - script: "" - }; - - dynamic.script = ` - \x3Cscript nonce="1t55lZ7tzuKTreHVNwE66Ox32Mc="> - $("#btn-storagepool-status-trim-suspend-` + pool.status.config.items.index + `-` + pool.id + `").on("click", function () { - $("[id^=btn-storagepool-status-dropdown-][id$=` + pool.id + `]").addClass("disabled"); - $("#spinner-storagepool-status-` + pool.status.config.items.index + `-` + pool.id + `").removeClass("hidden"); - - FnStoragePoolTrimSuspend({ name: "` + pool.name + `", id: "` + pool.id + `" }, { id: null }); - }); - \x3C/script> - `; - - $("#dynamics-storagepool-status-" + pool.id).append(dynamic.script); -} - -//#endregion - -//#region Modals Register - -function FnModalsRegister() { - $("#modals").append(`
    `); - $("#modals").append(`
    `); - - FnModalAbout(); - FnModalConfigure(); - FnModalUpdate(); - FnModalWelcome(); - FnModalStoragePoolsCreate(); - FnModalStoragePoolsImport(); - FnModalFileSystemsUnlock(); -} - -//#endregion - -//#region Modal Cockpit ZFS Manager - -function FnModalAbout() { - let modal = { - window: "" - }; - - modal.window = ` - - `; - - $("#modals").append(modal.window); -} - -function FnModalConfigure() { - let modal = { - window: "" - }; - - modal.window = ` - - - \x3Cscript nonce="1t55lZ7tzuKTreHVNwE66Ox32Mc="> - $("#btn-configure").on("click", function () { - FnModalConfigureContent({ id: $("#modal-configure") }); - }); - \x3C/script> - `; - - $("#modals").append(modal.window); -} - -function FnModalConfigureContent(modal = { id }) { - modal.content = ` - - - \x3Cscript nonce="1t55lZ7tzuKTreHVNwE66Ox32Mc="> - $("#switch-configure-samba-manage input").on("click", function () { - if (!$(this).prop("checked")) { - $("#switch-configure-samba-windowscompatibility input").prop("disabled", true); - $("#switch-configure-samba-windowscompatibility").parent().addClass("hidden"); - } else { - $("#switch-configure-samba-windowscompatibility input").removeClass("hidden").prop("disabled", false); - $("#switch-configure-samba-windowscompatibility").parent().removeClass("hidden"); - } - }); - - $("#switch-configure-zfs-storagepool-boot input").on("click", function () { - if (!$(this).prop("checked")) { - $("#switch-configure-zfs-storagepool-bootlockdown input").prop("disabled", true); - $("#switch-configure-zfs-storagepool-bootlockdown").parent().addClass("hidden"); - } else { - $("#switch-configure-zfs-storagepool-bootlockdown input").prop("disabled", false); - $("#switch-configure-zfs-storagepool-bootlockdown").parent().removeClass("hidden"); - } - }); - - $("#btn-configure-apply").on("click", function () { - $("#spinner-configure").removeClass("hidden"); - $(this).prop("disabled", true); - - let user = { - cockpit: { - manage: $("#switch-configure-cockpit-manage input").prop("checked") - }, - disks: { - base2: $("#switch-configure-disks-base2 input").prop("checked"), - }, - loglevel: $("#btnspan-configure-zfs-storagepool-loglevel").attr("data-field-value"), - samba: { - manage: $("#switch-configure-samba-manage input").prop("checked"), - windowscompatibility: $("#switch-configure-samba-windowscompatibility input").prop("checked") - }, - updates: { - check: $("#switch-configure-updates-check input").prop("checked") - }, - zfs: { - filesystem: { - cloneorigin: $("#switch-configure-zfs-filesystem-cloneorigin input").prop("checked"), - quotarestrict: $("#switch-configure-zfs-filesystem-quotarestrict input").prop("checked"), - readonlylockdown: $("#switch-configure-zfs-filesystem-readonlylockdown input").prop("checked"), - snapshotactions: $("#switch-configure-zfs-filesystem-snapshotactions input").prop("checked") - }, - status: { - errorcolors: $("#switch-configure-zfs-status-errorcolors input").prop("checked"), - trimunsupported: $("#switch-configure-zfs-status-trimunsupported input").prop("checked") - }, - storagepool: { - activetab: $("#btnspan-configure-zfs-storagepool-activetab").attr("data-field-value"), - boot: $("#switch-configure-zfs-storagepool-boot input").prop("checked"), - bootlockdown: $("#switch-configure-zfs-storagepool-bootlockdown input").prop("checked"), - refreshall: $("#switch-configure-zfs-storagepool-refreshall input").prop("checked"), - root: $("#switch-configure-zfs-storagepool-root input").prop("checked") - } - } - }; - - FnConfigure({ cockpit: { manage: user.cockpit.manage }, disks: { base2: user.disks.base2 }, loglevel: user.loglevel, samba: { manage: user.samba.manage, windowscompatibility: user.samba.windowscompatibility }, updates: { check: user.updates.check }, zfs: { filesystem: { cloneorigin: user.zfs.filesystem.cloneorigin, quotarestrict: user.zfs.filesystem.quotarestrict, readonlylockdown: user.zfs.filesystem.readonlylockdown, snapshotactions: user.zfs.filesystem.snapshotactions }, status: { errorcolors: user.zfs.status.errorcolors, trimunsupported: user.zfs.status.trimunsupported }, storagepool: { activetab: user.zfs.storagepool.activetab, boot: user.zfs.storagepool.boot, bootlockdown: user.zfs.storagepool.bootlockdown, refreshall: user.zfs.storagepool.refreshall, root: user.zfs.storagepool.root } } }, { name: "configure", welcome: false }) - }); - - $("#dropdown-configure-zfs-storagepool-activetab").on("click", "li a", function () { - $("#btnspan-configure-zfs-storagepool-activetab").text($(this).text()).attr("data-field-value", $(this).parent().attr("value")); - $(this).parent().siblings().removeClass("active"); - $(this).parent().addClass("active"); - }); - - $("#dropdown-configure-zfs-storagepool-loglevel").on("click", "li a", function () { - $("#btnspan-configure-zfs-storagepool-loglevel").text($(this).text()).attr("data-field-value", $(this).parent().attr("value")); - $(this).parent().siblings().removeClass("active"); - $(this).parent().addClass("active"); - }); - \x3C/script> - `; - - modal.id.empty().append(modal.content); -} - -function FnModalUpdate() { - let modal = { - window: "" - }; - - modal.window = ` - - `; - - $("#modals").append(modal.window); -} - -function FnModalUpdateContent(modal = { id }) { - modal.content = ` - - `; - - modal.id.empty().append(modal.content); - - $("#progressbar-update .progress-bar").css("width", "100%"); -} - -function FnModalWelcome() { - let modal = { - window: "" - }; - - modal.window = ` - - `; - - $("#modals").append(modal.window); -} - -function FnModalWelcomeContent(modal = { id }) { - modal.content = ` - - - \x3Cscript nonce="1t55lZ7tzuKTreHVNwE66Ox32Mc="> - $("#switch-welcome-samba-manage input").on("click", function () { - if (!$(this).prop("checked")) { - $("#switch-welcome-samba-windowscompatibility input").prop("disabled", true); - $("#switch-welcome-samba-windowscompatibility").parent().addClass("hidden"); - } else { - $("#switch-welcome-samba-windowscompatibility input").removeClass("hidden").prop("disabled", false); - $("#switch-welcome-samba-windowscompatibility").parent().removeClass("hidden"); - } - }); - - $("#switch-welcome-zfs-storagepool-boot input").on("click", function () { - if (!$(this).prop("checked")) { - $("#switch-welcome-zfs-storagepool-bootlockdown input").prop("disabled", true); - $("#switch-welcome-zfs-storagepool-bootlockdown").parent().addClass("hidden"); - } else { - $("#switch-welcome-zfs-storagepool-bootlockdown input").prop("disabled", false); - $("#switch-welcome-zfs-storagepool-bootlockdown").parent().removeClass("hidden"); - } - }); - - $("#btn-welcome-apply").on("click", function () { - $("#spinner-welcome").removeClass("hidden"); - $(this).prop("disabled", true); - - let user = { - cockpit: { - manage: $("#switch-welcome-cockpit-manage input").prop("checked") - }, - loglevel: $("#btnspan-welcome-zfs-storagepool-loglevel").attr("data-field-value"), - samba: { - manage: $("#switch-welcome-samba-manage input").prop("checked"), - windowscompatibility: $("#switch-welcome-samba-windowscompatibility input").prop("checked") - }, - updates: { - check: $("#switch-welcome-updates-check input").prop("checked") - }, - zfs: { - storagepool: { - boot: $("#switch-welcome-zfs-storagepool-boot input").prop("checked"), - bootlockdown: $("#switch-welcome-zfs-storagepool-bootlockdown input").prop("checked"), - root: $("#switch-welcome-zfs-storagepool-root input").prop("checked") - } - } - }; - - FnConfigure({ cockpit: { manage: user.cockpit.manage }, disks: { base2: ` + zfsmanager.configuration.disks.base2 + ` }, loglevel: user.loglevel, samba: { manage: user.samba.manage, windowscompatibility: user.samba.windowscompatibility }, updates: { check: user.updates.check }, zfs: { filesystem: { cloneorigin: ` + zfsmanager.configuration.zfs.filesystem.cloneorigin + `, quotarestrict: ` + zfsmanager.configuration.zfs.filesystem.quotarestrict + `, readonlylockdown: ` + zfsmanager.configuration.zfs.filesystem.readonlylockdown + `, snapshotactions: ` + zfsmanager.configuration.zfs.filesystem.snapshotactions + ` }, status: { errorcolors: ` + zfsmanager.configuration.zfs.status.errorcolors + `, trimunsupported: ` + zfsmanager.configuration.zfs.status.trimunsupported + ` }, storagepool: { activetab: ` + zfsmanager.configuration.zfs.storagepool.activetab + `, boot: user.zfs.storagepool.boot, bootlockdown: user.zfs.storagepool.bootlockdown, refreshall: ` + zfsmanager.configuration.zfs.storagepool.refreshall + `, root: user.zfs.storagepool.root } } }, { name: "welcome", welcome: true }) - }); - - $("#dropdown-welcome-zfs-storagepool-activetab").on("click", "li a", function () { - $("#btnspan-welcome-zfs-storagepool-activetab").text($(this).text()).attr("data-field-value", $(this).parent().attr("value")); - $(this).parent().siblings().removeClass("active"); - $(this).parent().addClass("active"); - }); - - $("#dropdown-welcome-zfs-storagepool-loglevel").on("click", "li a", function () { - $("#btnspan-welcome-zfs-storagepool-loglevel").text($(this).text()).attr("data-field-value", $(this).parent().attr("value")); - $(this).parent().siblings().removeClass("active"); - $(this).parent().addClass("active"); - }); - \x3C/script> - `; - - modal.id.empty().append(modal.content); -} - -//#endregion - -//#region Modal Storage Pools - -function FnModalStoragePoolsCreate() { - let modal = { - window: "" - }; - - modal.window = ` - - - \x3Cscript nonce="1t55lZ7tzuKTreHVNwE66Ox32Mc="> - $("#btn-storagepools-create").on("click", function () { - FnModalStoragePoolsCreateContent({ id: $("#modal-storagepools-create") }); - FnDisksAvailableGet({ name: "storagepools-create-disks", id: null, default: true }); - - $("#input-storagepools-create-refreservation").val("10"); - $("#validationwrapper-storagepools-create-refreservation .min-slider-handle").attr("tabindex", "1003"); - setTimeout(function() { - $("#input-storagepools-create-name").focus(); - }, 600); - }); - \x3C/script> - `; - - $("#modals-storagepools").append(modal.window); -} - -function FnModalStoragePoolsCreateContent(modal = { id }) { - modal.content = ` - - - \x3Cscript nonce="1t55lZ7tzuKTreHVNwE66Ox32Mc="> - $("#input-storagepools-create-refreservation").tooltip({ trigger: "manual" }) - .on("keyup", function (element) { - let $this = $(this); - let sd = $this.siblings("[data-provide=slider]").slider(); - - if ($this.val().trim() && !$.isNumeric(this.value)) { - this.value = sd.slider("getValue"); - } - }) - .on("keypress blur", function (element) { - if (element.which == 13 || element.type === "blur") { - element.preventDefault(); - - let $this = $(this); - let sd = $this.siblings("[data-provide=slider]").slider(); - let max = sd.slider("getAttribute", "max"); - let min = sd.slider("getAttribute", "min"); - - if (!$.isNumeric(this.value) || (this.value > max || this.value < min)) { - let warningInfo = $.isNumeric(this.value) ? "Valid value should be between " + min + " and " + max : "Valid value should be number"; - $this.attr("data-original-title", warningInfo).tooltip("show").addClass("warning"); - this.value = sd.slider("getValue"); - setTimeout(function () { - $this.tooltip("hide"); - }, 3000); - } else { - if ($this.is(".warning")) { - $this.tooltip("hide"); - } - - this.value = $this.val().trim(); - sd.slider("setValue", this.value); - } - } - }) - .siblings("[data-provide=slider]").each(function () { - $("#input-storagepools-create-refreservation").val(this.value); - $(this).slider().on("change", function (element) { - $("#input-storagepools-create-refreservation").val(element.value.newValue); - }); - }); - - $("#input-storagepools-create-refreservation").on("change textInput input", function (element) { - if ($(this).val() > 20) { //Force reset to maximum allowed value - $(this).val(20); - } else if ($(this).val() < 0) { //Force reset to minimum allowed value - $(this).val(0); - } - - if ($.isNumeric($(this).val())) { - $("#slider-storagepools-create-refreservation").slider("setValue", $(this).val()); - } - }); - - $("#switch-storagepools-create-disks-wwn input").on("click", function () { - $("#btnspan-storagepools-create-disks-identifier").text("Block Device"); - $("#dropdown-storagepools-create-disks-identifier li").siblings().removeClass("active"); - $("#dropdown-storagepools-create-disks-identifier li[value='blockdevice']").addClass("active"); - $("#helpblock-storagepools-create-disks-identifierwarning").addClass("hidden").text(""); - ` + (zfsmanager.zfs.warnings.nvmevdev ? `$("#helpblock-storagepools-create-disks-identifierwarningzfs").addClass("hidden");` : ``) + ` - - let disk = { - identifier: ($(this).prop("checked") ? "wwn" : "blockdevice"), - identifiertext: ($(this).prop("checked") ? "WWN" : "Block Device") - }; - - if ($(this).prop("checked")) { - $("#controllabel-storagepools-create-disks-identifier").addClass("hidden"); - $("#validationwrapper-storagepools-create-disks-identifier").addClass("hidden"); - } else { - $("#controllabel-storagepools-create-disks-identifier").removeClass("hidden"); - $("#validationwrapper-storagepools-create-disks-identifier").removeClass("hidden"); - } - - $("#listgroup-storagepools-create-disks input[name='checkbox-storagepools-create-disks']").map(function () { - if ($(this).attr("data-disk-id-" + disk.identifier)) { - $(this).next().find(".select-ct-disk-row-id").text((disk.identifier == "blockdevice" ? "/dev/" : "") + $(this).attr("data-disk-id-" + disk.identifier)); - $(this).attr("data-disk-name", $(this).attr("data-disk-id-" + disk.identifier)); - } else { - $(this).next().find(".select-ct-disk-row-id").text("/dev/" + $(this).attr("data-disk-id-blockdevice")); - $(this).attr("data-disk-name", $(this).attr("data-disk-id-blockdevice")); - $("#helpblock-storagepools-create-disks-identifierwarning").removeClass("hidden").text("One or more disks is missing a " + disk.identifiertext + " identifier."); - } - }); - }); - - $("#btn-storagepools-create-apply").on("click", function () { - $("#spinner-storagepools-create").removeClass("hidden"); - $(this).prop("disabled", true); - - let disks = { - id: [] - }; - let filesystem = { - compression: "", - dedup: "off", - recordsize: "131072", - refreservationpercent: 0, - selinux: false - }; - let pool = { - ashift: 0, - autoexpand: "", - autoreplace: "", - autotrim: "", - force: false, - name: "", - virtualdevice: "" - } - let validation = { - disks: false, - name: false - }; - - $("#listgroup-storagepools-create-disks input[name='checkbox-storagepools-create-disks']:checked").map(function () { - disks.id.push($(this).attr("data-disk-name")); - }); - - if ($("#input-storagepools-create-name").val().length == 0) { - $("#helpblock-storagepools-create-name").addClass("has-error").removeClass("hidden").text("Name can not be empty."); - - validation.name = false; - } else if (/^[a-zA-Z0-9-_.: ]*$/.test($("#input-storagepools-create-name").val()) == false) { - $("#helpblock-storagepools-create-name").addClass("has-error").removeClass("hidden").text("Name contains invalid characters."); - - validation.name = false; - } else if (/^[0-9]/.test($("#input-storagepools-create-name").val())) { - $("#helpblock-storagepools-create-name").addClass("has-error").removeClass("hidden").text("Name can not begin with numerical characters."); - - validation.name = false; - } else if (/^[.]/.test($("#input-storagepools-create-name").val())) { - $("#helpblock-storagepools-create-name").addClass("has-error").removeClass("hidden").text("Name can not begin with a period (.)."); - - validation.name = false; - } else if (/^[_]/.test($("#input-storagepools-create-name").val())) { - $("#helpblock-storagepools-create-name").addClass("has-error").removeClass("hidden").text("Name can not begin with an underscore (_)."); - - validation.name = false; - } else if (/^[-]/.test($("#input-storagepools-create-name").val())) { - $("#helpblock-storagepools-create-name").addClass("has-error").removeClass("hidden").text("Name can not begin with a hypen (-)."); - - validation.name = false; - } else if (/^[:]/.test($("#input-storagepools-create-name").val())) { - $("#helpblock-storagepools-create-name").addClass("has-error").removeClass("hidden").text("Name can not begin with an colon (:)."); - - validation.name = false; - } else if (/^[ ]/.test($("#input-storagepools-create-name").val())) { - $("#helpblock-storagepools-create-name").addClass("has-error").removeClass("hidden").text("Name can not begin with whitespace ( )."); - - validation.name = false; - } else if (/[ ]$/.test($("#input-storagepools-create-name").val())) { - $("#helpblock-storagepools-create-name").addClass("has-error").removeClass("hidden").text("Name can not end with whitespace ( )."); - - validation.name = false; - } else if (/^c[0-9]|^log|^mirror|^raidz|^raidz1|^raidz2|^raidz3|^spare/.test($("#input-storagepools-create-name").val())) { - $("#helpblock-storagepools-create-name").addClass("has-error").removeClass("hidden").text("Name can not begin with a reserved name."); - - validation.name = false; - } else { - $("#validationwrapper-storagepools-create-name").removeClass("has-error"); - $("#helpblock-storagepools-create-name").addClass("hidden").text(""); - - validation.name = true; - } - if (disks.id.length < 1 && $("#btnspan-storagepools-create-virtualdevice").attr("data-field-value") == "disk") { - $("#helpblock-storagepools-create-disks").removeClass("hidden").text("One or more disks is needed for Disk."); - - validation.disks = false; - } else if (disks.id.length < 2 && $("#btnspan-storagepools-create-virtualdevice").attr("data-field-value") == "mirror") { - $("#helpblock-storagepools-create-disks").removeClass("hidden").text("Two or more disks is needed for Mirror."); - - validation.disks = false; - } else if (disks.id.length < 2 && $("#btnspan-storagepools-create-virtualdevice").attr("data-field-value") == "raidz1") { - $("#helpblock-storagepools-create-disks").removeClass("hidden").text("Two or more disks is needed for RaidZ1."); - - validation.disks = false; - } else if (disks.id.length < 3 && $("#btnspan-storagepools-create-virtualdevice").attr("data-field-value") == "raidz2") { - $("#helpblock-storagepools-create-disks").removeClass("hidden").text("Three or more disks is needed for RaidZ2."); - - validation.disks = false; - } else if (disks.id.length < 4 && $("#btnspan-storagepools-create-virtualdevice").attr("data-field-value") == "raidz3") { - $("#helpblock-storagepools-create-disks").removeClass("hidden").text("Four or more disks is needed for RaidZ3."); - - validation.disks = false; - } else { - $("#validationwrapper-storagepools-create-disks").removeClass("has-error"); - $("#helpblock-storagepools-create-disks").removeClass("hidden").text(""); - - validation.disks = true; - } - - if (!validation.name || !validation.disks) { - if (!validation.name) { - $("#validationwrapper-storagepools-create-name").addClass("has-error"); - $("#input-storagepools-create-name").focus(); - } - if (!validation.disks) { - $("#validationwrapper-storagepools-create-disks").addClass("has-error"); - } - - $("#spinner-storagepools-create").addClass("hidden"); - $(this).prop("disabled", false); - } - - if (validation.name && validation.disks) { - filesystem.compression = ($("#switch-storagepools-create-compression input").prop("checked") ? "lz4" : "off"); - filesystem.dedup = $("#btnspan-storagepools-create-dedup").attr("data-field-value"); - filesystem.recordsize = $("#btnspan-storagepools-create-recordsize").attr("data-field-value"); - filesystem.refreservationpercent = ($("#input-storagepools-create-refreservation").val() != "0" ? $("#input-storagepools-create-refreservation").val() : "0"); - filesystem.selinux = $("#switch-storagepools-create-selinux input").prop("checked"); - - pool.ashift = $("#btnspan-storagepools-create-ashift").attr("data-field-value"); - pool.autoexpand = ($("#switch-storagepools-create-autoexpand input").prop("checked") ? "on" : "off"); - pool.autoreplace = ($("#switch-storagepools-create-autoreplace input").prop("checked") ? "on" : "off"); - pool.autotrim = ($("#switch-storagepools-create-autotrim input").prop("checked") ? "on" : "off"); - pool.force = $("#switch-storagepools-create-force input").prop("checked"); - pool.name = $("#input-storagepools-create-name").val(); - pool.virtualdevice = ($("#btnspan-storagepools-create-virtualdevice").attr("data-field-value") == "disk" ? "" : $("#btnspan-storagepools-create-virtualdevice").attr("data-field-value")); - - FnStoragePoolCreate({ name: pool.name, ashift: pool.ashift, autoexpand: pool.autoexpand, autoreplace: pool.autoreplace, autotrim: pool.autotrim, force: pool.force, virtualdevice: pool.virtualdevice }, { compression: filesystem.compression, dedup: filesystem.dedup, recordsize: filesystem.recordsize, refreservationpercent: filesystem.refreservationpercent, selinux: filesystem.selinux }, { id: disks.id }); - } - }); - - $("#dropdown-storagepools-create-virtualdevice").on("click", "li a", function () { - $("#btnspan-storagepools-create-virtualdevice").text($(this).text()).attr("data-field-value", $(this).parent().attr("value")); - $(this).parent().siblings().removeClass("active"); - $(this).parent().addClass("active"); - }); - - $("#dropdown-storagepools-create-ashift").on("click", "li a", function () { - $("#btnspan-storagepools-create-ashift").text($(this).text()).attr("data-field-value", $(this).parent().attr("value")); - $(this).parent().siblings().removeClass("active"); - $(this).parent().addClass("active"); - }); - - $("#dropdown-storagepools-create-disks-identifier").on("click", "li a", function () { - $("#btnspan-storagepools-create-disks-identifier").text($(this).text()).attr("data-field-value", $(this).parent().attr("value")); - $(this).parent().siblings().removeClass("active"); - $(this).parent().addClass("active"); - - $("#helpblock-storagepools-create-disks-identifierwarning").addClass("hidden").text(""); - ` + (zfsmanager.zfs.warnings.nvmevdev ? `$("#helpblock-storagepools-create-disks-identifierwarningzfs").addClass("hidden");` : ``) + ` - - let disk = { - identifier: $(this).parent().attr("value"), - identifiertext: $(this).parent().text() - }; - - $("#listgroup-storagepools-create-disks input[name='checkbox-storagepools-create-disks']").map(function () { - if ($(this).attr("data-disk-id-" + disk.identifier)) { - $(this).next().find(".select-ct-disk-row-id").text((disk.identifier == "blockdevice" ? "/dev/" : "") + $(this).attr("data-disk-id-" + disk.identifier)); - $(this).attr("data-disk-name", $(this).attr("data-disk-id-" + disk.identifier)); - } else { - $(this).next().find(".select-ct-disk-row-id").text("/dev/" + $(this).attr("data-disk-id-blockdevice")); - $(this).attr("data-disk-name", $(this).attr("data-disk-id-blockdevice")); - $("#helpblock-storagepools-create-disks-identifierwarning").removeClass("hidden").text("One or more disks is missing a " + disk.identifiertext + " identifier."); - - ` + (zfsmanager.zfs.warnings.nvmevdev ? ` - if (disk.identifier == "vdev" && /^nvme/gi.test($(this).attr("data-disk-id-blockdevice"))) { - $("#helpblock-storagepools-create-disks-identifierwarningzfs").removeClass("hidden"); - } - ` : ``) + ` - } - }); - }); - - $("#dropdown-storagepools-create-dedup").on("click", "li a", function () { - $("#btnspan-storagepools-create-dedup").text($(this).text()).attr("data-field-value", $(this).parent().attr("value")); - $(this).parent().siblings().removeClass("active"); - $(this).parent().addClass("active"); - }); - - $("#dropdown-storagepools-create-recordsize").on("click", "li a", function () { - $("#btnspan-storagepools-create-recordsize").text($(this).text()).attr("data-field-value", $(this).parent().attr("value")); - $(this).parent().siblings().removeClass("active"); - $(this).parent().addClass("active"); - }); - \x3C/script> - `; - - modal.id.empty().append(modal.content); -} - -function FnModalStoragePoolsImport() { - let modal = { - window: "" - }; - - modal.window = ` - - - \x3Cscript nonce="1t55lZ7tzuKTreHVNwE66Ox32Mc="> - $("#btn-storagepools-import").on("click", function () { - FnModalStoragePoolsImportContent({ id: $("#modal-storagepools-import") }); - FnStoragePoolsImportableGet({ destroyed: false }); - }); - \x3C/script> - `; - - $("#modals-storagepools").append(modal.window); -} - -function FnModalStoragePoolsImportContent(modal = { id }) { - modal.content = ` - - - \x3Cscript nonce="1t55lZ7tzuKTreHVNwE66Ox32Mc="> - $("#switch-storagepools-import-destroyed input").on("click", function () { - $("#helpblock-storagepools-import-storagepools").addClass("hidden").text(""); - $("#helpblock-storagepools-import-storagepools-warning").addClass("hidden").text(""); - - FnStoragePoolsImportableGet({ destroyed: ($(this).prop("checked") ? true : false) }); - }); - - $("#switch-storagepools-import-rename input").on("click", function () { - if ($(this).prop("checked")) { - $("#controllabel-storagepools-import-namenew").removeClass("hidden"); - $("#validationwrapper-storagepools-import-namenew").removeClass("hidden"); - $("#input-storagepools-import-namenew").focus(); - } else { - $("#controllabel-storagepools-import-namenew").addClass("hidden"); - $("#validationwrapper-storagepools-import-namenew").addClass("hidden"); - $("#validationwrapper-storagepools-import-namenew").removeClass("has-error"); - $("#helpblock-storagepools-import-namenew").removeClass("has-error").addClass("hidden").text(""); - $("#input-storagepools-import-namenew").val(""); - } - }); - - $("#switch-storagepools-import-selinux input").on("click", function () { - if ($(this).prop("checked") && $("#switch-storagepools-import-readonly input").prop("checked")) { - $("#switch-storagepools-import-readonly input").click(); - } - }); - - $("#switch-storagepools-import-readonly input").on("click", function () { - if ($(this).prop("checked") && $("#switch-storagepools-import-selinux input").prop("checked")) { - $("#switch-storagepools-import-selinux input").click(); - } - }); - - $("#btn-storagepools-import-apply").on("click", function () { - $("#spinner-storagepools-import").removeClass("hidden"); - $(this).prop("disabled", true); - - let disks = { - id: { - blockdevice: true, - disk: false, - path: false, - vdev: false - }, - identifier: "" - }; - - let filesystem = { - mount: true, - selinux: true - }; - - let pool = { - altroot: "", - name: [], - namenew: "", - guid: [], - destroyed: false, - force: false, - ignoremissinglog: false, - readonly: false, - recoverymode: false - }; - - let validation = { - altroot: false, - name: false, - namenew: false, - storagepools: false - }; - - $("#listgroup-storagepools-import-storagepools input[name='checkbox-storagepools-import-storagepools']:checked").map(function () { - pool.guid.push($(this).attr("data-pool-import-guid")); - pool.name.push($(this).attr("data-pool-import-name")); - - disks.id.disk = ($(this).attr("data-pool-import-id-disk") == "true" ? true : false); - disks.id.path = ($(this).attr("data-pool-import-id-path") == "true" ? true : false); - disks.id.vdev = ($(this).attr("data-pool-import-id-vdev") == "true" ? true : false); - }); - - if (pool.guid.length != 1) { - $("#helpblock-storagepools-import-storagepools").removeClass("hidden").text("One storage pool is needed for import."); - - validation.storagepools = false; - } else { - $("#validationwrapper-storagepools-import-storagepools").removeClass("has-error"); - $("#helpblock-storagepools-import-storagepools").removeClass("hidden").text(""); - - validation.storagepools = true; - - pool.guid = pool.guid.join(" "); - pool.name = pool.name.join(" "); - } - - if (validation.storagepools && !$("#switch-storagepools-import-rename input").prop("checked")) { - if (pool.name.length == 0) { - $("#helpblock-storagepools-import-storagepools").removeClass("hidden").text("Storage pool name can not be empty. New name is needed."); - - validation.name = false; - } else if (/^[a-zA-Z0-9-_.: ]*$/.test(pool.name) == false) { - $("#helpblock-storagepools-import-storagepools").removeClass("hidden").text("Storage pool name contains invalid characters. New name is needed."); - - validation.name = false; - } else if (/^[0-9]/.test(pool.name)) { - $("#helpblock-storagepools-import-storagepools").removeClass("hidden").text("Storage pool name can not begin with numerical characters. New name is needed."); - - validation.name = false; - } else if (/^[.]/.test(pool.name)) { - $("#helpblock-storagepools-import-storagepools").removeClass("hidden").text("Storage pool name can not begin with a period (.). New name is needed."); - - validation.name = false; - } else if (/^[_]/.test(pool.name)) { - $("#helpblock-storagepools-import-storagepools").removeClass("hidden").text("Storage pool name can not begin with an underscore (_). New name is needed."); - - validation.name = false; - } else if (/^[-]/.test(pool.name)) { - $("#helpblock-storagepools-import-storagepools").removeClass("hidden").text("Storage pool name can not begin with a hypen (-). New name is needed."); - - validation.name = false; - } else if (/^[:]/.test(pool.name)) { - $("#helpblock-storagepools-import-storagepools").removeClass("hidden").text("Storage pool name can not begin with an colon (:). New name is needed."); - - validation.name = false; - } else if (/^[ ]/.test(pool.name)) { - $("#helpblock-storagepools-import-storagepools").removeClass("hidden").text("Storage pool name can not begin with whitespace ( ). New name is needed."); - - validation.name = false; - } else if (/[ ]$/.test(pool.name)) { - $("#helpblock-storagepools-import-storagepools").removeClass("hidden").text("Storage pool name can not end with whitespace ( ). New name is needed."); - - validation.name = false; - } else if (/^c[0-9]|^log|^mirror|^raidz|^raidz1|^raidz2|^raidz3|^spare/.test(pool.name)) { - $("#helpblock-storagepools-import-storagepools").removeClass("hidden").text("Storage pool name can not begin with a reserved name. New name is needed."); - - validation.name = false; - } else { - validation.name = true; - } - - if (!validation.name && !$("#switch-storagepools-import-rename input").prop("checked")) { - $("#switch-storagepools-import-rename input").click(); - $("#input-storagepools-import-namenew").focus(); - } - } - - if (validation.storagepools && !validation.name && $("#switch-storagepools-import-rename input").prop("checked") && $("#input-storagepools-import-namenew").val().length >= 2) { - validation.name = true; - } - - if ($("#switch-storagepools-import-rename input").prop("checked")) { - if ($("#input-storagepools-import-namenew").val().length == 0) { - $("#helpblock-storagepools-import-namenew").addClass("has-error").removeClass("hidden").text("New name can not be empty."); - - validation.namenew = false; - } else if (/^[a-zA-Z0-9-_.: ]*$/.test($("#input-storagepools-import-namenew").val()) == false) { - $("#helpblock-storagepools-import-namenew").addClass("has-error").removeClass("hidden").text("New name contains invalid characters."); - - validation.namenew = false; - } else if (/^[0-9]/.test($("#input-storagepools-import-namenew").val())) { - $("#helpblock-storagepools-import-namenew").addClass("has-error").removeClass("hidden").text("New name can not begin with numerical characters."); - - validation.namenew = false; - } else if (/^[.]/.test($("#input-storagepools-import-namenew").val())) { - $("#helpblock-storagepools-import-namenew").addClass("has-error").removeClass("hidden").text("New name can not begin with a period (.)."); - - validation.namenew = false; - } else if (/^[_]/.test($("#input-storagepools-import-namenew").val())) { - $("#helpblock-storagepools-import-namenew").addClass("has-error").removeClass("hidden").text("New name can not begin with an underscore (_)."); - - validation.namenew = false; - } else if (/^[-]/.test($("#input-storagepools-import-namenew").val())) { - $("#helpblock-storagepools-import-namenew").addClass("has-error").removeClass("hidden").text("New name can not begin with a hypen (-)."); - - validation.namenew = false; - } else if (/^[:]/.test($("#input-storagepools-import-namenew").val())) { - $("#helpblock-storagepools-import-namenew").addClass("has-error").removeClass("hidden").text("New name can not begin with an colon (:)."); - - validation.namenew = false; - } else if (/^[ ]/.test($("#input-storagepools-import-namenew").val())) { - $("#helpblock-storagepools-import-namenew").addClass("has-error").removeClass("hidden").text("New name can not begin with whitespace ( )."); - - validation.namenew = false; - } else if (/[ ]$/.test($("#input-storagepools-import-namenew").val())) { - $("#helpblock-storagepools-import-namenew").addClass("has-error").removeClass("hidden").text("New name can not end with whitespace ( )."); - - validation.namenew = false; - } else if (/^c[0-9]|^log|^mirror|^raidz|^raidz1|^raidz2|^raidz3|^spare/.test($("#input-storagepools-import-namenew").val())) { - $("#helpblock-storagepools-import-namenew").addClass("has-error").removeClass("hidden").text("New name can not begin with a reserved name."); - - validation.namenew = false; - } else { - $("#validationwrapper-storagepools-import-namenew").removeClass("has-error"); - $("#helpblock-storagepools-import-namenew").addClass("hidden").text(""); - - validation.namenew = true; - } - } else { - $("#validationwrapper-storagepools-import-namenew").removeClass("has-error"); - $("#helpblock-storagepools-import-namenew").removeClass("has-error").addClass("hidden").text(""); - - validation.namenew = true; - } - - if (/^[a-zA-Z0-9-_.:/ ]*$/.test($("#input-storagepools-import-altroot").val()) == false) { - $("#helpblock-storagepools-import-altroot").addClass("has-error").removeClass("hidden").text("Alt Root contains invalid characters."); - - validation.altroot = false; - } else if ($("#input-storagepools-import-altroot").val() && /^[/]/.test($("#input-storagepools-import-altroot").val()) == false) { - $("#helpblock-storagepools-import-altroot").addClass("has-error").removeClass("hidden").text("Alt Root is an absolute path and must begin with a forward slash (/)."); - - validation.altroot = false; - } else if (/^[.]/.test($("#input-storagepools-import-altroot").val())) { - $("#helpblock-storagepools-import-altroot").addClass("has-error").removeClass("hidden").text("Alt Root can not begin with a period (.)."); - - validation.altroot = false; - } else if (/[.]$/.test($("#input-storagepools-import-altroot").val())) { - $("#helpblock-storagepools-import-altroot").addClass("has-error").removeClass("hidden").text("Alt Root can not end with a period (.)."); - - validation.altroot = false; - } else if (/[/][.][/]/g.test($("#input-storagepools-import-altroot").val())) { - $("#helpblock-storagepools-import-altroot").addClass("has-error").removeClass("hidden").text("Alt Root can not contain a period as a sub directory (/./)."); - - validation.altroot = false; - } else if (/[/][.][.][/]/g.test($("#input-storagepools-import-altroot").val())) { - $("#helpblock-storagepools-import-altroot").addClass("has-error").removeClass("hidden").text("Alt Root can not contain a double period as a sub directory (/../)."); - - validation.altroot = false; - } else if (/[/][/]/g.test($("#input-storagepools-import-altroot").val())) { - $("#helpblock-storagepools-import-altroot").addClass("has-error").removeClass("hidden").text("Alt Root can not contain double forward slashes (//)."); - - validation.altroot = false; - } else if (/[.][.]/g.test($("#input-storagepools-import-altroot").val())) { - $("#helpblock-storagepools-import-altroot").addClass("has-error").removeClass("hidden").text("Alt Root can not contain a double period (..)."); - - validation.altroot = false; - } else if (/^[ ]/.test($("#input-storagepools-import-altroot").val())) { - $("#helpblock-storagepools-import-altroot").addClass("has-error").removeClass("hidden").text("Alt Root can not begin with whitespace ( )."); - - validation.altroot = false; - } else if (/[ ]$/.test($("#input-storagepools-import-altroot").val())) { - $("#helpblock-storagepools-import-altroot").addClass("has-error").removeClass("hidden").text("Alt Root can not end with whitespace ( )."); - - validation.altroot = false; - } else { - $("#validationwrapper-storagepools-import-altroot").removeClass("has-error"); - $("#helpblock-storagepools-import-altroot").addClass("hidden").text(""); - - validation.altroot = true; - } - - if (!validation.altroot || !validation.name || !validation.namenew || !validation.storagepools) { - if (!validation.name || !validation.storagepools) { - $("#validationwrapper-storagepools-import-storagepools").addClass("has-error"); - } - if (!validation.namenew) { - $("#validationwrapper-storagepools-import-namenew").addClass("has-error"); - $("#input-storagepools-import-namenew").focus(); - } - if (!validation.altroot) { - $("#validationwrapper-storagepools-import-altroot").addClass("has-error"); - $("#input-storagepools-import-altroot").focus(); - } - - $("#spinner-storagepools-import").addClass("hidden"); - $(this).prop("disabled", false); - } - - if (validation.altroot && validation.name && validation.namenew && validation.storagepools) { - disks.identifier = $("#btnspan-storagepools-import-disks-identifier").attr("data-field-value"); - - filesystem.mount = $("#switch-storagepools-import-mount input").prop("checked"); - filesystem.selinux = $("#switch-storagepools-import-selinux input").prop("checked"); - - pool.altroot = $("#input-storagepools-import-altroot").val(); - pool.destroyed = $("#switch-storagepools-import-destroyed input").prop("checked"); - pool.force = $("#switch-storagepools-import-force input").prop("checked"); - pool.ignoremissinglog = $("#switch-storagepools-import-ignoremissinglog input").prop("checked"); - pool.namenew = ($("#switch-storagepools-import-rename input").prop("checked") ? $("#input-storagepools-import-namenew").val() : ""); - pool.readonly = $("#switch-storagepools-import-readonly input").prop("checked"); - pool.recoverymode = $("#switch-storagepools-import-recoverymode input").prop("checked"); - - FnStoragePoolImport({ name: pool.name, altroot: pool.altroot, destroyed: pool.destroyed, force: pool.force, guid: pool.guid, ignoremissinglog: pool.ignoremissinglog, namenew: pool.namenew, readonly: pool.readonly, recoverymode: pool.recoverymode }, { mount: filesystem.mount, selinux: filesystem.selinux }, { id: { blockdevice: disks.id.blockdevice, disk: disks.id.disk, path: disks.id.path, vdev: disks.id.vdev }, identifier: disks.identifier }); - } - }); - - $("#dropdown-storagepools-import-disks-identifier").on("click", "li a", function () { - $("#btnspan-storagepools-import-disks-identifier").text($(this).text()).attr("data-field-value", $(this).parent().attr("value")); - $(this).parent().siblings().removeClass("active"); - $(this).parent().addClass("active"); - }); - \x3C/script> - `; - - modal.id.empty().append(modal.content); -} - -//#endregion - -//#region Modal Storage Pool - -function FnModalStoragePoolConfigure(pool = { name, id, boot: false, guid, readonly: false, root: false }) { - let modal = { - window: "" - }; - - modal.window = ` - - - \x3Cscript nonce="1t55lZ7tzuKTreHVNwE66Ox32Mc="> - $("#btn-storagepool-configure-` + pool.id + `").on("click", function () { - FnModalStoragePoolConfigureContent({ name: "` + pool.name + `", id: "` + pool.id + `", guid: "` + pool.guid + `", readonly: ` + pool.readonly + ` }, { id: $("#modal-storagepool-configure-` + pool.id + `") }); - FnStoragePoolConfigurationGet({ name: "` + pool.name + `", id: "` + pool.id + `", boot: ` + pool.boot + `, root: ` + pool.root + ` }, { name: "storagepool-configure", id: "` + pool.id + `" }); - }); - \x3C/script> - `; - - $("#modals-storagepool-" + pool.id).append(modal.window); -} - -function FnModalStoragePoolConfigureContent(pool = { name, id, guid, readonly: false }, modal = { id }) { - modal.content = ` - - - \x3Cscript nonce="1t55lZ7tzuKTreHVNwE66Ox32Mc="> - $("#switch-storagepool-configure-multihost-` + pool.id + ` input").on("click", function () { - FnSystemHostIdGet({ name: "storagepool-configure", id: "` + pool.id + `" }); - - if (!$(this).prop("checked")) { - $("#controllabel-storagepool-configure-hostid-` + pool.id + `").addClass("hidden"); - $("#validationwrapper-storagepool-configure-hostid-` + pool.id + `").addClass("hidden"); - } - }); - - $("#btn-storagepool-configure-apply-` + pool.id + `").on("click", function () { - $("#spinner-storagepool-configure-` + pool.id + `").removeClass("hidden"); - $(this).prop("disabled", true); - - let modal = { - id: "" - }; - let pool = { - ashift: 0, - autoexpand: "", - autoreplace: "", - autotrim: "", - comment: "", - delegation: "", - failmode: "", - listsnapshots: "", - multihost: "" - }; - let system = { - hostid: false - }; - let validation = { - comment: false - }; - - if ($("#input-storagepool-configure-comment-` + pool.id + `").val().length > 32) { - $("#helpblock-storagepool-configure-comment-` + pool.id + `").addClass("has-error").removeClass("hidden").text("Comment can not be longer than 32 characters."); - - validation.comment = false; - } else if (/^[ -~]*$/.test($("#input-storagepool-configure-comment-` + pool.id + `").val()) == false) { - $("#helpblock-storagepool-configure-comment-` + pool.id + `").addClass("has-error").removeClass("hidden").text("Comment contains invalid characters."); - - validation.comment = false; - } else { - $("#validationwrapper-storagepool-configure-comment-` + pool.id + `").removeClass("has-error"); - $("#helpblock-storagepool-configure-comment-` + pool.id + `").addClass("hidden").text(""); - - validation.comment = true; - } - - if (!validation.comment) { - $("#validationwrapper-storagepool-configure-comment-` + pool.id + `").addClass("has-error"); - $("#input-storagepool-configure-comment-` + pool.id + `").focus(); - - $("#spinner-storagepool-configure-` + pool.id + `").addClass("hidden"); - $(this).prop("disabled", false); - } - - if (validation.comment) { - modal.id = $("#modal-storagepool-configure-` + pool.id + `"); - - pool.ashift = ($("#btnspan-storagepool-configure-ashift-` + pool.id + `").attr("data-field-value-new") != "" ? $("#btnspan-storagepool-configure-ashift-` + pool.id + `").attr("data-field-value-new") : null); - pool.autoexpand = ($("#switch-storagepool-configure-autoexpand-` + pool.id + ` input").prop("checked") ? "on" : "off"); - pool.autoreplace = ($("#switch-storagepool-configure-autoreplace-` + pool.id + ` input").prop("checked") ? "on" : "off"); - pool.autotrim = ($("#switch-storagepool-configure-autotrim-` + pool.id + ` input").prop("checked") ? "on" : "off"); - pool.comment = $("#input-storagepool-configure-comment-` + pool.id + `").val(); - pool.delegation = ($("#switch-storagepool-configure-delegation-` + pool.id + ` input").prop("checked") ? "on" : "off"); - pool.failmode = ($("#btnspan-storagepool-configure-failmode-` + pool.id + `").attr("data-field-value-new") != "" ? $("#btnspan-storagepool-configure-failmode-` + pool.id + `").attr("data-field-value-new") : null); - pool.listsnapshots = ($("#switch-storagepool-configure-listsnapshots-` + pool.id + ` input").prop("checked") ? "on" : "off"); - pool.multihost = ($("#switch-storagepool-configure-multihost-` + pool.id + ` input").prop("checked") ? "on" : "off"); - - if (!$("#validationwrapper-storagepool-configure-hostid-` + pool.id + `").hasClass("hidden")) { - system.hostid = $("#btnspan-storagepool-configure-hostid-` + pool.id + `").attr("data-field-value"); - } else { - if ($("#btnspan-storagepool-configure-hostid-` + pool.id + `").attr("data-field-value") == "missing") { //Host ID is missing - Generate Host ID before disabling multihost property to avoid error - system.hostid = "libc"; - } - } - - //Set values to null if unchanged, so that they are skipped in the configure function - if (pool.ashift == $("#btnspan-storagepool-configure-ashift-` + pool.id + `").attr("data-field-value")) { - pool.ashift = null; - } - if (pool.autoexpand == $("#switch-storagepool-configure-autoexpand-` + pool.id + `").attr("data-field-value")) { - pool.autoexpand = null; - } - if (pool.autoreplace == $("#switch-storagepool-configure-autoreplace-` + pool.id + `").attr("data-field-value")) { - pool.autoreplace = null; - } - if (pool.autotrim == $("#switch-storagepool-configure-autotrim-` + pool.id + `").attr("data-field-value")) { - pool.autotrim = null; - } - if (pool.comment == $("#input-storagepool-configure-comment-` + pool.id + `").attr("data-field-value")) { - pool.comment = null; - } else if (pool.comment != $("#input-storagepool-configure-comment-` + pool.id + `").attr("data-field-value") && !pool.comment) { - pool.comment = "$empty"; - } - if (pool.failmode == $("#btnspan-storagepool-configure-failmode-` + pool.id + `").attr("data-field-value")) { - pool.failmode = null; - } - if (pool.delegation == $("#switch-storagepool-configure-delegation-` + pool.id + `").attr("data-field-value")) { - pool.delegation = null; - } - if (pool.listsnapshots == $("#switch-storagepool-configure-listsnapshots-` + pool.id + `").attr("data-field-value")) { - pool.listsnapshots = null; - } - if (pool.multihost == $("#switch-storagepool-configure-multihost-` + pool.id + `").attr("data-field-value")) { - pool.multihost = null; - } - - FnStoragePoolConfigure({ name: "` + pool.name + `", id: "` + pool.id + `", ashift: pool.ashift, autoexpand: pool.autoexpand, autoreplace: pool.autoreplace, autotrim: pool.autotrim, comment: pool.comment, delegation: pool.delegation, failmode: pool.failmode, listsnapshots: pool.listsnapshots, multihost: pool.multihost, readonly: ` + pool.readonly + ` }, { hostid: system.hostid }, { id: modal.id }); - } - }); - - $("#dropdown-storagepool-configure-ashift-` + pool.id + `").on("click", "li a", function () { - $("#btnspan-storagepool-configure-ashift-` + pool.id + `").text($(this).text()).attr("data-field-value-new", $(this).parent().attr("value")); - $(this).parent().siblings().removeClass("active"); - $(this).parent().addClass("active"); - }); - - $("#dropdown-storagepool-configure-failmode-` + pool.id + `").on("click", "li a", function () { - $("#btnspan-storagepool-configure-failmode-` + pool.id + `").text($(this).text()).attr("data-field-value-new", $(this).parent().attr("value")); - $(this).parent().siblings().removeClass("active"); - $(this).parent().addClass("active"); - }); - - $("#dropdown-storagepool-configure-hostid-` + pool.id + `").on("click", "li a", function () { - $("#btnspan-storagepool-configure-hostid-` + pool.id + `").text($(this).text()).attr("data-field-value", $(this).parent().attr("value")); - $(this).parent().siblings().removeClass("active"); - $(this).parent().addClass("active"); - }); - \x3C/script> - `; - - modal.id.empty().append(modal.content); -} - -function FnModalStoragePoolConfigureFeatures(pool = { name, id, boot: false, readonly: false }) { - let modal = { - window: "" - }; - - modal.window = ` - - - \x3Cscript nonce="1t55lZ7tzuKTreHVNwE66Ox32Mc="> - $("#btn-storagepool-configure-features-` + pool.id + `").on("click", function () { - FnModalStoragePoolConfigureFeaturesContent({ name: "` + pool.name + `", id: "` + pool.id + `", boot: ` + pool.boot + `, readonly: ` + pool.readonly + ` }, { id: $("#modal-storagepool-configure-features-` + pool.id + `") }); - FnStoragePoolConfigurationFeaturesGet({ name: "` + pool.name + `", id: "` + pool.id + `", boot: ` + pool.boot + ` }, { name: "storagepool-configure-features", id: "` + pool.id + `" }); - }); - \x3C/script> - `; - - $("#modals-storagepool-" + pool.id).append(modal.window); -} - -function FnModalStoragePoolConfigureFeaturesContent(pool = { name, id, boot: false, readonly: false }, modal = { id }) { - pool.version = $("#tr-storagepool-" + pool.id).attr("data-pool-version"); - - modal.content = ` - - - \x3Cscript nonce="1t55lZ7tzuKTreHVNwE66Ox32Mc="> - $("[id^=switch-storagepool-configure-features-][id$='-` + pool.id + `'] input").on("click", function () { - if ($(this).prop("checked") && $(this).parent().attr("data-field-value") == "disabled") { - $("#alert-storagepool-configure-features-compatibility-` + pool.id + `").removeClass("hidden"); - } - - FnModalStoragePoolConfigureFeaturesDependencies({ name: "` + pool.name + `", id: "` + pool.id + `" }, { switch: { id: $(this) } }); - }); - - $("#btn-storagepool-configure-features-apply-` + pool.id + `").on("click", function () { - $("#spinner-storagepool-configure-features-` + pool.id + `").removeClass("hidden"); - $(this).prop("disabled", true); - - let modal = { - id: "" - }; - - let pool = { - feature: { - allocation_classes: ($("#switch-storagepool-configure-features-allocation_classes-` + pool.id + ` input").prop("checked") && !$("#switch-storagepool-configure-features-allocation_classes-` + pool.id + ` input").prop("disabled") ? "enabled" : null), - async_destroy: ($("#switch-storagepool-configure-features-async_destroy-` + pool.id + ` input").prop("checked") && !$("#switch-storagepool-configure-features-async_destroy-` + pool.id + ` input").prop("disabled") ? "enabled" : null), - bookmark_v2: ($("#switch-storagepool-configure-features-bookmark_v2-` + pool.id + ` input").prop("checked") && !$("#switch-storagepool-configure-features-bookmark_v2-` + pool.id + ` input").prop("disabled") ? "enabled" : null), - bookmarks: ($("#switch-storagepool-configure-features-bookmarks-` + pool.id + ` input").prop("checked") && !$("#switch-storagepool-configure-features-bookmarks-` + pool.id + ` input").prop("disabled") ? "enabled" : null), - device_removal: ($("#switch-storagepool-configure-features-device_removal-` + pool.id + ` input").prop("checked") && !$("#switch-storagepool-configure-features-device_removal-` + pool.id + ` input").prop("disabled") ? "enabled" : null), - edonr: ($("#switch-storagepool-configure-features-edonr-` + pool.id + ` input").prop("checked") && !$("#switch-storagepool-configure-features-edonr-` + pool.id + ` input").prop("disabled") ? "enabled" : null), - embedded_data: ($("#switch-storagepool-configure-features-embedded_data-` + pool.id + ` input").prop("checked") && !$("#switch-storagepool-configure-features-embedded_data-` + pool.id + ` input").prop("disabled") ? "enabled" : null), - empty_bpobj: ($("#switch-storagepool-configure-features-empty_bpobj-` + pool.id + ` input").prop("checked") && !$("#switch-storagepool-configure-features-empty_bpobj-` + pool.id + ` input").prop("disabled") ? "enabled" : null), - enabled_txg: ($("#switch-storagepool-configure-features-enabled_txg-` + pool.id + ` input").prop("checked") && !$("#switch-storagepool-configure-features-enabled_txg-` + pool.id + ` input").prop("disabled") ? "enabled" : null), - encryption: ($("#switch-storagepool-configure-features-encryption-` + pool.id + ` input").prop("checked") && !$("#switch-storagepool-configure-features-encryption-` + pool.id + ` input").prop("disabled") ? "enabled" : null), - extensible_dataset: ($("#switch-storagepool-configure-features-extensible_dataset-` + pool.id + ` input").prop("checked") && !$("#switch-storagepool-configure-features-extensible_dataset-` + pool.id + ` input").prop("disabled") ? "enabled" : null), - filesystem_limits: ($("#switch-storagepool-configure-features-filesystem_limits-` + pool.id + ` input").prop("checked") && !$("#switch-storagepool-configure-features-filesystem_limits-` + pool.id + ` input").prop("disabled") ? "enabled" : null), - hole_birth: ($("#switch-storagepool-configure-features-hole_birth-` + pool.id + ` input").prop("checked") && !$("#switch-storagepool-configure-features-hole_birth-` + pool.id + ` input").prop("disabled") ? "enabled" : null), - large_blocks: ($("#switch-storagepool-configure-features-large_blocks-` + pool.id + ` input").prop("checked") && !$("#switch-storagepool-configure-features-large_blocks-` + pool.id + ` input").prop("disabled") ? "enabled" : null), - large_dnode: ($("#switch-storagepool-configure-features-large_dnode-` + pool.id + ` input").prop("checked") && !$("#switch-storagepool-configure-features-large_dnode-` + pool.id + ` input").prop("disabled") ? "enabled" : null), - lz4_compress: ($("#switch-storagepool-configure-features-lz4_compress-` + pool.id + ` input").prop("checked") && !$("#switch-storagepool-configure-features-lz4_compress-` + pool.id + ` input").prop("disabled") ? "enabled" : null), - multi_vdev_crash_dump: ($("#switch-storagepool-configure-features-multi_vdev_crash_dump-` + pool.id + ` input").prop("checked") && !$("#switch-storagepool-configure-features-multi_vdev_crash_dump-` + pool.id + ` input").prop("disabled") ? "enabled" : null), - obsolete_counts: ($("#switch-storagepool-configure-features-obsolete_counts-` + pool.id + ` input").prop("checked") && !$("#switch-storagepool-configure-features-obsolete_counts-` + pool.id + ` input").prop("disabled") ? "enabled" : null), - project_quota: ($("#switch-storagepool-configure-features-project_quota-` + pool.id + ` input").prop("checked") && !$("#switch-storagepool-configure-features-project_quota-` + pool.id + ` input").prop("disabled") ? "enabled" : null), - resilver_defer: ($("#switch-storagepool-configure-features-resilver_defer-` + pool.id + ` input").prop("checked") && !$("#switch-storagepool-configure-features-resilver_defer-` + pool.id + ` input").prop("disabled") ? "enabled" : null), - sha512: ($("#switch-storagepool-configure-features-sha512-` + pool.id + ` input").prop("checked") && !$("#switch-storagepool-configure-features-sha512-` + pool.id + ` input").prop("disabled") ? "enabled" : null), - skein: ($("#switch-storagepool-configure-features-skein-` + pool.id + ` input").prop("checked") && !$("#switch-storagepool-configure-features-skein-` + pool.id + ` input").prop("disabled") ? "enabled" : null), - spacemap_histogram: ($("#switch-storagepool-configure-features-spacemap_histogram-` + pool.id + ` input").prop("checked") && !$("#switch-storagepool-configure-features-spacemap_histogram-` + pool.id + ` input").prop("disabled") ? "enabled" : null), - spacemap_v2: ($("#switch-storagepool-configure-features-spacemap_v2-` + pool.id + ` input").prop("checked") && !$("#switch-storagepool-configure-features-spacemap_v2-` + pool.id + ` input").prop("disabled") ? "enabled" : null), - userobj_accounting: ($("#switch-storagepool-configure-features-userobj_accounting-` + pool.id + ` input").prop("checked") && !$("#switch-storagepool-configure-features-userobj_accounting-` + pool.id + ` input").prop("disabled") ? "enabled" : null), - zpool_checkpoint: ($("#switch-storagepool-configure-features-zpool_checkpoint-` + pool.id + ` input").prop("checked") && !$("#switch-storagepool-configure-features-zpool_checkpoint-` + pool.id + ` input").prop("disabled") ? "enabled" : null) - } - }; - - FnStoragePoolConfigureFeatures({ name: "` + pool.name + `", id: "` + pool.id + `", feature: { allocation_classes: pool.feature.allocation_classes, async_destroy: pool.feature.async_destroy, bookmark_v2: pool.feature.bookmark_v2, bookmarks: pool.feature.bookmarks, device_removal: pool.feature.device_removal, edonr: pool.feature.edonr, embedded_data: pool.feature.embedded_data, empty_bpobj: pool.feature.empty_bpobj, enabled_txg: pool.feature.enabled_txg, encryption: pool.feature.encryption, extensible_dataset: pool.feature.extensible_dataset, filesystem_limits: pool.feature.filesystem_limits, hole_birth: pool.feature.hole_birth, large_blocks: pool.feature.large_blocks, large_dnode: pool.feature.large_dnode, lz4_compress: pool.feature.lz4_compress, multi_vdev_crash_dump: pool.feature.multi_vdev_crash_dump, obsolete_counts: pool.feature.obsolete_counts, project_quota: pool.feature.project_quota, resilver_defer: pool.feature.resilver_defer, sha512: pool.feature.sha512, skein: pool.feature.skein, spacemap_histogram: pool.feature.spacemap_histogram, spacemap_v2: pool.feature.spacemap_v2, userobj_accounting: pool.feature.userobj_accounting, zpool_checkpoint: pool.feature.zpool_checkpoint }, readonly: ` + pool.readonly + ` }, { id: $("#modal-storagepool-configure-features-` + pool.id + `") }); - }); - \x3C/script> - `; - - modal.id.empty().append(modal.content); -} - -function FnModalStoragePoolConfigureFeaturesDependencies(pool = { name, id }, modal = { switch: { id } }) { - if (modal.switch.id.parent().attr("id") == "switch-storagepool-configure-features-bookmarks-" + pool.id) { - if ($("#switch-storagepool-configure-features-bookmarks-" + pool.id + " input").prop("checked")) { - if (!$("#switch-storagepool-configure-features-extensible_dataset-" + pool.id + " input").prop("checked") && !$("#switch-storagepool-configure-features-extensible_dataset-" + pool.id + " input").prop("disabled")) { - $("#switch-storagepool-configure-features-extensible_dataset-" + pool.id + " input").click(); - } - } else { - if ($("#switch-storagepool-configure-features-bookmark_v2-" + pool.id + " input").prop("checked") && !$("#switch-storagepool-configure-features-bookmark_v2-" + pool.id + " input").prop("disabled")) { - $("#switch-storagepool-configure-features-bookmark_v2-" + pool.id + " input").click(); - } - if ($("#switch-storagepool-configure-features-encryption-" + pool.id + " input").prop("checked") && !$("#switch-storagepool-configure-features-encryption-" + pool.id + " input").prop("disabled")) { - $("#switch-storagepool-configure-features-encryption-" + pool.id + " input").click(); - } - } - } else if (modal.switch.id.parent().attr("id") == "switch-storagepool-configure-features-bookmark_v2-" + pool.id) { - if ($("#switch-storagepool-configure-features-bookmark_v2-" + pool.id + " input").prop("checked")) { - if (!$("#switch-storagepool-configure-features-bookmarks-" + pool.id + " input").prop("checked") && !$("#switch-storagepool-configure-features-bookmarks-" + pool.id + " input").prop("disabled")) { - $("#switch-storagepool-configure-features-bookmarks-" + pool.id + " input").click(); - } - if (!$("#switch-storagepool-configure-features-extensible_dataset-" + pool.id + " input").prop("checked") && !$("#switch-storagepool-configure-features-extensible_dataset-" + pool.id + " input").prop("disabled")) { - $("#switch-storagepool-configure-features-extensible_dataset-" + pool.id + " input").click(); - } - } else { - if ($("#switch-storagepool-configure-features-encryption-" + pool.id + " input").prop("checked") && !$("#switch-storagepool-configure-features-encryption-" + pool.id + " input").prop("disabled")) { - $("#switch-storagepool-configure-features-encryption-" + pool.id + " input").click(); - } - } - } else if (modal.switch.id.parent().attr("id") == "switch-storagepool-configure-features-device_removal-" + pool.id) { - if (!$("#switch-storagepool-configure-features-device_removal-" + pool.id + " input").prop("checked")) { - if ($("#switch-storagepool-configure-features-obsolete_counts-" + pool.id + " input").prop("checked") && !$("#switch-storagepool-configure-features-obsolete_counts-" + pool.id + " input").prop("disabled")) { - $("#switch-storagepool-configure-features-obsolete_counts-" + pool.id + " input").click(); - } - } - } else if (modal.switch.id.parent().attr("id") == "switch-storagepool-configure-features-edonr-" + pool.id) { - if ($("#switch-storagepool-configure-features-edonr-" + pool.id + " input").prop("checked")) { - if (!$("#switch-storagepool-configure-features-extensible_dataset-" + pool.id + " input").prop("checked") && !$("#switch-storagepool-configure-features-extensible_dataset-" + pool.id + " input").prop("disabled")) { - $("#switch-storagepool-configure-features-extensible_dataset-" + pool.id + " input").click(); - } - } - } else if (modal.switch.id.parent().attr("id") == "switch-storagepool-configure-features-enabled_txg-" + pool.id) { - if (!$("#switch-storagepool-configure-features-enabled_txg-" + pool.id + " input").prop("checked")) { - if ($("#switch-storagepool-configure-features-hole_birth-" + pool.id + " input").prop("checked") && !$("#switch-storagepool-configure-features-hole_birth-" + pool.id + " input").prop("disabled")) { - $("#switch-storagepool-configure-features-hole_birth-" + pool.id + " input").click(); - } - } - } else if (modal.switch.id.parent().attr("id") == "switch-storagepool-configure-features-encryption-" + pool.id) { - if ($("#switch-storagepool-configure-features-encryption-" + pool.id + " input").prop("checked")) { - if (!$("#switch-storagepool-configure-features-bookmarks-" + pool.id + " input").prop("checked") && !$("#switch-storagepool-configure-features-bookmarks-" + pool.id + " input").prop("disabled")) { - $("#switch-storagepool-configure-features-bookmarks-" + pool.id + " input").click(); - } - if (!$("#switch-storagepool-configure-features-bookmark_v2-" + pool.id + " input").prop("checked") && !$("#switch-storagepool-configure-features-bookmark_v2-" + pool.id + " input").prop("disabled")) { - $("#switch-storagepool-configure-features-bookmark_v2-" + pool.id + " input").click(); - } - if (!$("#switch-storagepool-configure-features-extensible_dataset-" + pool.id + " input").prop("checked") && !$("#switch-storagepool-configure-features-extensible_dataset-" + pool.id + " input").prop("disabled")) { - $("#switch-storagepool-configure-features-extensible_dataset-" + pool.id + " input").click(); - } - } - } else if (modal.switch.id.parent().attr("id") == "switch-storagepool-configure-features-extensible_dataset-" + pool.id) { - if (!$("#switch-storagepool-configure-features-extensible_dataset-" + pool.id + " input").prop("checked")) { - if ($("#switch-storagepool-configure-features-bookmarks-" + pool.id + " input").prop("checked") && !$("#switch-storagepool-configure-features-bookmarks-" + pool.id + " input").prop("disabled")) { - $("#switch-storagepool-configure-features-bookmarks-" + pool.id + " input").click(); - } - if ($("#switch-storagepool-configure-features-bookmark_v2-" + pool.id + " input").prop("checked") && !$("#switch-storagepool-configure-features-bookmark_v2-" + pool.id + " input").prop("disabled")) { - $("#switch-storagepool-configure-features-bookmark_v2-" + pool.id + " input").click(); - } - if ($("#switch-storagepool-configure-features-edonr-" + pool.id + " input").prop("checked") && !$("#switch-storagepool-configure-features-edonr-" + pool.id + " input").prop("disabled")) { - $("#switch-storagepool-configure-features-edonr-" + pool.id + " input").click(); - } - if ($("#switch-storagepool-configure-features-encryption-" + pool.id + " input").prop("checked") && !$("#switch-storagepool-configure-features-encryption-" + pool.id + " input").prop("disabled")) { - $("#switch-storagepool-configure-features-encryption-" + pool.id + " input").click(); - } - if ($("#switch-storagepool-configure-features-filesystem_limits-" + pool.id + " input").prop("checked") && !$("#switch-storagepool-configure-features-filesystem_limits-" + pool.id + " input").prop("disabled")) { - $("#switch-storagepool-configure-features-filesystem_limits-" + pool.id + " input").click(); - } - if ($("#switch-storagepool-configure-features-large_blocks-" + pool.id + " input").prop("checked") && !$("#switch-storagepool-configure-features-large_blocks-" + pool.id + " input").prop("disabled")) { - $("#switch-storagepool-configure-features-large_blocks-" + pool.id + " input").click(); - } - if ($("#switch-storagepool-configure-features-large_dnode-" + pool.id + " input").prop("checked") && !$("#switch-storagepool-configure-features-large_dnode-" + pool.id + " input").prop("disabled")) { - $("#switch-storagepool-configure-features-large_dnode-" + pool.id + " input").click(); - } - if ($("#switch-storagepool-configure-features-project_quota-" + pool.id + " input").prop("checked") && !$("#switch-storagepool-configure-features-project_quota-" + pool.id + " input").prop("disabled")) { - $("#switch-storagepool-configure-features-project_quota-" + pool.id + " input").click(); - } - if ($("#switch-storagepool-configure-features-sha512-" + pool.id + " input").prop("checked") && !$("#switch-storagepool-configure-features-sha512-" + pool.id + " input").prop("disabled")) { - $("#switch-storagepool-configure-features-sha512-" + pool.id + " input").click(); - } - if ($("#switch-storagepool-configure-features-skein-" + pool.id + " input").prop("checked") && !$("#switch-storagepool-configure-features-skein-" + pool.id + " input").prop("disabled")) { - $("#switch-storagepool-configure-features-skein-" + pool.id + " input").click(); - } - if ($("#switch-storagepool-configure-features-userobj_accounting-" + pool.id + " input").prop("checked") && !$("#switch-storagepool-configure-features-userobj_accounting-" + pool.id + " input").prop("disabled")) { - $("#switch-storagepool-configure-features-userobj_accounting-" + pool.id + " input").click(); - } - } - } else if (modal.switch.id.parent().attr("id") == "switch-storagepool-configure-features-filesystem_limits-" + pool.id) { - if ($("#switch-storagepool-configure-features-filesystem_limits-" + pool.id + " input").prop("checked")) { - if (!$("#switch-storagepool-configure-features-extensible_dataset-" + pool.id + " input").prop("checked") && !$("#switch-storagepool-configure-features-extensible_dataset-" + pool.id + " input").prop("disabled")) { - $("#switch-storagepool-configure-features-extensible_dataset-" + pool.id + " input").click(); - } - } - } else if (modal.switch.id.parent().attr("id") == "switch-storagepool-configure-features-hole_birth-" + pool.id) { - if ($("#switch-storagepool-configure-features-hole_birth-" + pool.id + " input").prop("checked")) { - if (!$("#switch-storagepool-configure-features-enabled_txg-" + pool.id + " input").prop("checked") && !$("#switch-storagepool-configure-features-enabled_txg-" + pool.id + " input").prop("disabled")) { - $("#switch-storagepool-configure-features-enabled_txg-" + pool.id + " input").click(); - } - } - } else if (modal.switch.id.parent().attr("id") == "switch-storagepool-configure-features-large_blocks-" + pool.id) { - if ($("#switch-storagepool-configure-features-large_blocks-" + pool.id + " input").prop("checked")) { - if (!$("#switch-storagepool-configure-features-extensible_dataset-" + pool.id + " input").prop("checked") && !$("#switch-storagepool-configure-features-extensible_dataset-" + pool.id + " input").prop("disabled")) { - $("#switch-storagepool-configure-features-extensible_dataset-" + pool.id + " input").click(); - } - } - } else if (modal.switch.id.parent().attr("id") == "switch-storagepool-configure-features-large_dnode-" + pool.id) { - if ($("#switch-storagepool-configure-features-large_dnode-" + pool.id + " input").prop("checked")) { - if (!$("#switch-storagepool-configure-features-extensible_dataset-" + pool.id + " input").prop("checked") && !$("#switch-storagepool-configure-features-extensible_dataset-" + pool.id + " input").prop("disabled")) { - $("#switch-storagepool-configure-features-extensible_dataset-" + pool.id + " input").click(); - } - } - } else if (modal.switch.id.parent().attr("id") == "switch-storagepool-configure-features-obsolete_counts-" + pool.id) { - if ($("#switch-storagepool-configure-features-obsolete_counts-" + pool.id + " input").prop("checked")) { - if (!$("#switch-storagepool-configure-features-device_removal-" + pool.id + " input").prop("checked") && !$("#switch-storagepool-configure-features-device_removal-" + pool.id + " input").prop("disabled")) { - $("#switch-storagepool-configure-features-device_removal-" + pool.id + " input").click(); - } - } - } else if (modal.switch.id.parent().attr("id") == "switch-storagepool-configure-features-project_quota-" + pool.id) { - if ($("#switch-storagepool-configure-features-project_quota-" + pool.id + " input").prop("checked")) { - if (!$("#switch-storagepool-configure-features-extensible_dataset-" + pool.id + " input").prop("checked") && !$("#switch-storagepool-configure-features-extensible_dataset-" + pool.id + " input").prop("disabled")) { - $("#switch-storagepool-configure-features-extensible_dataset-" + pool.id + " input").click(); - } - } - } else if (modal.switch.id.parent().attr("id") == "switch-storagepool-configure-features-sha512-" + pool.id) { - if ($("#switch-storagepool-configure-features-sha512-" + pool.id + " input").prop("checked")) { - if (!$("#switch-storagepool-configure-features-extensible_dataset-" + pool.id + " input").prop("checked") && !$("#switch-storagepool-configure-features-extensible_dataset-" + pool.id + " input").prop("disabled")) { - $("#switch-storagepool-configure-features-extensible_dataset-" + pool.id + " input").click(); - } - } - } else if (modal.switch.id.parent().attr("id") == "switch-storagepool-configure-features-skein-" + pool.id) { - if ($("#switch-storagepool-configure-features-skein-" + pool.id + " input").prop("checked")) { - if (!$("#switch-storagepool-configure-features-extensible_dataset-" + pool.id + " input").prop("checked") && !$("#switch-storagepool-configure-features-extensible_dataset-" + pool.id + " input").prop("disabled")) { - $("#switch-storagepool-configure-features-extensible_dataset-" + pool.id + " input").click(); - } - } - } else if (modal.switch.id.parent().attr("id") == "switch-storagepool-configure-features-userobj_accounting-" + pool.id) { - if ($("#switch-storagepool-configure-features-userobj_accounting-" + pool.id + " input").prop("checked")) { - if (!$("#switch-storagepool-configure-features-extensible_dataset-" + pool.id + " input").prop("checked") && !$("#switch-storagepool-configure-features-extensible_dataset-" + pool.id + " input").prop("disabled")) { - $("#switch-storagepool-configure-features-extensible_dataset-" + pool.id + " input").click(); - } - } - } -} - -function FnModalStoragePoolDestroy(pool = { name, id, altroot: false }) { - let modal = { - window: "" - }; - - modal.window = ` - - - \x3Cscript nonce="1t55lZ7tzuKTreHVNwE66Ox32Mc="> - $("#btn-storagepool-destroy-` + pool.id + `").on("click", function () { - FnModalStoragePoolDestroyContent({ name: "` + pool.name + `", id: "` + pool.id + `", altroot: ` + pool.altroot + ` }, { id: $("#modal-storagepool-destroy-` + pool.id + `") }); - }); - \x3C/script> - `; - - $("#modals-storagepool-" + pool.id).append(modal.window); -} - -function FnModalStoragePoolDestroyContent(pool = { name, id, altroot: false }, modal = { id }) { - modal.content = ` - - - \x3Cscript nonce="1t55lZ7tzuKTreHVNwE66Ox32Mc="> - $("#btn-storagepool-destroy-apply-` + pool.id + `").on("click", function () { - $("#spinner-storagepool-destroy-` + pool.id + `").removeClass("hidden"); - $(this).prop("disabled", true); - - let pool = { - force: $("#switch-storagepool-destroy-force-` + pool.id + ` input").prop("checked"), - labelclear: $("#switch-storagepool-destroy-labelclear-` + pool.id + ` input").prop("checked") - }; - let samba = { - restart: $("#switch-storagepool-destroy-samba-restart-` + pool.id + ` input").prop("checked") - }; - - FnStoragePoolDestroy({ name: "` + pool.name + `", id: "` + pool.id + `", altroot: ` + pool.altroot + `, force: pool.force, labelclear: pool.labelclear }, { restart: samba.restart }); - }); - \x3C/script> - `; - - modal.id.empty().append(modal.content); -} - -function FnModalStoragePoolExport(pool = { name, id, altroot: false, readonly: false }) { - let modal = { - window: "" - }; - - modal.window = ` - - - \x3Cscript nonce="1t55lZ7tzuKTreHVNwE66Ox32Mc="> - $("#btn-storagepool-export-` + pool.id + `").on("click", function () { - FnModalStoragePoolExportContent({ name: "` + pool.name + `", id: "` + pool.id + `", altroot: ` + pool.altroot + `, readonly: ` + pool.readonly + ` }, { id: $("#modal-storagepool-export-` + pool.id + `") }); - }); - \x3C/script> - `; - - $("#modals-storagepool-" + pool.id).append(modal.window); -} - -function FnModalStoragePoolExportContent(pool = { name, id, altroot: false, readonly: false }, modal = { id }) { - modal.content = ` - - - \x3Cscript nonce="1t55lZ7tzuKTreHVNwE66Ox32Mc="> - $("#btn-storagepool-export-apply-` + pool.id + `").on("click", function () { - $("#spinner-storagepool-export-` + pool.id + `").removeClass("hidden"); - $(this).prop("disabled", true); - - let pool = { - force: $("#switch-storagepool-export-force-` + pool.id + ` input").prop("checked") - }; - let samba = { - restart: $("#switch-storagepool-export-samba-restart-` + pool.id + ` input").prop("checked") - }; - - FnStoragePoolExport({ name: "` + pool.name + `", id: "` + pool.id + `", altroot: ` + pool.altroot + `, force: pool.force, readonly: ` + pool.readonly + ` }, { restart: samba.restart }); - }); - \x3C/script> - `; - - modal.id.empty().append(modal.content); -} - -//#endregion - -//#region Modal File Systems - -function FnModalFileSystemsCreate(pool = { name, id, altroot: false, feature: { allocation_classes: true, edonr: true, encryption: true, large_blocks: true, large_dnode: true, lz4_compress: true, sha512: true, skein: true } }) { - let modal = { - window: "" - }; - - modal.window = ` - - - \x3Cscript nonce="1t55lZ7tzuKTreHVNwE66Ox32Mc="> - $("#btn-storagepool-filesystems-create-` + pool.id + `").on("click", function () { - FnModalFileSystemsCreateContent({ name: "` + pool.name + `", id: "` + pool.id + `", altroot: ` + pool.altroot + `, feature: { allocation_classes: ` + pool.feature.allocation_classes + `, edonr: ` + pool.feature.edonr + `, encryption: ` + pool.feature.encryption + `, large_blocks: ` + pool.feature.large_blocks + `, large_dnode: ` + pool.feature.large_dnode + `, lz4_compress: ` + pool.feature.lz4_compress + `, sha512: ` + pool.feature.sha512 + `, skein: ` + pool.feature.skein + ` } }, { id: $("#modal-storagepool-filesystems-create-` + pool.id + `") }); - FnFileSystemsNamesGet({ name: "` + pool.name + `", id: "` + pool.id + `" }, { existing: { name: null, clone: false, encryption: false, encryptionroot: null, origin: null}, override: true }, { dropdown: { id: $("#dropdown-storagepool-filesystems-create-parentfilesystem-` + pool.id + `"), selected: "` + pool.name + `" } }); - FnFileSystemConfigurationInheritedGet({ name: "` + pool.name + `", id: "` + pool.id + `" }, { name: "` + pool.name + `" }, { name: "storagepool-filesystems-create", id: "` + pool.id + `" }); - - $("#input-storagepool-filesystems-create-quota-` + pool.id + `").val("0"); - $("#validationwrapper-storagepool-filesystems-create-quota-` + pool.id + ` .min-slider-handle").attr("tabindex", "15"); - setTimeout(function() { - $("#input-storagepool-filesystems-create-name-` + pool.id + `").focus(); - }, 600); - }); - \x3C/script> - `; - - $("#modals-storagepool-filesystems-" + pool.id).append(modal.window); -} - -function FnModalFileSystemsCreateContent(pool = { name, id, altroot: false, feature: { allocation_classes: true, edonr: true, encryption: true, large_blocks: true, large_dnode: true, lz4_compress: true, sha512: true, skein: true } }, modal = { id }) { - modal.content = ` - - - \x3Cscript nonce="1t55lZ7tzuKTreHVNwE66Ox32Mc="> - $("#input-storagepool-filesystems-create-quota-` + pool.id + `").tooltip({ trigger: "manual" }) - .on("keyup", function (element) { - let $this = $(this); - let sd = $this.siblings("[data-provide=slider]").slider(); - - if ($this.val().trim() && !$.isNumeric(this.value)) { - this.value = sd.slider("getValue"); - } - }) - .on("keypress blur", function (element) { - if (element.which == 13 || element.type === "blur") { - element.preventDefault(); - - let $this = $(this); - let sd = $this.siblings("[data-provide=slider]").slider(); - let max = sd.slider("getAttribute", "max"); - let min = sd.slider("getAttribute", "min"); - - if (!$.isNumeric(this.value) || (this.value > max || this.value < min)) { - let warningInfo = $.isNumeric(this.value) ? "Valid value should be between " + min + " and " + max : "Valid value should be number"; - $this.attr("data-original-title", warningInfo).tooltip("show").addClass("warning"); - this.value = sd.slider("getValue"); - setTimeout(function () { - $this.tooltip("hide"); - }, 3000); - } else { - if ($this.is(".warning")) { - $this.tooltip("hide"); - } - - this.value = $this.val().trim(); - sd.slider("setValue", this.value); - } - } - }) - .siblings("[data-provide=slider]").each(function () { - $("#input-storagepool-filesystems-create-quota-` + pool.id + `").val(this.value); - $(this).slider().on("change", function (element) { - $("#input-storagepool-filesystems-create-quota-` + pool.id + `").val(element.value.newValue); - }); - }); - - $("#input-storagepool-filesystems-create-quota-` + pool.id + `").on("change textInput input", function (element) { - if ($(this).val() > 1000) { //Force reset to maximum allowed value - $(this).val(1000); - } else if ($(this).val() < 0) { //Force reset to minimum allowed value - $(this).val(0); - } - - if ($.isNumeric($(this).val())) { - $("#slider-storagepool-filesystems-create-quota-` + pool.id + `").slider("setValue", $(this).val()); - } - }); - - $("#switch-storagepool-filesystems-create-encryption-` + pool.id + ` input").on("click", function () { - $("#validationwrapper-storagepool-filesystems-create-encryption-passphrase-` + pool.id + `").removeClass("has-error"); - $("#helpblock-storagepool-filesystems-create-encryption-passphrase-` + pool.id + `").removeClass("has-error").addClass("hidden").text(""); - $("#validationwrapper-storagepool-filesystems-create-encryption-passphrase-confirm-` + pool.id + `").removeClass("has-error"); - $("#helpblock-storagepool-filesystems-create-encryption-passphrase-confirm-` + pool.id + `").removeClass("has-error").addClass("hidden").text(""); - - if ($(this).prop("checked")) { - $("#controllabel-storagepool-filesystems-create-encryption-passphrase-` + pool.id + `").removeClass("hidden"); - $("#validationwrapper-storagepool-filesystems-create-encryption-passphrase-` + pool.id + `").removeClass("hidden"); - $("#controllabel-storagepool-filesystems-create-encryption-passphrase-confirm-` + pool.id + `").removeClass("hidden"); - $("#validationwrapper-storagepool-filesystems-create-encryption-passphrase-confirm-` + pool.id + `").removeClass("hidden"); - $("#controllabel-storagepool-filesystems-create-encryption-cipher-` + pool.id + `").removeClass("hidden"); - $("#validationwrapper-storagepool-filesystems-create-encryption-cipher-` + pool.id + `").removeClass("hidden"); - } else { - $("#controllabel-storagepool-filesystems-create-encryption-passphrase-` + pool.id + `").addClass("hidden"); - $("#validationwrapper-storagepool-filesystems-create-encryption-passphrase-` + pool.id + `").addClass("hidden"); - $("#input-storagepool-filesystems-create-encryption-passphrase-` + pool.id + `").val(""); - $("#controllabel-storagepool-filesystems-create-encryption-passphrase-confirm-` + pool.id + `").addClass("hidden"); - $("#validationwrapper-storagepool-filesystems-create-encryption-passphrase-confirm-` + pool.id + `").addClass("hidden"); - $("#input-storagepool-filesystems-create-encryption-passphrase-confirm-` + pool.id + `").val(""); - $("#controllabel-storagepool-filesystems-create-encryption-cipher-` + pool.id + `").addClass("hidden"); - $("#validationwrapper-storagepool-filesystems-create-encryption-cipher-` + pool.id + `").addClass("hidden"); - } - }); - - $("#switch-storagepool-filesystems-create-sharenfs-` + pool.id + ` input").on("click", function () { - $("#validationwrapper-storagepool-filesystems-create-sharenfs-options-` + pool.id + `").removeClass("has-error"); - $("#helpblock-storagepool-filesystems-create-sharenfs-options-` + pool.id + `").removeClass("has-error").addClass("hidden").text(""); - - if ($(this).prop("checked")) { - $("#controllabel-storagepool-filesystems-create-sharenfs-options-` + pool.id + `").removeClass("hidden"); - $("#validationwrapper-storagepool-filesystems-create-sharenfs-options-` + pool.id + `").removeClass("hidden"); - - FnSystemNfsVersionGet({ alert: { id: $("#alert-storagepool-filesystems-create-sharenfs-options-` + pool.id + `") } }); - } else { - $("#validationwrapper-storagepool-filesystems-create-sharenfs-options-` + pool.id + `").addClass("hidden"); - $("#controllabel-storagepool-filesystems-create-sharenfs-options-` + pool.id + `").addClass("hidden"); - } - }); - - $("#btn-storagepool-filesystems-create-apply-` + pool.id + `").on("click", function () { - $("#spinner-storagepool-filesystems-create-` + pool.id + `").removeClass("hidden"); - $(this).prop("disabled", true); - - let filesystem = { - name: "", - id: "", - atime: "", - casesensitivity: "", - cipher: "", - compression: "", - dedup: "", - dnodesize: "", - encryption: "", - passphrase: "", - quota: "none", - readonly: "", - recordsize: "", - selinux: "", - sharesmb: "", - special_small_blocks: "", - xattr: "" - }; - let validation = { - encryption: false, - name: false, - sharenfs: false - }; - - if ($("#input-storagepool-filesystems-create-name-` + pool.id + `").val().length == 0) { - $("#helpblock-storagepool-filesystems-create-name-` + pool.id + `").addClass("has-error").removeClass("hidden").text("Name can not be empty."); - - validation.name = false; - } else if (/^[a-zA-Z0-9-_.: ]*$/.test($("#input-storagepool-filesystems-create-name-` + pool.id + `").val()) == false) { - $("#helpblock-storagepool-filesystems-create-name-` + pool.id + `").addClass("has-error").removeClass("hidden").text("Name contains invalid characters."); - - validation.name = false; - } else if (/^[.]/.test($("#input-storagepool-filesystems-create-name-` + pool.id + `").val())) { - $("#helpblock-storagepool-filesystems-create-name-` + pool.id + `").addClass("has-error").removeClass("hidden").text("Name can not begin with a period (.)."); - - validation.name = false; - } else if (/^[_]/.test($("#input-storagepool-filesystems-create-name-` + pool.id + `").val())) { - $("#helpblock-storagepool-filesystems-create-name-` + pool.id + `").addClass("has-error").removeClass("hidden").text("Name can not begin with an underscore (_)."); - - validation.name = false; - } else if (/^[-]/.test($("#input-storagepool-filesystems-create-name-` + pool.id + `").val())) { - $("#helpblock-storagepool-filesystems-create-name-` + pool.id + `").addClass("has-error").removeClass("hidden").text("Name can not begin with a hypen (-)."); - - validation.name = false; - } else if (/^[:]/.test($("#input-storagepool-filesystems-create-name-` + pool.id + `").val())) { - $("#helpblock-storagepool-filesystems-create-name-` + pool.id + `").addClass("has-error").removeClass("hidden").text("Name can not begin with an colon (:)."); - - validation.name = false; - } else if (/^[ ]/.test($("#input-storagepool-filesystems-create-name-` + pool.id + `").val())) { - $("#helpblock-storagepool-filesystems-create-name-` + pool.id + `").addClass("has-error").removeClass("hidden").text("Name can not begin with whitespace ( )."); - - validation.name = false; - } else if (/[ ]$/.test($("#input-storagepool-filesystems-create-name-` + pool.id + `").val())) { - $("#helpblock-storagepool-filesystems-create-name-` + pool.id + `").addClass("has-error").removeClass("hidden").text("Name can not end with whitespace ( )."); - - validation.name = false; - } else { - $("#validationwrapper-storagepool-filesystems-create-name-` + pool.id + `").removeClass("has-error"); - $("#helpblock-storagepool-filesystems-create-name-` + pool.id + `").addClass("hidden").text(""); - - validation.name = true; - } - if ($("#switch-storagepool-filesystems-create-encryption-` + pool.id + ` input").prop("checked")) { - if ($("#input-storagepool-filesystems-create-encryption-passphrase-` + pool.id + `").val().length == 0 && $("#switch-storagepool-filesystems-create-encryption-` + pool.id + ` input").prop("disabled")) { - $("#validationwrapper-storagepool-filesystems-create-encryption-passphrase-` + pool.id + `").removeClass("has-error"); - $("#helpblock-storagepool-filesystems-create-encryption-passphrase-` + pool.id + `").removeClass("has-error").addClass("hidden").text(""); - $("#validationwrapper-storagepool-filesystems-create-encryption-passphrase-confirm-` + pool.id + `").removeClass("has-error"); - $("#helpblock-storagepool-filesystems-create-encryption-passphrase-confirm-` + pool.id + `").removeClass("has-error").addClass("hidden").text(""); - - validation.encryption = true; - } else if ($("#input-storagepool-filesystems-create-encryption-passphrase-` + pool.id + `").val().length == 0) { - $("#validationwrapper-storagepool-filesystems-create-encryption-passphrase-` + pool.id + `").addClass("has-error"); - $("#helpblock-storagepool-filesystems-create-encryption-passphrase-` + pool.id + `").addClass("has-error").removeClass("hidden").text("Passphrase can not be empty."); - $("#input-storagepool-filesystems-create-encryption-passphrase-` + pool.id + `").focus(); - - validation.encryption = false; - } else if ($("#input-storagepool-filesystems-create-encryption-passphrase-` + pool.id + `").val().length < 8) { - $("#validationwrapper-storagepool-filesystems-create-encryption-passphrase-` + pool.id + `").addClass("has-error"); - $("#helpblock-storagepool-filesystems-create-encryption-passphrase-` + pool.id + `").addClass("has-error").removeClass("hidden").text("Passphrase requires a minimum of 8 characters."); - $("#input-storagepool-filesystems-create-encryption-passphrase-` + pool.id + `").focus(); - - validation.encryption = false; - } else if (/^[a-zA-Z0-9-_. \`~!@#$%^\(\)+\\[\\]{}:',/?]*$/.test($("#input-storagepool-filesystems-create-encryption-passphrase-` + pool.id + `").val()) == false) { - $("#validationwrapper-storagepool-filesystems-create-encryption-passphrase-` + pool.id + `").addClass("has-error"); - $("#helpblock-storagepool-filesystems-create-encryption-passphrase-` + pool.id + `").addClass("has-error").removeClass("hidden").text("Passphrase contains invalid characters."); - $("#input-storagepool-filesystems-create-encryption-passphrase-` + pool.id + `").focus(); - - validation.encryption = false; - } else if ($("#input-storagepool-filesystems-create-encryption-passphrase-confirm-` + pool.id + `").val().length < 8 || $("#input-storagepool-filesystems-create-encryption-passphrase-` + pool.id + `").val() != $("#input-storagepool-filesystems-create-encryption-passphrase-confirm-` + pool.id + `").val()) { - $("#validationwrapper-storagepool-filesystems-create-encryption-passphrase-` + pool.id + `").removeClass("has-error"); - $("#helpblock-storagepool-filesystems-create-encryption-passphrase-` + pool.id + `").removeClass("has-error").removeClass("hidden").text(""); - $("#validationwrapper-storagepool-filesystems-create-encryption-passphrase-confirm-` + pool.id + `").addClass("has-error"); - $("#helpblock-storagepool-filesystems-create-encryption-passphrase-confirm-` + pool.id + `").addClass("has-error").removeClass("hidden").text("Passphrase does not match"); - $("#input-storagepool-filesystems-create-encryption-passphrase-confirm-` + pool.id + `").focus(); - - validation.encryption = false; - } else { - $("#validationwrapper-storagepool-filesystems-create-encryption-passphrase-` + pool.id + `").removeClass("has-error"); - $("#helpblock-storagepool-filesystems-create-encryption-passphrase-` + pool.id + `").removeClass("has-error").addClass("hidden").text(""); - $("#validationwrapper-storagepool-filesystems-create-encryption-passphrase-confirm-` + pool.id + `").removeClass("has-error"); - $("#helpblock-storagepool-filesystems-create-encryption-passphrase-confirm-` + pool.id + `").removeClass("has-error").addClass("hidden").text(""); - - validation.encryption = true; - } - } else { - validation.encryption = true; - } - - if ($("#switch-storagepool-filesystems-create-sharenfs-` + pool.id + ` input").prop("checked")) { - if (/^[a-zA-Z0-9-_.:/@#+=!&*(), ]*$/.test($("#input-storagepool-filesystems-create-sharenfs-options-` + pool.id + `").val()) == false) { - $("#validationwrapper-storagepool-filesystems-create-sharenfs-options-` + pool.id + `").addClass("has-error"); - $("#helpblock-storagepool-filesystems-create-sharenfs-options-` + pool.id + `").addClass("has-error").removeClass("hidden").text("NFS Share options contain invalid characters."); - $("#input-storagepool-filesystems-create-sharenfs-options-` + pool.id + `").focus(); - - validation.sharenfs = false; - } else { - validation.sharenfs = true; - } - } else { - validation.sharenfs = true; - } - - if (!validation.name || !validation.encryption || !validation.sharenfs) { - if (!validation.name) { - $("#validationwrapper-storagepool-filesystems-create-name-` + pool.id + `").addClass("has-error"); - $("#input-storagepool-filesystems-create-name-` + pool.id + `").focus(); - } - - $("#spinner-storagepool-filesystems-create-` + pool.id + `").addClass("hidden"); - $(this).prop("disabled", false); - } - - if (validation.name && validation.encryption && validation.sharenfs) { - filesystem.atime = $("#btnspan-storagepool-filesystems-create-atime-` + pool.id + `").attr("data-field-value"); - filesystem.casesensitivity = $("#btnspan-storagepool-filesystems-create-casesensitivity-` + pool.id + `").attr("data-field-value"); - filesystem.cipher = $("#btnspan-storagepool-filesystems-create-encryption-cipher-` + pool.id + `").attr("data-field-value"); - filesystem.compression = $("#btnspan-storagepool-filesystems-create-compression-` + pool.id + `").attr("data-field-value"); - filesystem.dedup = $("#btnspan-storagepool-filesystems-create-dedup-` + pool.id + `").attr("data-field-value"); - filesystem.dnodesize = $("#btnspan-storagepool-filesystems-create-dnodesize-` + pool.id + `").attr("data-field-value"); - filesystem.encryption = $("#switch-storagepool-filesystems-create-encryption-` + pool.id + ` input").prop("checked"); - filesystem.name = $("#btnspan-storagepool-filesystems-create-parentfilesystem-` + pool.id + `").attr("data-field-value") + "/" + $("#input-storagepool-filesystems-create-name-` + pool.id + `").val(); - filesystem.id = FnGenerateId({ at: true, colon: true, forwardslash: true, period: true, underscore: true, whitespace: true }, { name: filesystem.name, attribute: true }); - filesystem.passphrase = $("#input-storagepool-filesystems-create-encryption-passphrase-` + pool.id + `").val(); - filesystem.readonly = ($("#switch-storagepool-filesystems-create-readonly-` + pool.id + ` input").prop("checked") ? "on" : "off"); - filesystem.recordsize = $("#btnspan-storagepool-filesystems-create-recordsize-` + pool.id + `").attr("data-field-value"); - filesystem.selinux = ($("#switch-storagepool-filesystems-create-selinux-` + pool.id + ` input").prop("checked") ? "on" : "off"); - filesystem.sharesmb = ($("#switch-storagepool-filesystems-create-samba-share-` + pool.id + ` input").prop("checked") ? "on" : "off"); - filesystem.special_small_blocks = $("#btnspan-storagepool-filesystems-create-special_small_blocks-` + pool.id + `").attr("data-field-value"); - filesystem.xattr = $("#btnspan-storagepool-filesystems-create-xattr-` + pool.id + `").attr("data-field-value"); - - if ($("#switch-storagepool-filesystems-create-sharenfs-` + pool.id + ` input").prop("checked")) { - if ($("#input-storagepool-filesystems-create-sharenfs-options-` + pool.id + `").val().toLowerCase() == "on" || $("#input-storagepool-filesystems-create-sharenfs-options-` + pool.id + `").val() == "sec=sys,rw,crossmnt,no_subtree_check,no_root_squash" || !$("#input-storagepool-filesystems-create-sharenfs-options-` + pool.id + `").val()) { - filesystem.sharenfs = "on"; - } else { - filesystem.sharenfs = $("#input-storagepool-filesystems-create-sharenfs-options-` + pool.id + `").val(); - } - } else { - filesystem.sharenfs = "off"; - } - - if ($("#input-storagepool-filesystems-create-quota-` + pool.id + `").val() > 0) { //Remove friendly text so final value is sent - filesystem.quota = $("#input-storagepool-filesystems-create-quota-` + pool.id + `").val() + $("#btnspan-storagepool-filesystems-create-quota-` + pool.id + `").attr("data-field-value").replace(/iB$/g, ""); - } else { - filesystem.quota = "none"; - } - - FnFileSystemCreate({ name: "` + pool.name + `", id: "` + pool.id + `", altroot: ` + pool.altroot + ` }, { name: filesystem.name, id: filesystem.id, atime: filesystem.atime, casesensitivity: filesystem.casesensitivity, cipher: filesystem.cipher, compression: filesystem.compression, dedup: filesystem.dedup, dnodesize: filesystem.dnodesize, encryption: filesystem.encryption, passphrase: filesystem.passphrase, quota: filesystem.quota, readonly: filesystem.readonly, recordsize: filesystem.recordsize, selinux: filesystem.selinux, sharenfs: filesystem.sharenfs, sharesmb: filesystem.sharesmb, special_small_blocks: filesystem.special_small_blocks, xattr: filesystem.xattr }); - } - }); - - $("#dropdown-storagepool-filesystems-create-parentfilesystem-` + pool.id + `").on("click", "li a", function () { - $("#btnspan-storagepool-filesystems-create-parentfilesystem-` + pool.id + `").text($(this).text()).attr("data-field-value", $(this).parent().attr("value")); - $(this).parent().siblings().removeClass("active"); - $(this).parent().addClass("active"); - - FnFileSystemConfigurationInheritedGet({ name: "` + pool.name + `", id: "` + pool.id + `" }, { name: $(this).text() }, { name: "storagepool-filesystems-create", id: "` + pool.id + `" }); - }); - - $("#dropdown-storagepool-filesystems-create-atime-` + pool.id + `").on("click", "li a", function () { - $("#btnspan-storagepool-filesystems-create-atime-` + pool.id + `").text($(this).text()).attr("data-field-value", $(this).parent().attr("value")); - $(this).parent().siblings().removeClass("active"); - $(this).parent().addClass("active"); - }); - - $("#dropdown-storagepool-filesystems-create-casesensitivity-` + pool.id + `").on("click", "li a", function () { - $("#btnspan-storagepool-filesystems-create-casesensitivity-` + pool.id + `").text($(this).text()).attr("data-field-value", $(this).parent().attr("value")); - $(this).parent().siblings().removeClass("active"); - $(this).parent().addClass("active"); - }); - - $("#dropdown-storagepool-filesystems-create-compression-` + pool.id + `").on("click", "li a", function () { - $("#btnspan-storagepool-filesystems-create-compression-` + pool.id + `").text($(this).text()).attr("data-field-value", $(this).parent().attr("value")); - $(this).parent().siblings().removeClass("active"); - $(this).parent().addClass("active"); - }); - - $("#dropdown-storagepool-filesystems-create-dedup-` + pool.id + `").on("click", "li a", function () { - $("#btnspan-storagepool-filesystems-create-dedup-` + pool.id + `").text($(this).text()).attr("data-field-value", $(this).parent().attr("value")); - $(this).parent().siblings().removeClass("active"); - $(this).parent().addClass("active"); - }); - - $("#dropdown-storagepool-filesystems-create-dnodesize-` + pool.id + `").on("click", "li a", function () { - $("#btnspan-storagepool-filesystems-create-dnodesize-` + pool.id + `").text($(this).text()).attr("data-field-value", $(this).parent().attr("value")); - $(this).parent().siblings().removeClass("active"); - $(this).parent().addClass("active"); - }); - - $("#dropdown-storagepool-filesystems-create-encryption-cipher-` + pool.id + `").on("click", "li a", function () { - $("#btnspan-storagepool-filesystems-create-encryption-cipher-` + pool.id + `").text($(this).text()).attr("data-field-value", $(this).parent().attr("value")); - $(this).parent().siblings().removeClass("active"); - $(this).parent().addClass("active"); - }); - - $("#dropdown-storagepool-filesystems-create-quota-` + pool.id + `").on("click", "li a", function () { - $("#btnspan-storagepool-filesystems-create-quota-` + pool.id + `").text($(this).text()).attr("data-field-value", $(this).text()); - $(this).parent().siblings().removeClass("active"); - $(this).parent().addClass("active"); - - let size = { - slider: { - value: $("#input-storagepool-filesystems-create-quota-` + pool.id + `").val(), - valuemax: $("#input-storagepool-filesystems-create-quota-` + pool.id + `").attr("data-filesystem-quota-max-" + $(this).text().toLowerCase()) - } - }; - - $("#slider-storagepool-filesystems-create-quota-` + pool.id + `").data("slider").options.max = size.slider.valuemax; - $("#slider-storagepool-filesystems-create-quota-` + pool.id + `").data("slider").options.step = (size.slider.valuemax < 10 ? "0.1" : "1"); - $("#slider-storagepool-filesystems-create-quota-` + pool.id + `").slider("setValue", 0); //Force display update - $("#slider-storagepool-filesystems-create-quota-` + pool.id + `").slider("setValue", size.slider.value); - $("#input-storagepool-filesystems-create-quota-` + pool.id + `").val($("#slider-storagepool-filesystems-create-quota-` + pool.id + `").data("slider").getValue()); - }); - - $("#dropdown-storagepool-filesystems-create-recordsize-` + pool.id + `").on("click", "li a", function () { - $("#btnspan-storagepool-filesystems-create-recordsize-` + pool.id + `").text($(this).text()).attr("data-field-value", $(this).parent().attr("value")); - $(this).parent().siblings().removeClass("active"); - $(this).parent().addClass("active"); - }); - - $("#dropdown-storagepool-filesystems-create-special_small_blocks-` + pool.id + `").on("click", "li a", function () { - $("#btnspan-storagepool-filesystems-create-special_small_blocks-` + pool.id + `").text($(this).text()).attr("data-field-value", $(this).parent().attr("value")); - $(this).parent().siblings().removeClass("active"); - $(this).parent().addClass("active"); - }); - - $("#dropdown-storagepool-filesystems-create-xattr-` + pool.id + `").on("click", "li a", function () { - $("#btnspan-storagepool-filesystems-create-xattr-` + pool.id + `").text($(this).text()).attr("data-field-value", $(this).parent().attr("value")); - $(this).parent().siblings().removeClass("active"); - $(this).parent().addClass("active"); - }); - \x3C/script> - `; - - modal.id.empty().append(modal.content); -} - -function FnModalFileSystemsUnlock() { - let modal = { - window: "" - }; - - modal.window = ` - - - \x3Cscript nonce="1t55lZ7tzuKTreHVNwE66Ox32Mc="> - $("#btn-storagepools-filesystems-unlock").on("click", function () { - FnModalFileSystemsUnlockContent({ id: $("#modal-storagepools-filesystems-unlock") }); - FnFileSystemsLockedGet(); - - setTimeout(function() { - $("#input-storagepools-filesystems-unlock-passphrase").focus(); - }, 600); - }); - \x3C/script> - `; - - $("#modals-storagepools-filesystems").append(modal.window); -} - -function FnModalFileSystemsUnlockContent(modal = { id }) { - modal.content = ` - - - \x3Cscript nonce="1t55lZ7tzuKTreHVNwE66Ox32Mc="> - $("#switch-storagepools-filesystems-unlock-mount input").on("click", function () { - if ($(this).prop("checked")) { - $("#switch-storagepools-filesystems-unlock-overlay").parent().removeClass("hidden"); - } else { - $("#switch-storagepools-filesystems-unlock-overlay").parent().addClass("hidden"); - } - }); - - $("#btn-storagepools-filesystems-unlock-apply").on("click", function () { - $("#spinner-storagepools-filesystems-unlock").removeClass("hidden"); - $(this).prop("disabled", true); - - let filesystem = { - mount: true, - passphrase: "" - }; - let filesystems = { - id: [] - }; - let modal = { - name: "storagepools-filesystems-unlock", - id: "" - }; - let samba = { - enable: false - }; - let validation = { - filesystems: false, - passphrase: false - }; - - $("#listgroup-storagepools-filesystems-unlock-filesystems input[name='checkbox-storagepools-filesystems-unlock-filesystems']:checked").map(function () { - filesystems.id.push($(this).attr("data-filesystem-name")); - }); - - if (filesystems.id.length == 0) { - $("#validationwrapper-storagepools-filesystems-unlock-filesystems").addClass("has-error"); - $("#helpblock-storagepools-filesystems-unlock-filesystems").removeClass("hidden").text("One or more file systems is needed for unlock."); - - validation.filesystems = false; - } else { - $("#validationwrapper-storagepools-filesystems-unlock-filesystems").removeClass("has-error"); - $("#helpblock-storagepools-filesystems-unlock-filesystems").removeClass("hidden").text(""); - - validation.filesystems = true; - } - - if ($("#input-storagepools-filesystems-unlock-passphrase").val().length == 0) { - $("#helpblock-storagepools-filesystems-unlock-passphrase").addClass("has-error").removeClass("hidden").text("Passphrase can not be empty."); - - validation.passphrase = false; - } else if ($("#input-storagepools-filesystems-unlock-passphrase").val().length < 8) { - $("#helpblock-storagepools-filesystems-unlock-passphrase").addClass("has-error").removeClass("hidden").text("Passphrase requires a minimum of 8 characters."); - - validation.passphrase = false; - } else if (/^[a-zA-Z0-9-_. \`~!@#$%^\(\)+\\[\\]{}:',/?]*$/.test($("#input-storagepools-filesystems-unlock-passphrase").val()) == false) { - $("#helpblock-storagepools-filesystems-unlock-passphrase").addClass("has-error").removeClass("hidden").text("Passphrase contains invalid characters."); - - validation.passphrase = false; - } else { - $("#validationwrapper-storagepools-filesystems-unlock-passphrase").removeClass("has-error"); - $("#helpblock-storagepools-filesystems-unlock-passphrase").removeClass("has-error").addClass("hidden").text(""); - - validation.passphrase = true; - } - - if (!validation.filesystems || !validation.passphrase) { - if (!validation.passphrase) { - $("#validationwrapper-storagepools-filesystems-unlock-passphrase").addClass("has-error"); - $("#input-storagepools-filesystems-unlock-passphrase").focus(); - } - - $("#spinner-storagepools-filesystems-unlock").addClass("hidden"); - $(this).prop("disabled", false); - } - - if (validation.filesystems && validation.passphrase) { - filesystem.mount = $("#switch-storagepools-filesystems-unlock-mount input").prop("checked"); - filesystem.overlay = $("#switch-storagepools-filesystems-unlock-overlay input").prop("checked"); - filesystem.passphrase = $("#input-storagepools-filesystems-unlock-passphrase").val(); - - FnFileSystemsUnlock({ id: filesystems.id }, { mount: filesystem.mount, overlay: filesystem.overlay, passphrase: filesystem.passphrase }, { name: modal.name, id: modal.id }); - } - }); - \x3C/script> - `; - - modal.id.empty().append(modal.content); -} - -//#endregion - -//#region Modal File System - -function FnModalFileSystemChangePassphrase(pool = { name, id }, filesystem = { name, id }) { - let modal = { - window: "" - }; - - modal.window = ` - - - \x3Cscript nonce="1t55lZ7tzuKTreHVNwE66Ox32Mc="> - $("#btn-storagepool-filesystem-changepassphrase-` + filesystem.id + `").on("click", function () { - FnModalFileSystemChangePassphraseContent({ name: "` + pool.name + `", id: "` + pool.id + `" }, { name: "` + filesystem.name + `", id: "` + filesystem.id + `" }, { id: $("#modal-storagepool-filesystem-changepassphrase-` + filesystem.id + `") }); - - setTimeout(function() { - $("#input-storagepool-filesystem-changepassphrase-passphrase-` + filesystem.id + `").focus(); - }, 600); - }); - \x3C/script> - `; - - $("#modals-storagepool-filesystem-" + pool.id).append(modal.window); -} - -function FnModalFileSystemChangePassphraseContent(pool = { name, id }, filesystem = { name, id }, modal = { id }) { - modal.content = ` - - - \x3Cscript nonce="1t55lZ7tzuKTreHVNwE66Ox32Mc="> - $("#btn-storagepool-filesystem-changepassphrase-apply-` + filesystem.id + `").on("click", function () { - $("#spinner-storagepool-filesystem-changepassphrase-` + filesystem.id + `").removeClass("hidden"); - $(this).prop("disabled", true); - - let filesystem = { - passphrase: "" - }; - let validation = { - passphrase: false - }; - - if ($("#input-storagepool-filesystem-changepassphrase-passphrase-` + filesystem.id + `").val().length == 0) { - $("#validationwrapper-storagepool-filesystem-changepassphrase-passphrase-` + filesystem.id + `").addClass("has-error"); - $("#helpblock-storagepool-filesystem-changepassphrase-passphrase-` + filesystem.id + `").addClass("has-error").removeClass("hidden").text("Passphrase can not be empty."); - $("#input-storagepool-filesystem-changepassphrase-passphrase-` + filesystem.id + `").focus(); - - validation.passphrase = false; - } else if ($("#input-storagepool-filesystem-changepassphrase-passphrase-` + filesystem.id + `").val().length < 8) { - $("#validationwrapper-storagepool-filesystem-changepassphrase-passphrase-` + filesystem.id + `").addClass("has-error"); - $("#helpblock-storagepool-filesystem-changepassphrase-passphrase-` + filesystem.id + `").addClass("has-error").removeClass("hidden").text("Passphrase requires a minimum of 8 characters."); - $("#input-storagepool-filesystem-changepassphrase-passphrase-` + filesystem.id + `").focus(); - - validation.passphrase = false; - } else if (/^[a-zA-Z0-9-_. \`~!@#$%^\(\)+\\[\\]{}:',/?]*$/.test($("#input-storagepool-filesystem-changepassphrase-passphrase-` + filesystem.id + `").val()) == false) { - $("#validationwrapper-storagepool-filesystem-changepassphrase-passphrase-` + filesystem.id + `").addClass("has-error"); - $("#helpblock-storagepool-filesystem-changepassphrase-passphrase-` + filesystem.id + `").addClass("has-error").removeClass("hidden").text("Passphrase contains invalid characters."); - $("#input-storagepool-filesystem-changepassphrase-passphrase-` + filesystem.id + `").focus(); - - validation.passphrase = false; - } else if ($("#input-storagepool-filesystem-changepassphrase-passphrase-confirm-` + filesystem.id + `").val().length < 8 || $("#input-storagepool-filesystem-changepassphrase-passphrase-` + filesystem.id + `").val() != $("#input-storagepool-filesystem-changepassphrase-passphrase-confirm-` + filesystem.id + `").val()) { - $("#validationwrapper-storagepool-filesystem-changepassphrase-passphrase-` + filesystem.id + `").removeClass("has-error"); - $("#helpblock-storagepool-filesystem-changepassphrase-passphrase-` + filesystem.id + `").removeClass("has-error").removeClass("hidden").text(""); - $("#validationwrapper-storagepool-filesystem-changepassphrase-passphrase-confirm-` + filesystem.id + `").addClass("has-error"); - $("#helpblock-storagepool-filesystem-changepassphrase-passphrase-confirm-` + filesystem.id + `").addClass("has-error").removeClass("hidden").text("Passphrase does not match."); - $("#input-storagepool-filesystem-changepassphrase-passphrase-confirm-` + filesystem.id + `").focus(); - - validation.passphrase = false; - } else { - $("#validationwrapper-storagepool-filesystem-changepassphrase-passphrase-` + filesystem.id + `").removeClass("has-error"); - $("#helpblock-storagepool-filesystem-changepassphrase-passphrase-` + filesystem.id + `").removeClass("has-error").removeClass("hidden").text(""); - $("#validationwrapper-storagepool-filesystem-changepassphrase-passphrase-confirm-` + filesystem.id + `").removeClass("has-error"); - $("#helpblock-storagepool-filesystem-changepassphrase-passphrase-confirm-` + filesystem.id + `").removeClass("has-error").removeClass("hidden").text(""); - - validation.passphrase = true; - } - - if (!validation.passphrase) { - $("#spinner-storagepool-filesystem-changepassphrase-` + filesystem.id + `").addClass("hidden"); - $(this).prop("disabled", false); - } - - if (validation.passphrase) { - $("#validationwrapper-storagepool-filesystem-changepassphrase-filesystem-` + filesystem.id + `").removeClass("has-error"); - $("#helpblock-storagepool-filesystem-changepassphrase-filesystem-` + filesystem.id + `").removeClass("has-error").addClass("hidden").text(""); - - filesystem.passphrase = $("#input-storagepool-filesystem-changepassphrase-passphrase-` + filesystem.id + `").val(); - - FnFileSystemChangePassphrase({ name: "` + pool.name + `", id: "` + pool.id + `" }, { name: "` + filesystem.name + `", id: "` + filesystem.id + `", passphrase: filesystem.passphrase }); - } - }); - \x3C/script> - `; - - modal.id.empty().append(modal.content); -} - -function FnModalFileSystemConfigure(pool = { name, id, altroot: false, feature: { allocation_classes: true, edonr: true, large_blocks: true, large_dnode: true, lz4_compress: true, sha512: true, skein: true }, readonly: false }, filesystem = { name, id, origin, type }) { - let modal = { - window: "" - }; - - modal.window = ` - - - \x3Cscript nonce="1t55lZ7tzuKTreHVNwE66Ox32Mc="> - $("#btn-storagepool-filesystem-configure-` + filesystem.id + `").on("click", function () { - FnModalFileSystemConfigureContent({ name: "` + pool.name + `", id: "` + pool.id + `", altroot: ` + pool.altroot + `, feature: { allocation_classes: ` + pool.feature.allocation_classes + `, edonr: ` + pool.feature.edonr + `, large_blocks: ` + pool.feature.large_blocks + `, large_dnode: ` + pool.feature.large_dnode + `, lz4_compress: ` + pool.feature.lz4_compress + `, sha512: ` + pool.feature.sha512 + `, skein: ` + pool.feature.skein + ` }, readonly: ` + pool.readonly + ` }, { name: "` + filesystem.name + `", id: "` + filesystem.id + `", origin: "` + filesystem.origin + `", type: "` + filesystem.type + `" }, { id: $("#modal-storagepool-filesystem-configure-` + filesystem.id + `") }); - FnFileSystemConfigurationGet({ name: "` + pool.name + `", id: "` + pool.id + `", readonly: ` + pool.readonly + ` }, { name: "` + filesystem.name + `", id: "` + filesystem.id + `" }, { name: "storagepool-filesystem-configure", id: "` + filesystem.id + `" }); - ` + (pool.altroot ? `FnStoragePoolAlternativeRootGet({ name: "` + pool.name + `", id: "` + pool.id + `" }, { name: "storagepool-filesystem-configure", id: "` + filesystem.id + `" });` : ``) + ` - - $("#input-storagepool-filesystem-configure-quota-` + filesystem.id + `").val("0"); - $("#validationwrapper-storagepool-filesystem-configure-quota-` + filesystem.id + ` .min-slider-handle").attr("tabindex", "14"); - $("#input-storagepool-filesystem-configure-refreservation-` + filesystem.id + `").val("0"); - $("#validationwrapper-storagepool-filesystem-configure-refreservation-` + filesystem.id + ` .min-slider-handle").attr("tabindex", "18"); - }); - \x3C/script> - `; - - $("#modals-storagepool-filesystem-" + pool.id).append(modal.window); -} - -function FnModalFileSystemConfigureContent(pool = { name, id, altroot: false, feature: { allocation_classes: true, edonr: true, large_blocks: true, large_dnode: true, lz4_compress: true, sha512: true, skein: true }, readonly: false }, filesystem = { name, id, origin, type }, modal = { id }) { - modal.content = ` - - - \x3Cscript nonce="1t55lZ7tzuKTreHVNwE66Ox32Mc="> - $("#input-storagepool-filesystem-configure-quota-` + filesystem.id + `").tooltip({ trigger: "manual" }) - .on("keyup", function (element) { - let $this = $(this); - let sd = $this.siblings("[data-provide=slider]").slider(); - - if ($this.val().trim() && !$.isNumeric(this.value)) { - this.value = sd.slider("getValue"); - } - }) - .on("keypress blur", function (element) { - if (element.which == 13 || element.type === "blur") { - element.preventDefault(); - - let $this = $(this); - let sd = $this.siblings("[data-provide=slider]").slider(); - let max = sd.slider("getAttribute", "max"); - let min = sd.slider("getAttribute", "min"); - - if (!$.isNumeric(this.value) || (this.value > max || this.value < min)) { - let warningInfo = $.isNumeric(this.value) ? "Valid value should be between " + min + " and " + max : "Valid value should be number"; - $this.attr("data-original-title", warningInfo).tooltip("show").addClass("warning"); - this.value = sd.slider("getValue"); - setTimeout(function () { - $this.tooltip("hide"); - }, 3000); - } else { - if ($this.is(".warning")) { - $this.tooltip("hide"); - } - - this.value = $this.val().trim(); - sd.slider("setValue", this.value); - } - } - }) - .siblings("[data-provide=slider]").each(function () { - $("#input-storagepool-filesystem-configure-quota-` + filesystem.id + `").val(this.value); - $(this).slider().on("change", function (element) { - $("#input-storagepool-filesystem-configure-quota-` + filesystem.id + `").val(element.value.newValue); - }); - }); - - $("#input-storagepool-filesystem-configure-quota-` + filesystem.id + `").on("change textInput input", function (element) { - if ($(this).val() > 1000) { //Force reset to maximum allowed value - $(this).val(1000); - } else if ($(this).val() < 0) { //Force reset to minimum allowed value - $(this).val(0); - } - - if ($.isNumeric($(this).val())) { - $("#slider-storagepool-filesystem-configure-quota-` + filesystem.id + `").slider("setValue", $(this).val()); - } - }); - - $("#input-storagepool-filesystem-configure-refreservation-` + filesystem.id + `").tooltip({ trigger: "manual" }) - .on("keyup", function (element) { - let $this = $(this); - let sd = $this.siblings("[data-provide=slider]").slider(); - - if ($this.val().trim() && !$.isNumeric(this.value)) { - this.value = sd.slider("getValue"); - } - }) - .on("keypress blur", function (element) { - if (element.which == 13 || element.type === "blur") { - element.preventDefault(); - - let $this = $(this); - let sd = $this.siblings("[data-provide=slider]").slider(); - let max = sd.slider("getAttribute", "max"); - let min = sd.slider("getAttribute", "min"); - - if (!$.isNumeric(this.value) || (this.value > max || this.value < min)) { - let warningInfo = $.isNumeric(this.value) ? "Valid value should be between " + min + " and " + max : "Valid value should be number"; - $this.attr("data-original-title", warningInfo).tooltip("show").addClass("warning"); - this.value = sd.slider("getValue"); - setTimeout(function () { - $this.tooltip("hide"); - }, 3000); - } else { - if ($this.is(".warning")) { - $this.tooltip("hide"); - } - - this.value = $this.val().trim(); - sd.slider("setValue", this.value); - } - } - }) - .siblings("[data-provide=slider]").each(function () { - $("#input-storagepool-filesystem-configure-refreservation-` + filesystem.id + `").val(this.value); - $(this).slider().on("change", function (element) { - $("#input-storagepool-filesystem-configure-refreservation-` + filesystem.id + `").val(element.value.newValue); - }); - }); - - $("#input-storagepool-filesystem-configure-refreservation-` + filesystem.id + `").on("change textInput input", function (element) { - if ($(this).val() > 1000) { //Force reset to maximum allowed value - $(this).val(1000); - } else if ($(this).val() < 0) { //Force reset to minimum allowed value - $(this).val(0); - } - - if ($.isNumeric($(this).val())) { - $("#slider-storagepool-filesystem-configure-refreservation-` + filesystem.id + `").slider("setValue", $(this).val()); - } - }); - - $("#switch-storagepool-filesystem-configure-sharenfs-` + filesystem.id + ` input").on("click", function () { - $("#validationwrapper-storagepool-filesystem-configure-sharenfs-options-` + filesystem.id + `").removeClass("has-error"); - $("#helpblock-storagepool-filesystem-configure-sharenfs-options-` + filesystem.id + `").removeClass("has-error").addClass("hidden").text(""); - - if ($(this).prop("checked")) { - $("#controllabel-storagepool-filesystem-configure-sharenfs-options-` + filesystem.id + `").removeClass("hidden"); - $("#validationwrapper-storagepool-filesystem-configure-sharenfs-options-` + filesystem.id + `").removeClass("hidden"); - - FnSystemNfsVersionGet({ alert: { id: $("#alert-storagepool-filesystem-configure-sharenfs-options-` + filesystem.id + `") } }); - } else { - $("#validationwrapper-storagepool-filesystem-configure-sharenfs-options-` + filesystem.id + `").addClass("hidden"); - $("#controllabel-storagepool-filesystem-configure-sharenfs-options-` + filesystem.id + `").addClass("hidden"); - } - }); - - $("#input-storagepool-filesystem-configure-mountpoint-` + filesystem.id + `").on("input", function (element) { - if ($("#switch-storagepool-filesystem-configure-sharesmb-` + filesystem.id + `").attr("data-field-value") == "on") { - if ($(this).val() != $(this).attr("data-field-value")) { - $("#switch-storagepool-filesystem-configure-samba-restart-` + filesystem.id + `").parent().removeClass("hidden"); - } else { - $("#switch-storagepool-filesystem-configure-samba-restart-` + filesystem.id + `").parent().addClass("hidden"); - } - } - }); - - $("#btn-storagepool-filesystem-configure-apply-` + filesystem.id + `").on("click",function () { - $("#spinner-storagepool-filesystem-configure-` + filesystem.id + `").removeClass("hidden"); - $(this).prop("disabled", true); - - let filesystem = { - aclinherit: "", - acltype: "", - atime: "", - canmount: "", - checksum: "", - compression: "", - context: "", - dedup: "", - dnodesize: "", - defcontext: "", - fscontext: "", - mountpoint: "", - quota: "none", - readonly: "", - recordsize: "", - refreservation: "0B", - rootcontext: "", - selinux: "", - sharenfs: "", - sharesmb: "", - special_small_blocks: "0B", - xattr: "" - }; - let modal = { - id: $("#modal-storagepool-filesystem-configure-` + filesystem.id + `") - }; - let samba = { - restart: false - }; - let validation = { - mountpoint: false, - sharenfs: false - }; - - if ($("#input-storagepool-filesystem-configure-mountpoint-` + filesystem.id + `").val().length == 0) { - $("#helpblock-storagepool-filesystem-configure-mountpoint-` + filesystem.id + `").addClass("has-error").removeClass("hidden").text("Mountpoint can not be empty."); - - validation.mountpoint = false; - } else if (/^[a-zA-Z0-9-_.:/ ]*$/.test($("#input-storagepool-filesystem-configure-mountpoint-` + filesystem.id + `").val()) == false) { - $("#helpblock-storagepool-filesystem-configure-mountpoint-` + filesystem.id + `").addClass("has-error").removeClass("hidden").text("Mountpoint contains invalid characters."); - - validation.mountpoint = false; - } else if ($("#input-storagepool-filesystem-configure-mountpoint-` + filesystem.id + `").val() && /^[/]/.test($("#input-storagepool-filesystem-configure-mountpoint-` + filesystem.id + `").val()) == false) { - $("#helpblock-storagepool-filesystem-configure-mountpoint-` + filesystem.id + `").addClass("has-error").removeClass("hidden").text("Mountpoint is an absolute path and must begin with a forward slash (/)."); - - validation.mountpoint = false; - } else if (/^[.]/.test($("#input-storagepool-filesystem-configure-mountpoint-` + filesystem.id + `").val())) { - $("#helpblock-storagepool-filesystem-configure-mountpoint-` + filesystem.id + `").addClass("has-error").removeClass("hidden").text("Mountpoint can not begin with a period (.)."); - - validation.mountpoint = false; - } else if (/[.]$/.test($("#input-storagepool-filesystem-configure-mountpoint-` + filesystem.id + `").val())) { - $("#helpblock-storagepool-filesystem-configure-mountpoint-` + filesystem.id + `").addClass("has-error").removeClass("hidden").text("Mountpoint can not end with a period (.)."); - - validation.mountpoint = false; - } else if (/[/][.][/]/g.test($("#input-storagepool-filesystem-configure-mountpoint-` + filesystem.id + `").val())) { - $("#helpblock-storagepool-filesystem-configure-mountpoint-` + filesystem.id + `").addClass("has-error").removeClass("hidden").text("Mountpoint can not contain a period as a sub directory (/./)."); - - validation.mountpoint = false; - } else if (/[/][.][.][/]/g.test($("#input-storagepool-filesystem-configure-mountpoint-` + filesystem.id + `").val())) { - $("#helpblock-storagepool-filesystem-configure-mountpoint-` + filesystem.id + `").addClass("has-error").removeClass("hidden").text("Mountpoint can not contain a double period as a sub directory (/../)."); - - validation.mountpoint = false; - } else if (/[/][/]/g.test($("#input-storagepool-filesystem-configure-mountpoint-` + filesystem.id + `").val())) { - $("#helpblock-storagepool-filesystem-configure-mountpoint-` + filesystem.id + `").addClass("has-error").removeClass("hidden").text("Mountpoint can not contain double forward slashes (//)."); - - validation.mountpoint = false; - } else if (/[.][.]/g.test($("#input-storagepool-filesystem-configure-mountpoint-` + filesystem.id + `").val())) { - $("#helpblock-storagepool-filesystem-configure-mountpoint-` + filesystem.id + `").addClass("has-error").removeClass("hidden").text("Mountpoint can not contain a double period (..)."); - - validation.mountpoint = false; - } else if (/^[ ]/.test($("#input-storagepool-filesystem-configure-mountpoint-` + filesystem.id + `").val())) { - $("#helpblock-storagepool-filesystem-configure-mountpoint-` + filesystem.id + `").addClass("has-error").removeClass("hidden").text("Mountpoint can not begin with whitespace ( )."); - - validation.mountpoint = false; - } else if (/[ ]$/.test($("#input-storagepool-filesystem-configure-mountpoint-` + filesystem.id + `").val())) { - $("#helpblock-storagepool-filesystem-configure-mountpoint-` + filesystem.id + `").addClass("has-error").removeClass("hidden").text("Mountpoint can not end with whitespace ( )."); - - validation.mountpoint = false; - } else { - $("#validationwrapper-storagepool-filesystem-configure-mountpoint-` + filesystem.id + `").removeClass("has-error"); - $("#helpblock-storagepool-filesystem-configure-mountpoint-` + filesystem.id + `").addClass("hidden").text(""); - - validation.mountpoint = true; - } - - if ($("#switch-storagepool-filesystem-configure-sharenfs-` + filesystem.id + ` input").prop("checked")) { - if (/^[a-zA-Z0-9-_.:/@#+=!&*(), ]*$/.test($("#input-storagepool-filesystem-configure-sharenfs-options-` + filesystem.id + `").val()) == false) { - $("#validationwrapper-storagepool-filesystem-configure-sharenfs-options-` + filesystem.id + `").addClass("has-error"); - $("#helpblock-storagepool-filesystem-configure-sharenfs-options-` + filesystem.id + `").addClass("has-error").removeClass("hidden").text("NFS Share options contain invalid characters."); - $("#input-storagepool-filesystem-configure-sharenfs-options-` + filesystem.id + `").focus(); - - validation.sharenfs = false; - } else { - validation.sharenfs = true; - } - } else { - validation.sharenfs = true; - } - - if (!validation.mountpoint || !validation.sharenfs) { - if (!validation.mountpoint) { - $("#validationwrapper-storagepool-filesystem-configure-mountpoint-` + filesystem.id + `").addClass("has-error"); - $("#input-storagepool-filesystem-configure-mountpoint-` + filesystem.id + `").focus(); - } - - $("#spinner-storagepool-filesystem-configure-` + filesystem.id + `").addClass("hidden"); - $(this).prop("disabled", false); - } - - if (validation.mountpoint && validation.sharenfs) { - filesystem.aclinherit = ($("#btnspan-storagepool-filesystem-configure-aclinherit-` + filesystem.id + `").attr("data-field-value-new") != "" ? $("#btnspan-storagepool-filesystem-configure-aclinherit-` + filesystem.id + `").attr("data-field-value-new") : null); - filesystem.acltype = ($("#btnspan-storagepool-filesystem-configure-acltype-` + filesystem.id + `").attr("data-field-value-new") != "" ? $("#btnspan-storagepool-filesystem-configure-acltype-` + filesystem.id + `").attr("data-field-value-new") : null); - filesystem.atime = ($("#btnspan-storagepool-filesystem-configure-atime-` + filesystem.id + `").attr("data-field-value-new") != "" ? $("#btnspan-storagepool-filesystem-configure-atime-` + filesystem.id + `").attr("data-field-value-new") : null); - filesystem.canmount = ($("#btnspan-storagepool-filesystem-configure-canmount-` + filesystem.id + `").attr("data-field-value-new") != "" ? $("#btnspan-storagepool-filesystem-configure-canmount-` + filesystem.id + `").attr("data-field-value-new") : null); - filesystem.checksum = ($("#btnspan-storagepool-filesystem-configure-checksum-` + filesystem.id + `").attr("data-field-value-new") != "" ? $("#btnspan-storagepool-filesystem-configure-checksum-` + filesystem.id + `").attr("data-field-value-new") : null); - filesystem.compression = ($("#btnspan-storagepool-filesystem-configure-compression-` + filesystem.id + `").attr("data-field-value-new") != "" ? $("#btnspan-storagepool-filesystem-configure-compression-` + filesystem.id + `").attr("data-field-value-new") : null); - filesystem.context = ($("#switch-storagepool-filesystem-configure-selinux-` + filesystem.id + ` input").prop("checked") ? "system_u:object_r:samba_share_t:s0" : "none"); - filesystem.dedup = ($("#btnspan-storagepool-filesystem-configure-dedup-` + filesystem.id + `").attr("data-field-value-new") != "" ? $("#btnspan-storagepool-filesystem-configure-dedup-` + filesystem.id + `").attr("data-field-value-new") : null); - filesystem.dnodesize = ($("#btnspan-storagepool-filesystem-configure-dnodesize-` + filesystem.id + `").attr("data-field-value-new") != "" ? $("#btnspan-storagepool-filesystem-configure-dnodesize-` + filesystem.id + `").attr("data-field-value-new") : null); - filesystem.defcontext = ($("#switch-storagepool-filesystem-configure-selinux-` + filesystem.id + ` input").prop("checked") ? "system_u:object_r:samba_share_t:s0" : "none"); - filesystem.fscontext = ($("#switch-storagepool-filesystem-configure-selinux-` + filesystem.id + ` input").prop("checked") ? "system_u:object_r:samba_share_t:s0" : "none"); - filesystem.mountpoint = $("#input-storagepool-filesystem-configure-mountpoint-` + filesystem.id + `").val(); - filesystem.readonly = ($("#switch-storagepool-filesystem-configure-readonly-` + filesystem.id + ` input").prop("checked") ? "on" : "off"); - filesystem.recordsize = ($("#btnspan-storagepool-filesystem-configure-recordsize-` + filesystem.id + `").attr("data-field-value-new") != "" ? $("#btnspan-storagepool-filesystem-configure-recordsize-` + filesystem.id + `").attr("data-field-value-new") : null); - filesystem.rootcontext = ($("#switch-storagepool-filesystem-configure-selinux-` + filesystem.id + ` input").prop("checked") ? "system_u:object_r:samba_share_t:s0" : "none"); - filesystem.selinux = $("#switch-storagepool-filesystem-configure-selinux-` + filesystem.id + ` input").prop("checked"); - filesystem.sharesmb = ` + (zfsmanager.configuration.samba.manage ? `$("#switch-storagepool-filesystem-configure-sharesmb-` + filesystem.id + `").attr("data-field-value");` : `($("#switch-storagepool-filesystem-configure-sharesmb-` + filesystem.id + ` input").prop("checked") ? "on" : "off");`) + ` - filesystem.special_small_blocks = ($("#btnspan-storagepool-filesystem-configure-special_small_blocks-` + filesystem.id + `").attr("data-field-value-new") != "" ? $("#btnspan-storagepool-filesystem-configure-special_small_blocks-` + filesystem.id + `").attr("data-field-value-new") : null); - filesystem.xattr = ($("#btnspan-storagepool-filesystem-configure-xattr-` + filesystem.id + `").attr("data-field-value-new") != "" ? $("#btnspan-storagepool-filesystem-configure-xattr-` + filesystem.id + `").attr("data-field-value-new") : null); - - if ($("#input-storagepool-filesystem-configure-quota-` + filesystem.id + `").val() > 0) { //Remove friendly text so final value is sent - filesystem.quota = $("#input-storagepool-filesystem-configure-quota-` + filesystem.id + `").val() + $("#btnspan-storagepool-filesystem-configure-quota-` + filesystem.id + `").attr("data-field-value").replace(/iB$/g, ""); - } else { - filesystem.quota = "none"; - } - - if ($("#input-storagepool-filesystem-configure-refreservation-` + filesystem.id + `").val() > 0) { //Remove friendly text so final value is sent - filesystem.refreservation = $("#input-storagepool-filesystem-configure-refreservation-` + filesystem.id + `").val() + $("#btnspan-storagepool-filesystem-configure-refreservation-` + filesystem.id + `").attr("data-field-value").replace(/iB$/g, ""); - } else { - filesystem.refreservation = "0B"; - } - - if ($("#switch-storagepool-filesystem-configure-sharenfs-` + filesystem.id + ` input").prop("checked")) { - if ($("#input-storagepool-filesystem-configure-sharenfs-options-` + filesystem.id + `").val().toLowerCase() == "on" || $("#input-storagepool-filesystem-configure-sharenfs-options-` + filesystem.id + `").val() == "sec=sys,rw,crossmnt,no_subtree_check,no_root_squash" || !$("#input-storagepool-filesystem-configure-sharenfs-options-` + filesystem.id + `").val()) { - filesystem.sharenfs = "on"; - } else { - filesystem.sharenfs = $("#input-storagepool-filesystem-configure-sharenfs-options-` + filesystem.id + `").val(); - } - } else { - filesystem.sharenfs = "off"; - } - - //Set values to null if unchanged, so that they are skipped in the configure function - if (/^Inherited/.test(filesystem.aclinherit) && $("#btnspan-storagepool-filesystem-configure-aclinherit-` + filesystem.id + `").attr("data-field-source") == "inherited") { - filesystem.aclinherit = null; - } else if (/^Default/.test(filesystem.aclinherit) && $("#btnspan-storagepool-filesystem-configure-aclinherit-` + filesystem.id + `").attr("data-field-source") == "default") { - filesystem.aclinherit = null; - } else if (filesystem.aclinherit == $("#btnspan-storagepool-filesystem-configure-aclinherit-` + filesystem.id + `").attr("data-field-value") && $("#btnspan-storagepool-filesystem-configure-aclinherit-` + filesystem.id + `").attr("data-field-source") == "local") { - filesystem.aclinherit = null; - } - - if (/^Inherited/.test(filesystem.acltype) && $("#btnspan-storagepool-filesystem-configure-acltype-` + filesystem.id + `").attr("data-field-source") == "inherited") { - filesystem.acltype = null; - } else if (/^Default/.test(filesystem.acltype) && $("#btnspan-storagepool-filesystem-configure-acltype-` + filesystem.id + `").attr("data-field-source") == "default") { - filesystem.acltype = null; - } else if (filesystem.acltype == $("#btnspan-storagepool-filesystem-configure-acltype-` + filesystem.id + `").attr("data-field-value") && $("#btnspan-storagepool-filesystem-configure-acltype-` + filesystem.id + `").attr("data-field-source") == "local") { - filesystem.acltype = null; - } - - if (/^Inherited/.test(filesystem.atime) && $("#btnspan-storagepool-filesystem-configure-atime-` + filesystem.id + `").attr("data-field-source") == "inherited") { - filesystem.atime = null; - } else if (/^Default/.test(filesystem.atime) && $("#btnspan-storagepool-filesystem-configure-atime-` + filesystem.id + `").attr("data-field-source") == "default") { - filesystem.atime = null; - } else if (filesystem.atime == $("#btnspan-storagepool-filesystem-configure-atime-` + filesystem.id + `").attr("data-field-value") && $("#btnspan-storagepool-filesystem-configure-atime-` + filesystem.id + `").attr("data-field-source") == "local") { - filesystem.atime = null; - } - - if (filesystem.canmount == $("#btnspan-storagepool-filesystem-configure-canmount-` + filesystem.id + `").attr("data-field-value")) { - filesystem.canmount = null; - } - - if (/^Inherited/.test(filesystem.checksum) && $("#btnspan-storagepool-filesystem-configure-checksum-` + filesystem.id + `").attr("data-field-source") == "inherited") { - filesystem.checksum = null; - } else if (/^Default/.test(filesystem.checksum) && $("#btnspan-storagepool-filesystem-configure-checksum-` + filesystem.id + `").attr("data-field-source") == "default") { - filesystem.checksum = null; - } else if (filesystem.checksum == $("#btnspan-storagepool-filesystem-configure-checksum-` + filesystem.id + `").attr("data-field-value") && $("#btnspan-storagepool-filesystem-configure-checksum-` + filesystem.id + `").attr("data-field-source") == "local") { - filesystem.checksum = null; - } - - if (/^Inherited/.test(filesystem.compression) && $("#btnspan-storagepool-filesystem-configure-compression-` + filesystem.id + `").attr("data-field-source") == "inherited") { - filesystem.compression = null; - } else if (/^Default/.test(filesystem.compression) && $("#btnspan-storagepool-filesystem-configure-compression-` + filesystem.id + `").attr("data-field-source") == "default") { - filesystem.compression = null; - } else if (filesystem.compression == $("#btnspan-storagepool-filesystem-configure-compression-` + filesystem.id + `").attr("data-field-value") && $("#btnspan-storagepool-filesystem-configure-compression-` + filesystem.id + `").attr("data-field-source") == "local") { - filesystem.compression = null; - } - - - if (/^Inherited/.test(filesystem.dedup) && $("#btnspan-storagepool-filesystem-configure-dedup-` + filesystem.id + `").attr("data-field-source") == "inherited") { - filesystem.dedup = null; - } else if (/^Default/.test(filesystem.dedup) && $("#btnspan-storagepool-filesystem-configure-dedup-` + filesystem.id + `").attr("data-field-source") == "default") { - filesystem.dedup = null; - } else if (filesystem.dedup == $("#btnspan-storagepool-filesystem-configure-dedup-` + filesystem.id + `").attr("data-field-value") && $("#btnspan-storagepool-filesystem-configure-dedup-` + filesystem.id + `").attr("data-field-source") == "local") { - filesystem.dedup = null; - } - - if (/^Inherited/.test(filesystem.dnodesize) && $("#btnspan-storagepool-filesystem-configure-dnodesize-` + filesystem.id + `").attr("data-field-source") == "inherited") { - filesystem.dnodesize = null; - } else if (/^Default/.test(filesystem.dnodesize) && $("#btnspan-storagepool-filesystem-configure-dnodesize-` + filesystem.id + `").attr("data-field-source") == "default") { - filesystem.dnodesize = null; - } else if (filesystem.dnodesize == $("#btnspan-storagepool-filesystem-configure-dnodesize-` + filesystem.id + `").attr("data-field-value") && $("#btnspan-storagepool-filesystem-configure-dnodesize-` + filesystem.id + `").attr("data-field-source") == "local") { - filesystem.dnodesize = null; - } - - if (filesystem.mountpoint == $("#input-storagepool-filesystem-configure-mountpoint-` + filesystem.id + `").attr("data-field-value")) { - filesystem.mountpoint = null; - } else { - ` + (pool.altroot ? `filesystem.mountpoint = filesystem.mountpoint.replace(new RegExp("^" + $("#input-storagepool-filesystem-configure-mountpoint-` + filesystem.id + `").attr("data-field-altroot")), "");` : ``) + ` - - samba.restart = $("#switch-storagepool-filesystem-configure-samba-restart-` + filesystem.id + ` input").prop("checked"); - } - - if (filesystem.quota == $("#input-storagepool-filesystem-configure-quota-` + filesystem.id + `").attr("data-field-value")) { - filesystem.quota = null; - } - - if (filesystem.readonly == $("#switch-storagepool-filesystem-configure-readonly-` + filesystem.id + `").attr("data-field-value")) { - filesystem.readonly = null; - } - - if (/^Inherited/.test(filesystem.recordsize) && $("#btnspan-storagepool-filesystem-configure-recordsize-` + filesystem.id + `").attr("data-field-source") == "inherited") { - filesystem.recordsize = null; - } else if (/^Default/.test(filesystem.recordsize) && $("#btnspan-storagepool-filesystem-configure-recordsize-` + filesystem.id + `").attr("data-field-source") == "default") { - filesystem.recordsize = null; - } else if (filesystem.recordsize == $("#btnspan-storagepool-filesystem-configure-recordsize-` + filesystem.id + `").attr("data-field-value") && $("#btnspan-storagepool-filesystem-configure-recordsize-` + filesystem.id + `").attr("data-field-source") == "local") { - filesystem.recordsize = null; - } - - if (filesystem.refreservation == $("#input-storagepool-filesystem-configure-refreservation-` + filesystem.id + `").attr("data-field-value")) { - filesystem.refreservation = null; - } - - if (filesystem.selinux == $("#switch-storagepool-filesystem-configure-selinux-` + filesystem.id + `").attr("data-field-value")) { - filesystem.context = null; - filesystem.defcontext = null; - filesystem.fscontext = null; - filesystem.rootcontext = null; - filesystem.selinux = null; - } - - if (filesystem.sharenfs == $("#input-storagepool-filesystem-configure-sharenfs-options-` + filesystem.id + `").attr("data-field-value")) { - filesystem.sharenfs = null; - } - - if (/^Inherited/.test(filesystem.special_small_blocks) && $("#btnspan-storagepool-filesystem-configure-special_small_blocks-` + filesystem.id + `").attr("data-field-source") == "inherited") { - filesystem.special_small_blocks = null; - } else if (/^Default/.test(filesystem.special_small_blocks) && $("#btnspan-storagepool-filesystem-configure-special_small_blocks-` + filesystem.id + `").attr("data-field-source") == "default") { - filesystem.special_small_blocks = null; - } else if (filesystem.special_small_blocks == $("#btnspan-storagepool-filesystem-configure-special_small_blocks-` + filesystem.id + `").attr("data-field-value") && $("#btnspan-storagepool-filesystem-configure-special_small_blocks-` + filesystem.id + `").attr("data-field-source") == "local") { - filesystem.special_small_blocks = null; - } - - if (/^Inherited/.test(filesystem.xattr) && $("#btnspan-storagepool-filesystem-configure-xattr-` + filesystem.id + `").attr("data-field-source") == "inherited") { - filesystem.xattr = null; - } else if (/^Default/.test(filesystem.xattr) && $("#btnspan-storagepool-filesystem-configure-xattr-` + filesystem.id + `").attr("data-field-source") == "default") { - filesystem.xattr = null; - } else if (filesystem.xattr == $("#btnspan-storagepool-filesystem-configure-xattr-` + filesystem.id + `").attr("data-field-value") && $("#btnspan-storagepool-filesystem-configure-xattr-` + filesystem.id + `").attr("data-field-source") == "local") { - filesystem.xattr = null; - } - - FnFileSystemConfigure({ name: "` + pool.name + `", id: "` + pool.id + `", altroot: ` + pool.altroot + `, readonly: ` + pool.readonly + ` }, { name: "` + filesystem.name + `", id: "` + filesystem.id + `", aclinherit: filesystem.aclinherit, acltype: filesystem.acltype, atime: filesystem.atime, canmount: filesystem.canmount, checksum: filesystem.checksum, compression: filesystem.compression, context: filesystem.context, dedup: filesystem.dedup, dnodesize: filesystem.dnodesize, defcontext: filesystem.defcontext, fscontext: filesystem.fscontext, mountpoint: filesystem.mountpoint, quota: filesystem.quota, readonly: filesystem.readonly, recordsize: filesystem.recordsize, refreservation: filesystem.refreservation, rootcontext: filesystem.rootcontext, sharenfs: filesystem.sharenfs, sharesmb: filesystem.sharesmb, special_small_blocks: filesystem.special_small_blocks, type: "` + filesystem.type + `", xattr: filesystem.xattr }, { restart: samba.restart }, { id: modal.id }); - } - }); - - $("#dropdown-storagepool-filesystem-configure-aclinherit-` + filesystem.id + `").on("click", "li a", function () { - $("#btnspan-storagepool-filesystem-configure-aclinherit-` + filesystem.id + `").text($(this).text()).attr("data-field-value-new", (/^Default/.test($(this).text()) ? "Default" : $(this).parent().attr("value"))); - $(this).parent().siblings().removeClass("active"); - $(this).parent().addClass("active"); - }); - - $("#dropdown-storagepool-filesystem-configure-acltype-` + filesystem.id + `").on("click", "li a", function () { - $("#btnspan-storagepool-filesystem-configure-acltype-` + filesystem.id + `").text($(this).text()).attr("data-field-value-new", (/^Default/.test($(this).text()) ? "Default" : $(this).parent().attr("value"))); - $(this).parent().siblings().removeClass("active"); - $(this).parent().addClass("active"); - }); - - $("#dropdown-storagepool-filesystem-configure-atime-` + filesystem.id + `").on("click", "li a", function () { - $("#btnspan-storagepool-filesystem-configure-atime-` + filesystem.id + `").text($(this).text()).attr("data-field-value-new", (/^Default/.test($(this).text()) ? "Default" : $(this).parent().attr("value"))); - $(this).parent().siblings().removeClass("active"); - $(this).parent().addClass("active"); - }); - - $("#dropdown-storagepool-filesystem-configure-canmount-` + filesystem.id + `").on("click", "li a", function () { - $("#btnspan-storagepool-filesystem-configure-canmount-` + filesystem.id + `").text($(this).text()).attr("data-field-value-new", (/^Default/.test($(this).text()) ? "Default" : $(this).parent().attr("value"))); - $(this).parent().siblings().removeClass("active"); - $(this).parent().addClass("active"); - }); - - $("#dropdown-storagepool-filesystem-configure-checksum-` + filesystem.id + `").on("click", "li a", function () { - $("#btnspan-storagepool-filesystem-configure-checksum-` + filesystem.id + `").text($(this).text()).attr("data-field-value-new", (/^Default/.test($(this).text()) ? "Default" : $(this).parent().attr("value"))); - $(this).parent().siblings().removeClass("active"); - $(this).parent().addClass("active"); - }); - - $("#dropdown-storagepool-filesystem-configure-compression-` + filesystem.id + `").on("click", "li a", function () { - $("#btnspan-storagepool-filesystem-configure-compression-` + filesystem.id + `").text($(this).text()).attr("data-field-value-new", (/^Default/.test($(this).text()) ? "Default" : $(this).parent().attr("value"))); - $(this).parent().siblings().removeClass("active"); - $(this).parent().addClass("active"); - }); - - $("#dropdown-storagepool-filesystem-configure-dedup-` + filesystem.id + `").on("click", "li a", function () { - $("#btnspan-storagepool-filesystem-configure-dedup-` + filesystem.id + `").text($(this).text()).attr("data-field-value-new", (/^Default/.test($(this).text()) ? "Default" : $(this).parent().attr("value"))); - $(this).parent().siblings().removeClass("active"); - $(this).parent().addClass("active"); - }); - - $("#dropdown-storagepool-filesystem-configure-dnodesize-` + filesystem.id + `").on("click", "li a", function () { - $("#btnspan-storagepool-filesystem-configure-dnodesize-` + filesystem.id + `").text($(this).text()).attr("data-field-value-new", (/^Default/.test($(this).text()) ? "Default" : $(this).parent().attr("value"))); - $(this).parent().siblings().removeClass("active"); - $(this).parent().addClass("active"); - }); - - $("#dropdown-storagepool-filesystem-configure-quota-` + filesystem.id + `").on("click", "li a", function () { - $("#btnspan-storagepool-filesystem-configure-quota-` + filesystem.id + `").text($(this).text()).attr("data-field-value", $(this).text()); - $(this).parent().siblings().removeClass("active"); - $(this).parent().addClass("active"); - - let size = { - slider: { - value: $("#input-storagepool-filesystem-configure-quota-` + filesystem.id + `").val(), - valuemax: $("#input-storagepool-filesystem-configure-quota-` + filesystem.id + `").attr("data-filesystem-quota-max-" + $(this).text().toLowerCase()) - } - }; - - $("#slider-storagepool-filesystem-configure-quota-` + filesystem.id + `").data("slider").options.max = size.slider.valuemax; - $("#slider-storagepool-filesystem-configure-quota-` + filesystem.id + `").data("slider").options.step = (size.slider.valuemax < 10 ? "0.1" : "1"); - $("#slider-storagepool-filesystem-configure-quota-` + filesystem.id + `").slider("setValue", 0); //Force display update - $("#slider-storagepool-filesystem-configure-quota-` + filesystem.id + `").slider("setValue", size.slider.value); - $("#input-storagepool-filesystem-configure-quota-` + filesystem.id + `").val($("#slider-storagepool-filesystem-configure-quota-` + filesystem.id + `").data("slider").getValue()); - }); - - $("#dropdown-storagepool-filesystem-configure-recordsize-` + filesystem.id + `").on("click", "li a", function () { - $("#btnspan-storagepool-filesystem-configure-recordsize-` + filesystem.id + `").text($(this).text()).attr("data-field-value-new", (/^Default/.test($(this).text()) ? "Default" : $(this).parent().attr("value"))); - $(this).parent().siblings().removeClass("active"); - $(this).parent().addClass("active"); - }); - - $("#dropdown-storagepool-filesystem-configure-refreservation-` + filesystem.id + `").on("click", "li a", function () { - $("#btnspan-storagepool-filesystem-configure-refreservation-` + filesystem.id + `").text($(this).text()).attr("data-field-value", $(this).text()); - $(this).parent().siblings().removeClass("active"); - $(this).parent().addClass("active"); - - let size = { - slider: { - value: $("#input-storagepool-filesystem-configure-refreservation-` + filesystem.id + `").val(), - valuemax: $("#input-storagepool-filesystem-configure-refreservation-` + filesystem.id + `").attr("data-filesystem-refreservation-max-" + $(this).text().toLowerCase()) - } - }; - - $("#slider-storagepool-filesystem-configure-refreservation-` + filesystem.id + `").data("slider").options.max = size.slider.valuemax; - $("#slider-storagepool-filesystem-configure-refreservation-` + filesystem.id + `").data("slider").options.step = (size.slider.valuemax < 10 ? "0.1" : "1"); - $("#slider-storagepool-filesystem-configure-refreservation-` + filesystem.id + `").slider("setValue", 0); //Force display update - $("#slider-storagepool-filesystem-configure-refreservation-` + filesystem.id + `").slider("setValue", size.slider.value); - $("#input-storagepool-filesystem-configure-refreservation-` + filesystem.id + `").val($("#slider-storagepool-filesystem-configure-refreservation-` + filesystem.id + `").data("slider").getValue()); - }); - - $("#dropdown-storagepool-filesystem-configure-special_small_blocks-` + filesystem.id + `").on("click", "li a", function () { - $("#btnspan-storagepool-filesystem-configure-special_small_blocks-` + filesystem.id + `").text($(this).text()).attr("data-field-value-new", (/^Default/.test($(this).text()) ? "Default" : $(this).parent().attr("value"))); - $(this).parent().siblings().removeClass("active"); - $(this).parent().addClass("active"); - }); - - $("#dropdown-storagepool-filesystem-configure-xattr-` + filesystem.id + `").on("click", "li a", function () { - $("#btnspan-storagepool-filesystem-configure-xattr-` + filesystem.id + `").text($(this).text()).attr("data-field-value-new", (/^Default/.test($(this).text()) ? "Default" : $(this).parent().attr("value"))); - $(this).parent().siblings().removeClass("active"); - $(this).parent().addClass("active"); - }); - \x3C/script> - `; - - modal.id.empty().append(modal.content); -} - -function FnModalFileSystemDestroy(pool = { name, id, altroot: false, readonly: false }, filesystem = { name, id, sharesmb: false, type }) { - let modal = { - window: "" - }; - - modal.window = ` - - - \x3Cscript nonce="1t55lZ7tzuKTreHVNwE66Ox32Mc="> - $("#btn-storagepool-filesystem-destroy-` + filesystem.id + `").on("click", function () { - FnModalFileSystemDestroyContent({ name: "` + pool.name + `", id: "` + pool.id + `", altroot: ` + pool.altroot + `, readonly: ` + pool.readonly + ` }, { name: "` + filesystem.name + `", id: "` + filesystem.id + `", sharesmb: ` + filesystem.sharesmb + `, type: "` + filesystem.type + `" }, { id: $("#modal-storagepool-filesystem-destroy-` + filesystem.id + `") }); - FnFileSystemChildDatasetsGet({ name: "` + pool.name + `", id: "` + pool.id + `" }, { name: "` + filesystem.name + `", id: "` + filesystem.id + `", clones: true }, { name: "storagepool-filesystem-destroy", id: "` + filesystem.id + `" }); - }); - \x3C/script> - `; - - $("#modals-storagepool-filesystem-" + pool.id).append(modal.window); -} - -function FnModalFileSystemDestroyContent(pool = { name, id, altroot: false, readonly: false }, filesystem = { name, id, sharesmb: false, type }, modal = { id }) { - modal.content = ` - - - \x3Cscript nonce="1t55lZ7tzuKTreHVNwE66Ox32Mc="> - $("#switch-storagepool-filesystem-destroy-recursive-` + filesystem.id + ` input").on("click", function () { - if ($(this).prop("checked") && $("#switch-storagepool-filesystem-destroy-recursiveall-` + filesystem.id + ` input").prop("checked")) { - $("#switch-storagepool-filesystem-destroy-recursiveall-` + filesystem.id + ` input").click(); - } - - $("#panel-storagepool-filesystem-destroy-child-filesystemswithclones-` + filesystem.id + `").addClass("hidden"); - $("#panel-storagepool-filesystem-destroy-child-filesystemswithclones-` + filesystem.id + ` .collapse").collapse("hide"); - $("#panel-storagepool-filesystem-destroy-child-snapshotswithclones-` + filesystem.id + `").addClass("hidden"); - $("#panel-storagepool-filesystem-destroy-child-snapshotswithclones-` + filesystem.id + ` .collapse").collapse("hide"); - - if ($(this).prop("checked") && $("#panelgroup-storagepool-filesystem-destroy-` + filesystem.id + `").attr("data-filesystem-child-filesystems") > 0) { - $("#panel-storagepool-filesystem-destroy-child-filesystems-` + filesystem.id + `").removeClass("hidden"); - } else { - $("#panel-storagepool-filesystem-destroy-child-filesystems-` + filesystem.id + `").addClass("hidden"); - $("#panel-storagepool-filesystem-destroy-child-filesystems-` + filesystem.id + ` .collapse").collapse("hide"); - } - if ($(this).prop("checked") && $("#panelgroup-storagepool-filesystem-destroy-` + filesystem.id + `").attr("data-filesystem-child-snapshots") > 0) { - $("#panel-storagepool-filesystem-destroy-child-snapshots-` + filesystem.id + `").removeClass("hidden"); - } else { - $("#panel-storagepool-filesystem-destroy-child-snapshots-` + filesystem.id + `").addClass("hidden"); - $("#panel-storagepool-filesystem-destroy-child-snapshots-` + filesystem.id + ` .collapse").collapse("hide"); - } - if ($(this).prop("checked") && ($("#panelgroup-storagepool-filesystem-destroy-` + filesystem.id + `").attr("data-filesystem-child-filesystems") > 0 || $("#panelgroup-storagepool-filesystem-destroy-` + filesystem.id + `").attr("data-filesystem-child-snapshots") > 0)) { - $("#panelgroup-storagepool-filesystem-destroy-` + filesystem.id + `").addClass("modal-ct-bodytext-1"); - } else { - $("#panelgroup-storagepool-filesystem-destroy-` + filesystem.id + `").removeClass("modal-ct-bodytext-1"); - } - }); - - $("#switch-storagepool-filesystem-destroy-recursiveall-` + filesystem.id + ` input").on("click", function () { - if ($(this).prop("checked") && $("#switch-storagepool-filesystem-destroy-recursive-` + filesystem.id + ` input").prop("checked")) { - $("#switch-storagepool-filesystem-destroy-recursive-` + filesystem.id + ` input").click(); - } - - $("#panel-storagepool-filesystem-destroy-child-filesystems-` + filesystem.id + `").addClass("hidden"); - $("#panel-storagepool-filesystem-destroy-child-filesystems-` + filesystem.id + ` .collapse").collapse("hide"); - $("#panel-storagepool-filesystem-destroy-child-snapshots-` + filesystem.id + `").addClass("hidden"); - $("#panel-storagepool-filesystem-destroy-child-snapshots-` + filesystem.id + ` .collapse").collapse("hide"); - - if ($(this).prop("checked") && $("#panelgroup-storagepool-filesystem-destroy-` + filesystem.id + `").attr("data-filesystem-child-filesystemswithclones") > 0) { - $("#panel-storagepool-filesystem-destroy-child-filesystemswithclones-` + filesystem.id + `").removeClass("hidden"); - } else { - $("#panel-storagepool-filesystem-destroy-child-filesystemswithclones-` + filesystem.id + `").addClass("hidden"); - $("#panel-storagepool-filesystem-destroy-child-filesystemswithclones-` + filesystem.id + ` .collapse").collapse("hide"); - } - if ($(this).prop("checked") && $("#panelgroup-storagepool-filesystem-destroy-` + filesystem.id + `").attr("data-filesystem-child-snapshotswithclones") > 0) { - $("#panel-storagepool-filesystem-destroy-child-snapshotswithclones-` + filesystem.id + `").removeClass("hidden"); - } else { - $("#panel-storagepool-filesystem-destroy-child-snapshotswithclones-` + filesystem.id + `").addClass("hidden"); - $("#panel-storagepool-filesystem-destroy-child-snapshotswithclones-` + filesystem.id + ` .collapse").collapse("hide"); - } - if ($(this).prop("checked") && ($("#panelgroup-storagepool-filesystem-destroy-` + filesystem.id + `").attr("data-filesystem-child-filesystemswithclones") > 0 || $("#panelgroup-storagepool-filesystem-destroy-` + filesystem.id + `").attr("data-filesystem-child-snapshotswithclones") > 0)) { - $("#panelgroup-storagepool-filesystem-destroy-` + filesystem.id + `").addClass("modal-ct-bodytext-1"); - } else { - $("#panelgroup-storagepool-filesystem-destroy-` + filesystem.id + `").removeClass("modal-ct-bodytext-1"); - } - }); - - $("#btn-storagepool-filesystem-destroy-apply-` + filesystem.id + `").on("click", function () { - $("#spinner-storagepool-filesystem-destroy-` + filesystem.id + `").removeClass("hidden"); - $(this).prop("disabled", true); - - let filesystem = { - force: $("#switch-storagepool-filesystem-destroy-force-` + filesystem.id + ` input").prop("checked"), - recursive: $("#switch-storagepool-filesystem-destroy-recursive-` + filesystem.id + ` input").prop("checked"), - recursiveall: $("#switch-storagepool-filesystem-destroy-recursiveall-` + filesystem.id + ` input").prop("checked") - }; - let samba = { - restart: $("#switch-storagepool-filesystem-destroy-samba-restart-` + filesystem.id + ` input").prop("checked") - }; - - FnFileSystemDestroy({ name: "` + pool.name + `", id: "` + pool.id + `", altroot: ` + pool.altroot + `, readonly: ` + pool.readonly + ` }, { name: "` + filesystem.name + `", id: "` + filesystem.id + `", force: filesystem.force, recursive: filesystem.recursive, recursiveall: filesystem.recursiveall, sharesmb: ` + filesystem.sharesmb + `, type: "` + filesystem.type + `" }, { restart: samba.restart }); - }); - \x3C/script> - `; - - modal.id.empty().append(modal.content); -} - -function FnModalFileSystemLock(pool = { name, id }, filesystem = { name, id, type }) { - let modal = { - window: "" - }; - - modal.window = ` - - - \x3Cscript nonce="1t55lZ7tzuKTreHVNwE66Ox32Mc="> - $("#btn-storagepool-filesystem-lock-` + filesystem.id + `").on("click", function () { - FnModalFileSystemLockContent({ name: "` + pool.name + `", id: "` + pool.id + `" }, { name: "` + filesystem.name + `", id: "` + filesystem.id + `", type: "` + filesystem.type + `" }, { id: $("#modal-storagepool-filesystem-lock-` + filesystem.id + `") }); - }); - \x3C/script> - `; - - $("#modals-storagepool-filesystem-" + pool.id).append(modal.window); -} - -function FnModalFileSystemLockContent(pool = { name, id }, filesystem = { name, id, type }, modal = { id }) { - modal.content = ` - - - \x3Cscript nonce="1t55lZ7tzuKTreHVNwE66Ox32Mc="> - $("#btn-storagepool-filesystem-lock-apply-` + filesystem.id + `").on("click", function () { - $("#spinner-storagepool-filesystem-lock-` + filesystem.id + `").removeClass("hidden"); - $(this).prop("disabled", true); - - FnFileSystemLock({ name: "` + pool.name + `", id: "` + pool.id + `" }, { name: "` + filesystem.name + `", id: "` + filesystem.id + `", type: "` + filesystem.type + `" }, { refresh: true }); - }); - \x3C/script> - `; - - modal.id.empty().append(modal.content); -} - -function FnModalFileSystemMount(pool = { name, id, altroot: false, readonly: false }, filesystem = { name, id, sharesmb: false, type }) { - let modal = { - window: "" - }; - - modal.window = ` - - - \x3Cscript nonce="1t55lZ7tzuKTreHVNwE66Ox32Mc="> - $("#btn-storagepool-filesystem-mount-` + filesystem.id + `").on("click", function () { - FnModalFileSystemMountContent({ name: "` + pool.name + `", id: "` + pool.id + `", altroot: ` + pool.altroot + `, readonly: ` + pool.readonly + ` }, { name: "` + filesystem.name + `", id: "` + filesystem.id + `", sharesmb: ` + filesystem.sharesmb + `, type: "` + filesystem.type + `" }, { id: $("#modal-storagepool-filesystem-mount-` + filesystem.id + `") }); - FnFileSystemsMountedGet({ name: "` + pool.name + `", id: "` + pool.id + `" }, { name: "` + filesystem.name + `", id: "` + filesystem.id + `" }, { alert: { id: $("#div-storagepool-filesystem-mount-warning-` + filesystem.id + `"), mount: true } }); - }); - \x3C/script> - `; - - $("#modals-storagepool-filesystem-" + pool.id).append(modal.window); -} - -function FnModalFileSystemMountContent(pool = { name, id, altroot: false, readonly: false }, filesystem = { name, id, sharesmb: false, type }, modal = { id }) { - modal.content = ` - - - \x3Cscript nonce="1t55lZ7tzuKTreHVNwE66Ox32Mc="> - $("#switch-storagepool-filesystem-mount-samba-enable-` + filesystem.id + ` input").on("click", function () { - if ($(this).prop("checked")) { - ` + (filesystem.name == pool.name ? `$("#alert-storagepool-filesystem-samba-warning-` + filesystem.id + `").removeClass("hidden");` : ``) + ` - } else { - ` + (filesystem.name == pool.name ? `$("#alert-storagepool-filesystem-samba-warning-` + filesystem.id + `").addClass("hidden");` : ``) + ` - } - }); - - $("#btn-storagepool-filesystem-mount-apply-` + filesystem.id + `").on("click", function () { - $("#spinner-storagepool-filesystem-mount-` + filesystem.id + `").removeClass("hidden"); - $(this).prop("disabled", true); - - let filesystem = { - overlay: $("#switch-storagepool-filesystem-mount-overlay-` + filesystem.id + ` input").prop("checked") - }; - let samba = { - enable: ` + ((pool.readonly || filesystem.sharesmb) ? false : `$("#switch-storagepool-filesystem-mount-samba-enable-` + filesystem.id + ` input").prop("checked")`) + ` - }; - - FnFileSystemMount({ name: "` + pool.name + `", id: "` + pool.id + `", altroot: ` + pool.altroot + `, readonly: ` + pool.readonly + ` }, { name: "` + filesystem.name + `", id: "` + filesystem.id + `", overlay: filesystem.overlay, type: "` + filesystem.type + `" }, { enable: samba.enable }, { refresh: true }); - }); - \x3C/script> - `; - - modal.id.empty().append(modal.content); -} - -function FnModalFileSystemPromote(pool = { name, id }, filesystem = { name, id, origin, type }) { - let modal = { - window: "" - }; - - modal.window = ` - - - \x3Cscript nonce="1t55lZ7tzuKTreHVNwE66Ox32Mc="> - $("#btn-storagepool-filesystem-promote-` + filesystem.id + `").on("click", function () { - FnModalFileSystemPromoteContent({ name: "` + pool.name + `", id: "` + pool.id + `" }, { name: "` + filesystem.name + `", id: "` + filesystem.id + `", origin: "` + filesystem.origin + `", type: "` + filesystem.type + `" }, { id: $("#modal-storagepool-filesystem-promote-` + filesystem.id + `") }); - }); - \x3C/script> - `; - - $("#modals-storagepool-filesystem-" + pool.id).append(modal.window); -} - -function FnModalFileSystemPromoteContent(pool = { name, id }, filesystem = { name, id, origin, type }, modal = { id }) { - modal.content = ` - - - \x3Cscript nonce="1t55lZ7tzuKTreHVNwE66Ox32Mc="> - $("#btn-storagepool-filesystem-promote-apply-` + filesystem.id + `").on("click", function () { - $("#spinner-storagepool-filesystem-promote-` + filesystem.id + `").removeClass("hidden"); - $(this).prop("disabled", true); - - FnFileSystemPromote({ name: "` + pool.name + `", id: "` + pool.id + `" }, { name: "` + filesystem.name + `", id: "` + filesystem.id + `", type: "` + filesystem.type + `" }); - }); - \x3C/script> - `; - - modal.id.empty().append(modal.content); -} - -function FnModalFileSystemRename(pool = { name, id, altroot: false }, filesystem = { name, id, clone: false, encryption: false, encryptionroot, origin, sharesmb: false, type }) { - let modal = { - window: "" - }; - - modal.window = ` - - - \x3Cscript nonce="1t55lZ7tzuKTreHVNwE66Ox32Mc="> - $("#btn-storagepool-filesystem-rename-` + filesystem.id + `").on("click", function () { - FnModalFileSystemRenameContent({ name: "` + pool.name + `", id: "` + pool.id + `", altroot: ` + pool.altroot + ` }, { name: "` + filesystem.name + `", id: "` + filesystem.id + `", clone: ` + filesystem.clone + `, encryption: ` + filesystem.encryption + `, origin: "` + filesystem.origin + `", sharesmb: ` + filesystem.sharesmb + `, type: "` + filesystem.type + `" }, { id: $("#modal-storagepool-filesystem-rename-` + filesystem.id + `") }); - FnFileSystemsNamesGet({ name: "` + pool.name + `", id: "` + pool.id + `" }, { existing: { name: "` + filesystem.name + `", clone: ` + filesystem.clone + `, encryption: ` + filesystem.encryption + `, encryptionroot: "` + filesystem.encryptionroot + `", origin: "` + filesystem.origin + `" }, override: false }, { dropdown: { id: $("#dropdown-storagepool-filesystem-rename-parentfilesystem-` + filesystem.id + `"), selected: "` + filesystem.name.replace(/\/[^\/]+$/, "") + `" } }); - - setTimeout(function() { - $("#input-storagepool-filesystem-rename-name-` + filesystem.id + `").focus(); - }, 600); - }); - \x3C/script> - `; - - $("#modals-storagepool-filesystem-" + pool.id).append(modal.window); -} - -function FnModalFileSystemRenameContent(pool = { name, id, altroot: false }, filesystem = { name, id, clone: false, encryption: false, origin, sharesmb: false, type }, modal = { id }) { - modal.content = ` - - - \x3Cscript nonce="1t55lZ7tzuKTreHVNwE66Ox32Mc="> - $("#btn-storagepool-filesystem-rename-apply-` + filesystem.id + `").on("click", function () { - $("#spinner-storagepool-filesystem-rename-` + filesystem.id + `").removeClass("hidden"); - $(this).prop("disabled", true); - - let filesystem = { - createnonexistparents: false, - force: false, - namenew: "", - parent: "" - }; - let samba = { - restart: false - }; - let validation = { - name: false - }; - - if ($("#btnspan-storagepool-filesystem-rename-parentfilesystem-` + filesystem.id + `").attr("data-field-value") + "/" + $("#input-storagepool-filesystem-rename-name-` + filesystem.id + `").val() == "` + filesystem.name + `") { - $("#helpblock-storagepool-filesystem-rename-name-` + filesystem.id + `").addClass("has-error").removeClass("hidden").text("Name or parent file system must be different."); - - validation.name = false; - } else if (new RegExp("^" + "` + filesystem.name + `/").test($("#btnspan-storagepool-filesystem-rename-parentfilesystem-` + filesystem.id + `").attr("data-field-value") + "/" + $("#input-storagepool-filesystem-rename-name-` + filesystem.id + `").val())) { - $("#helpblock-storagepool-filesystem-rename-name-` + filesystem.id + `").addClass("has-error").removeClass("hidden").text("Name can not be a descendant of current file system."); - - validation.name = false; - } else if ($("#input-storagepool-filesystem-rename-name-` + filesystem.id + `").val().length == 0) { - $("#helpblock-storagepool-filesystem-rename-name-` + filesystem.id + `").addClass("has-error").removeClass("hidden").text("Name can not be empty."); - - validation.name = false; - } else if (/^[a-zA-Z0-9-_.:/ ]*$/.test($("#input-storagepool-filesystem-rename-name-` + filesystem.id + `").val()) == false) { - $("#helpblock-storagepool-filesystem-rename-name-` + filesystem.id + `").addClass("has-error").removeClass("hidden").text("Name contains invalid characters."); - - validation.name = false; - } else if (/^[.]/.test($("#input-storagepool-filesystem-rename-name-` + filesystem.id + `").val())) { - $("#helpblock-storagepool-filesystem-rename-name-` + filesystem.id + `").addClass("has-error").removeClass("hidden").text("Name can not begin with a period (.)."); - - validation.name = false; - } else if (/^[_]/.test($("#input-storagepool-filesystem-rename-name-` + filesystem.id + `").val())) { - $("#helpblock-storagepool-filesystem-rename-name-` + filesystem.id + `").addClass("has-error").removeClass("hidden").text("Name can not begin with an underscore (_)."); - - validation.name = false; - } else if (/^[-]/.test($("#input-storagepool-filesystem-rename-name-` + filesystem.id + `").val())) { - $("#helpblock-storagepool-filesystem-rename-name-` + filesystem.id + `").addClass("has-error").removeClass("hidden").text("Name can not begin with a hypen (-)."); - - validation.name = false; - } else if (/^[:]/.test($("#input-storagepool-filesystem-rename-name-` + filesystem.id + `").val())) { - $("#helpblock-storagepool-filesystem-rename-name-` + filesystem.id + `").addClass("has-error").removeClass("hidden").text("Name can not begin with an colon (:)."); - - validation.name = false; - } else if (/^[/]/.test($("#input-storagepool-filesystem-rename-name-` + filesystem.id + `").val())) { - $("#helpblock-storagepool-filesystem-rename-name-` + filesystem.id + `").addClass("has-error").removeClass("hidden").text("Name can not begin with a forward slash (/)."); - - validation.name = false; - } else if (/[/]$/.test($("#input-storagepool-filesystem-rename-name-` + filesystem.id + `").val())) { - $("#helpblock-storagepool-filesystem-rename-name-` + filesystem.id + `").addClass("has-error").removeClass("hidden").text("Name can not end with a forward slash (/)."); - - validation.name = false; - } else if (/^ |\\/ /.test($("#input-storagepool-filesystem-rename-name-` + filesystem.id + `").val())) { - $("#helpblock-storagepool-filesystem-rename-name-` + filesystem.id + `").addClass("has-error").removeClass("hidden").text("Name can not begin with whitespace ( )."); - - validation.name = false; - } else if (/ $| \\//.test($("#input-storagepool-filesystem-rename-name-` + filesystem.id + `").val())) { - $("#helpblock-storagepool-filesystem-rename-name-` + filesystem.id + `").addClass("has-error").removeClass("hidden").text("Name can not end with whitespace ( )."); - - validation.name = false; - } else { - $("#validationwrapper-storagepool-filesystem-rename-name-` + filesystem.id + `").removeClass("has-error"); - $("#helpblock-storagepool-filesystem-rename-name-` + filesystem.id + `").addClass("hidden").text(""); - - validation.name = true; - } - - if (!validation.name) { - $("#validationwrapper-storagepool-filesystem-rename-name-` + filesystem.id + `").addClass("has-error"); - $("#input-storagepool-filesystem-rename-name-` + filesystem.id + `").focus(); - - $("#spinner-storagepool-filesystem-rename-` + filesystem.id + `").addClass("hidden"); - $(this).prop("disabled", false); - } - - if (validation.name) { - filesystem.createnonexistparents = $("#switch-storagepool-filesystem-rename-createnonexistparents-` + filesystem.id + ` input").prop("checked"); - filesystem.force = $("#switch-storagepool-filesystem-rename-force-` + filesystem.id + ` input").prop("checked"); - filesystem.namenew = $("#btnspan-storagepool-filesystem-rename-parentfilesystem-` + filesystem.id + `").attr("data-field-value") + "/" + $("#input-storagepool-filesystem-rename-name-` + filesystem.id + `").val(); - filesystem.parent = $("#btnspan-storagepool-filesystem-rename-parentfilesystem-` + filesystem.id + `").attr("data-field-value"); - - samba.restart = $("#switch-storagepool-filesystem-rename-samba-restart-` + filesystem.id + ` input").prop("checked") - - FnFileSystemRename({ name: "` + pool.name + `", id: "` + pool.id + `", altroot: ` + pool.altroot + ` }, { name: "` + filesystem.name + `", id: "` + filesystem.id + `", createnonexistparents: filesystem.createnonexistparents, force: filesystem.force, namenew: filesystem.namenew, parent: filesystem.parent, sharesmb: ` + filesystem.sharesmb + `, type: "` + filesystem.type + `" }, { restart: samba.restart }); - } - }); - - $("#dropdown-storagepool-filesystem-rename-parentfilesystem-` + filesystem.id + `").on("click", "li a", function () { - $("#btnspan-storagepool-filesystem-rename-parentfilesystem-` + filesystem.id + `").text($(this).text()).attr("data-field-value", $(this).parent().attr("value")); - $(this).parent().siblings().removeClass("active"); - $(this).parent().addClass("active"); - }); - \x3C/script> - `; - - modal.id.empty().append(modal.content); -} - -function FnModalFileSystemSambaConfigure(pool = { name, id, altroot: false, readonly: false }, filesystem = { name, id, mountpoint }) { - let modal = { - window: "" - }; - - modal.window = ` - - - \x3Cscript nonce="1t55lZ7tzuKTreHVNwE66Ox32Mc="> - $("#btn-storagepool-filesystem-samba-configure-` + filesystem.id + `").on("click", function () { - FnModalFileSystemSambaConfigureContent({ name: "` + pool.name + `", id: "` + pool.id + `", altroot: ` + pool.altroot + `, readonly: ` + pool.readonly + ` }, { name: "` + filesystem.name + `", id: "` + filesystem.id + `", mountpoint: "` + filesystem.mountpoint + `" }, { id: $("#modal-storagepool-filesystem-samba-configure-` + filesystem.id + `") }); - FnSambaZfsShareConfigurationGet({ name: "` + pool.name + `", id: "` + pool.id + `", altroot: ` + pool.altroot + `, readonly: ` + pool.readonly + ` }, { name: "` + filesystem.name + `", id: "` + filesystem.id + `" }, { name: "storagepool-filesystem-samba-configure", id: "` + filesystem.id + `" }); - - setTimeout(function() { - $("#input-storagepool-filesystem-samba-configure-name-` + filesystem.id + `").focus(); - }, 600); - }); - \x3C/script> - `; - - $("#modals-storagepool-filesystem-" + pool.id).append(modal.window); -} - -function FnModalFileSystemSambaConfigureContent(pool = { name, id, altroot: false, readonly: false }, filesystem = { name, id, mountpoint }, modal = { id }) { - modal.content = ` - - - \x3Cscript nonce="1t55lZ7tzuKTreHVNwE66Ox32Mc="> - $("#switch-storagepool-filesystem-samba-configure-additional-` + filesystem.id + ` input").on("click", function () { - $("#validationwrapper-storagepool-filesystem-samba-configure-additional-` + filesystem.id + `").removeClass("has-error"); - $("#helpblock-storagepool-filesystem-samba-configure-additional-` + filesystem.id + `").removeClass("has-error").addClass("hidden").text(""); - - if ($("#switch-storagepool-filesystem-samba-configure-additional-` + filesystem.id + ` input").prop("checked")) { - $("#validationwrapper-storagepool-filesystem-samba-configure-additional-` + filesystem.id + `").removeClass("hidden"); - } else { - $("#validationwrapper-storagepool-filesystem-samba-configure-additional-` + filesystem.id + `").addClass("hidden"); - } - }); - - $("#btn-storagepool-filesystem-samba-configure-apply-` + filesystem.id + `").on("click", function () { - $("#spinner-storagepool-filesystem-samba-configure-` + filesystem.id + `").removeClass("hidden"); - $(this).prop("disabled", true); - - let samba = { - share: { - additional: ($("#switch-storagepool-filesystem-samba-configure-additional-` + filesystem.id + ` input").prop("checked") ? $("#textarea-storagepool-filesystem-samba-configure-additional-` + filesystem.id + `").val().split("\\n").filter(v => v) : []), - administrative: false, - browseable: true, - comment: "", - guestok: false, - name: "", - nameexisting: "", - readonly: false - } - }; - let validation = { - comment: false, - name: false, - additional: false - }; - - if ($("#input-storagepool-filesystem-samba-configure-name-` + filesystem.id + `").val().length == 0) { - $("#helpblock-storagepool-filesystem-samba-configure-name-` + filesystem.id + `").addClass("has-error").removeClass("hidden").text("Share name can not be empty."); - - validation.name = false; - } else if (/^[a-zA-Z0-9-_.@%+!#$^,(){}~ ]*$/.test($("#input-storagepool-filesystem-samba-configure-name-` + filesystem.id + `").val()) == false) { - $("#helpblock-storagepool-filesystem-samba-configure-name-` + filesystem.id + `").addClass("has-error").removeClass("hidden").text("Share name contains invalid characters."); - - validation.name = false; - } else if (/^[ ]/.test($("#input-storagepool-filesystem-samba-configure-name-` + filesystem.id + `").val())) { - $("#helpblock-storagepool-filesystem-samba-configure-name-` + filesystem.id + `").addClass("has-error").removeClass("hidden").text("Share name can not begin with whitespace ( )."); - - validation.name = false; - } else if (/[ ]$/.test($("#input-storagepool-filesystem-samba-configure-name-` + filesystem.id + `").val())) { - $("#helpblock-storagepool-filesystem-samba-configure-name-` + filesystem.id + `").addClass("has-error").removeClass("hidden").text("Share name can not end with whitespace ( )."); - - validation.name = false; - } else { - $("#validationwrapper-storagepool-filesystem-samba-configure-name-` + filesystem.id + `").removeClass("has-error"); - $("#helpblock-storagepool-filesystem-samba-configure-name-` + filesystem.id + `").addClass("hidden").text(""); - - validation.name = true; - } - - if (/^[ -~]*$/.test($("#input-storagepool-filesystem-samba-configure-comment-` + filesystem.id + `").val()) == false) { - $("#helpblock-storagepool-filesystem-samba-configure-comment-` + filesystem.id + `").addClass("has-error").removeClass("hidden").text("Comment contains invalid characters."); - - validation.comment = false; - } else if (/^[.]/.test($("#input-storagepool-filesystem-samba-configure-comment-` + filesystem.id + `").val())) { - $("#helpblock-storagepool-filesystem-samba-configure-comment-` + filesystem.id + `").addClass("has-error").removeClass("hidden").text("Comment can not begin with a period (.)."); - - validation.comment = false; - } else if (/^[ ]/.test($("#input-storagepool-filesystem-samba-configure-comment-` + filesystem.id + `").val())) { - $("#helpblock-storagepool-filesystem-samba-configure-comment-` + filesystem.id + `").addClass("has-error").removeClass("hidden").text("Comment can not begin with whitespace ( )."); - - validation.comment = false; - } else if (/[ ]$/.test($("#input-storagepool-filesystem-samba-configure-comment-` + filesystem.id + `").val())) { - $("#helpblock-storagepool-filesystem-samba-configure-comment-` + filesystem.id + `").addClass("has-error").removeClass("hidden").text("Comment can not end with whitespace ( )."); - - validation.comment = false; - } else { - $("#validationwrapper-storagepool-filesystem-samba-configure-comment-` + filesystem.id + `").removeClass("has-error"); - $("#helpblock-storagepool-filesystem-samba-configure-comment-` + filesystem.id + `").addClass("hidden").text(""); - - validation.comment = true; - } - - if (samba.share.additional.length > 0) { - samba.share.additional.forEach((_value, _index) => { - if (/[\\[\\]]/g.test(_value)) { //Do not allow section names - $("#helpblock-storagepool-filesystem-samba-configure-additional-` + filesystem.id + `").addClass("has-error").removeClass("hidden").text("Additional must not contain brackets. Line: " + (_index + 1)); - - validation.additional = false; - return; - } else if (/^[#]/.test(_value) == false && /[=]/.test(_value) && /(path|comment|browseable|read only|guest ok).*=/gi.test(_value)) { - $("#helpblock-storagepool-filesystem-samba-configure-additional-` + filesystem.id + `").addClass("has-error").removeClass("hidden").text("Additional must not contain duplicate properties. Line: " + (_index + 1)); - - validation.additional = false; - return; - } else if (/[#=]/.test(_value) == false) { - $("#helpblock-storagepool-filesystem-samba-configure-additional-` + filesystem.id + `").addClass("has-error").removeClass("hidden").text("Additional must contain comments or properties only. Line: " + (_index + 1)); - - validation.additional = false; - return; - } else if (_index == (samba.share.additional.length -1)) { - $("#validationwrapper-storagepool-filesystem-samba-configure-additional-` + filesystem.id + `").removeClass("has-error"); - $("#helpblock-storagepool-filesystem-samba-configure-additional-` + filesystem.id + `").removeClass("has-error").addClass("hidden").text(""); - - validation.additional = true; - } - }); - } else { - validation.additional = true; - } - - if (!validation.name || !validation.comment || !validation.additional) { - if (!validation.name) { - $("#validationwrapper-storagepool-filesystem-samba-configure-name-` + filesystem.id + `").addClass("has-error"); - $("#input-storagepool-filesystem-samba-configure-name-` + filesystem.id + `").focus(); - } - if (!validation.comment) { - $("#validationwrapper-storagepool-filesystem-samba-configure-comment-` + filesystem.id + `").addClass("has-error"); - $("#input-storagepool-filesystem-samba-configure-comment-` + filesystem.id + `").focus(); - } - if (!validation.additional) { - $("#validationwrapper-storagepool-filesystem-samba-configure-additional-` + filesystem.id + `").addClass("has-error"); - $("#textarea-storagepool-filesystem-samba-configure-additional-` + filesystem.id + `").focus(); - } - - $("#spinner-storagepool-filesystem-samba-configure-` + filesystem.id + `").addClass("hidden"); - $(this).prop("disabled", false); - } - - if (validation.name && validation.comment && validation.additional) { - samba.restart = $("#switch-storagepool-filesystem-samba-configure-restart-` + filesystem.id + ` input").prop("checked"); - samba.share.administrative = $("#switch-storagepool-filesystem-samba-configure-administrative-` + filesystem.id + ` input").prop("checked"); - samba.share.browseable = $("#switch-storagepool-filesystem-samba-configure-browseable-` + filesystem.id + ` input").prop("checked"); - samba.share.comment = $("#input-storagepool-filesystem-samba-configure-comment-` + filesystem.id + `").val(); - samba.share.guestok = $("#switch-storagepool-filesystem-samba-configure-guestok-` + filesystem.id + ` input").prop("checked"); - samba.share.name = $("#input-storagepool-filesystem-samba-configure-name-` + filesystem.id + `").val(); - samba.share.nameexisting = $("#input-storagepool-filesystem-samba-configure-name-` + filesystem.id + `").attr("data-field-value"); - samba.share.readonly = $("#switch-storagepool-filesystem-samba-configure-readonly-` + filesystem.id + ` input").prop("checked"); - - FnSambaZfsShareConfigure({ name: "` + pool.name + `", id: "` + pool.id + `" }, { name: "` + filesystem.name + `", id: "` + filesystem.id + `", mountpoint: "` + filesystem.mountpoint + `" }, { share: { additional: samba.share.additional, administrative: samba.share.administrative, browseable: samba.share.browseable, guestok: samba.share.guestok, name: samba.share.name, comment: samba.share.comment, nameexisting: samba.share.nameexisting, readonly: samba.share.readonly, temporary: ` + (pool.altroot || pool.readonly ? true : false) + ` }, restart: samba.restart }); - } - }); - \x3C/script> - `; - - modal.id.empty().append(modal.content); -} - -function FnModalFileSystemSambaDisable(pool = { name, id, altroot: false, readonly: false }, filesystem = { name, id, type }) { - let modal = { - window: "" - }; - - modal.window = ` - - - \x3Cscript nonce="1t55lZ7tzuKTreHVNwE66Ox32Mc="> - $("#btn-storagepool-filesystem-samba-disable-` + filesystem.id + `").on("click", function () { - FnModalFileSystemSambaDisableContent({ name: "` + pool.name + `", id: "` + pool.id + `", altroot: ` + pool.altroot + `, readonly: ` + pool.readonly + ` }, { name: "` + filesystem.name + `", id: "` + filesystem.id + `", type: "` + filesystem.type + `" }, { id: $("#modal-storagepool-filesystem-samba-disable-` + filesystem.id + `") }); - }); - \x3C/script> - `; - - $("#modals-storagepool-filesystem-" + pool.id).append(modal.window); -} - -function FnModalFileSystemSambaDisableContent(pool = { name, id, altroot: false, readonly: false }, filesystem = { name, id, type }, modal = { id }) { - modal.content = ` - - - \x3Cscript nonce="1t55lZ7tzuKTreHVNwE66Ox32Mc="> - $("#btn-storagepool-filesystem-samba-disable-apply-` + filesystem.id + `").on("click", function () { - $("#spinner-storagepool-filesystem-samba-disable-` + filesystem.id + `").removeClass("hidden"); - $(this).prop("disabled", true); - - let samba = { - restart: $("#switch-storagepool-filesystem-samba-disable-restart-` + filesystem.id + ` input").prop("checked") - }; - - FnSambaShareDisable({ name: "` + pool.name + `", id: "` + pool.id + `", altroot: ` + pool.altroot + `, readonly: ` + pool.readonly + ` }, { name: "` + filesystem.name + `", id: "` + filesystem.id + `" }, { restart: samba.restart }, { modal: true, silent: false }); - }); - \x3C/script> - `; - - modal.id.empty().append(modal.content); -} - -function FnModalFileSystemSambaEnable(pool = { name, id, altroot: false, readonly: false }, filesystem = { name, id, mounted: false, mountpoint }) { - let modal = { - window: "" - }; - - modal.window = ` - - - \x3Cscript nonce="1t55lZ7tzuKTreHVNwE66Ox32Mc="> - $("#btn-storagepool-filesystem-samba-enable-` + filesystem.id + `").on("click", function () { - FnModalFileSystemSambaEnableContent({ name: "` + pool.name + `", id: "` + pool.id + `", altroot: ` + pool.altroot + `, readonly: ` + pool.readonly + ` }, { name: "` + filesystem.name + `", id: "` + filesystem.id + `", mounted: ` + filesystem.mounted + `, mountpoint: "` + filesystem.mountpoint + `" }, { id: $("#modal-storagepool-filesystem-samba-enable-` + filesystem.id + `") }); - - setTimeout(function() { - $("#input-storagepool-filesystem-samba-enable-name-` + filesystem.id + `").focus(); - }, 600); - }); - \x3C/script> - `; - - $("#modals-storagepool-filesystem-" + pool.id).append(modal.window); -} - -function FnModalFileSystemSambaEnableContent(pool = { name, id, altroot: false, readonly: false }, filesystem = { name, id, mounted: false, mountpoint }, modal = { id }) { - modal.content = ` - - - \x3Cscript nonce="1t55lZ7tzuKTreHVNwE66Ox32Mc="> - $("#switch-storagepool-filesystem-samba-enable-additional-` + filesystem.id + ` input").on("click", function () { - $("#validationwrapper-storagepool-filesystem-samba-enable-additional-` + filesystem.id + `").removeClass("has-error"); - $("#helpblock-storagepool-filesystem-samba-enable-additional-` + filesystem.id + `").removeClass("has-error").addClass("hidden").text(""); - - if ($(this).prop("checked")) { - $("#validationwrapper-storagepool-filesystem-samba-enable-additional-` + filesystem.id + `").removeClass("hidden"); - } else { - $("#validationwrapper-storagepool-filesystem-samba-enable-additional-` + filesystem.id + `").addClass("hidden"); - } - }); - - $("#btn-storagepool-filesystem-samba-enable-apply-` + filesystem.id + `").on("click", function () { - $("#spinner-storagepool-filesystem-samba-enable-` + filesystem.id + `").removeClass("hidden"); - $(this).prop("disabled", true); - - let samba = { - share: { - additional: ($("#switch-storagepool-filesystem-samba-enable-additional-` + filesystem.id + ` input").prop("checked") ? $("#textarea-storagepool-filesystem-samba-enable-additional-` + filesystem.id + `").val().split("\\n").filter(v => v) : []), - administrative: false, - browseable: true, - comment: "", - guestok: false, - name: "", - readonly: false - } - }; - let validation = { - comment: false, - name: false, - additional: false - }; - - if ($("#input-storagepool-filesystem-samba-enable-name-` + filesystem.id + `").val().length == 0) { - $("#helpblock-storagepool-filesystem-samba-enable-name-` + filesystem.id + `").addClass("has-error").removeClass("hidden").text("Share name can not be empty."); - - validation.name = false; - } else if (/^[a-zA-Z0-9-_.@%+!#$^,(){}~ ]*$/.test($("#input-storagepool-filesystem-samba-enable-name-` + filesystem.id + `").val()) == false) { - $("#helpblock-storagepool-filesystem-samba-enable-name-` + filesystem.id + `").addClass("has-error").removeClass("hidden").text("Share name contains invalid characters."); - - validation.name = false; - } else if (/^[ ]/.test($("#input-storagepool-filesystem-samba-enable-name-` + filesystem.id + `").val())) { - $("#helpblock-storagepool-filesystem-samba-enable-name-` + filesystem.id + `").addClass("has-error").removeClass("hidden").text("Share name can not begin with whitespace ( )."); - - validation.name = false; - } else if (/[ ]$/.test($("#input-storagepool-filesystem-samba-enable-name-` + filesystem.id + `").val())) { - $("#helpblock-storagepool-filesystem-samba-enable-name-` + filesystem.id + `").addClass("has-error").removeClass("hidden").text("Share name can not end with whitespace ( )."); - - validation.name = false; - } else { - $("#validationwrapper-storagepool-filesystem-samba-enable-name-` + filesystem.id + `").removeClass("has-error"); - $("#helpblock-storagepool-filesystem-samba-enable-name-` + filesystem.id + `").addClass("hidden").text(""); - - validation.name = true; - } - - if (/^[ -~]*$/.test($("#input-storagepool-filesystem-samba-enable-comment-` + filesystem.id + `").val()) == false) { - $("#helpblock-storagepool-filesystem-samba-enable-comment-` + filesystem.id + `").addClass("has-error").removeClass("hidden").text("Comment contains invalid characters."); - - validation.comment = false; - } else if (/^[ ]/.test($("#input-storagepool-filesystem-samba-enable-comment-` + filesystem.id + `").val())) { - $("#helpblock-storagepool-filesystem-samba-enable-comment-` + filesystem.id + `").addClass("has-error").removeClass("hidden").text("Comment can not begin with whitespace ( )."); - - validation.comment = false; - } else if (/[ ]$/.test($("#input-storagepool-filesystem-samba-enable-comment-` + filesystem.id + `").val())) { - $("#helpblock-storagepool-filesystem-samba-enable-comment-` + filesystem.id + `").addClass("has-error").removeClass("hidden").text("Comment can not end with whitespace ( )."); - - validation.comment = false; - } else { - $("#validationwrapper-storagepool-filesystem-samba-enable-comment-` + filesystem.id + `").removeClass("has-error"); - $("#helpblock-storagepool-filesystem-samba-enable-comment-` + filesystem.id + `").addClass("hidden").text(""); - - validation.comment = true; - } - - if (samba.share.additional.length > 0) { - samba.share.additional.forEach((_value, _index) => { - if (/[\\[\\]]/g.test(_value)) { //Do not allow section names - $("#helpblock-storagepool-filesystem-samba-enable-additional-` + filesystem.id + `").addClass("has-error").removeClass("hidden").text("Additional must not contain brackets. Line: " + (_index + 1)); - - validation.additional = false; - return; - } else if (/^[#]/.test(_value) == false && /[=]/.test(_value) && /(path|comment|browseable|read only|guest ok).*=/gi.test(_value)) { - $("#helpblock-storagepool-filesystem-samba-enable-additional-` + filesystem.id + `").addClass("has-error").removeClass("hidden").text("Additional must not contain duplicate properties. Line: " + (_index + 1)); - - validation.additional = false; - return; - } else if (/[#=]/.test(_value) == false) { - $("#helpblock-storagepool-filesystem-samba-enable-additional-` + filesystem.id + `").addClass("has-error").removeClass("hidden").text("Additional must contain comments or properties only. Line: " + (_index + 1)); - - validation.additional = false; - return; - } else if (_index == (samba.share.additional.length -1)) { - $("#validationwrapper-storagepool-filesystem-samba-enable-additional-` + filesystem.id + `").removeClass("has-error"); - $("#helpblock-storagepool-filesystem-samba-enable-additional-` + filesystem.id + `").removeClass("has-error").addClass("hidden").text(""); - - validation.additional = true; - } - }); - } else { - validation.additional = true; - } - - if (!validation.name || !validation.comment || !validation.additional) { - if (!validation.name) { - $("#validationwrapper-storagepool-filesystem-samba-enable-name-` + filesystem.id + `").addClass("has-error"); - $("#input-storagepool-filesystem-samba-enable-name-` + filesystem.id + `").focus(); - } - if (!validation.comment) { - $("#validationwrapper-storagepool-filesystem-samba-enable-comment-` + filesystem.id + `").addClass("has-error"); - $("#input-storagepool-filesystem-samba-enable-comment-` + filesystem.id + `").focus(); - } - if (!validation.additional) { - $("#validationwrapper-storagepool-filesystem-samba-enable-additional-` + filesystem.id + `").addClass("has-error"); - $("#textarea-storagepool-filesystem-samba-enable-additional-` + filesystem.id + `").focus(); - } - - $("#spinner-storagepool-filesystem-samba-enable-` + filesystem.id + `").addClass("hidden"); - $(this).prop("disabled", false); - } - - if (validation.name && validation.comment && validation.additional) { - samba.share.administrative = $("#switch-storagepool-filesystem-samba-enable-administrative-` + filesystem.id + ` input").prop("checked"); - samba.share.browseable = $("#switch-storagepool-filesystem-samba-enable-browseable-` + filesystem.id + ` input").prop("checked"); - samba.share.comment = $("#input-storagepool-filesystem-samba-enable-comment-` + filesystem.id + `").val(); - samba.share.guestok = $("#switch-storagepool-filesystem-samba-enable-guestok-` + filesystem.id + ` input").prop("checked"); - samba.share.name = $("#input-storagepool-filesystem-samba-enable-name-` + filesystem.id + `").val(); - samba.share.readonly = $("#switch-storagepool-filesystem-samba-enable-readonly-` + filesystem.id + ` input").prop("checked"); - - FnSambaShareEnable({ name: "` + pool.name + `", id: "` + pool.id + `", readonly: ` + pool.readonly + ` }, { name: "` + filesystem.name + `", id: "` + filesystem.id + `", mounted: ` + filesystem.mounted + `, mountpoint: "` + filesystem.mountpoint + `" }, { share: { additional: samba.share.additional, administrative: samba.share.administrative, browseable: samba.share.browseable, guestok: samba.share.guestok, name: samba.share.name, comment: samba.share.comment, readonly: samba.share.readonly, temporary: ` + (pool.altroot || pool.readonly ? true : false) + ` } }, { silent: false }); - } - }); - \x3C/script> - `; - - modal.id.empty().append(modal.content); -} - -function FnModalFileSystemSnapshotCreate(pool = { name, id }, filesystem = { name, id }) { - let modal = { - window: "" - }; - - modal.window = ` - - - \x3Cscript nonce="1t55lZ7tzuKTreHVNwE66Ox32Mc="> - $("#btn-storagepool-filesystem-snapshot-create-` + filesystem.id + `").on("click", function () { - FnModalFileSystemSnapshotCreateContent({ name: "` + pool.name + `", id: "` + pool.id + `" }, { name: "` + filesystem.name + `", id: "` + filesystem.id + `" }, { id: $("#modal-storagepool-filesystem-snapshot-create-` + filesystem.id + `") }); - }); - \x3C/script> - `; - - $("#modals-storagepool-filesystem-" + pool.id).append(modal.window); -} - -function FnModalFileSystemSnapshotCreateContent(pool = { name, id }, filesystem = { name, id }, modal = { id }) { - modal.content = ` - - - \x3Cscript nonce="1t55lZ7tzuKTreHVNwE66Ox32Mc="> - $("#switch-storagepool-filesystem-snapshot-create-customname-` + filesystem.id + ` input").on("click", function () { - $("#validationwrapper-storagepool-filesystem-snapshot-create-name-` + filesystem.id + `").removeClass("has-error"); - $("#helpblock-storagepool-filesystem-snapshot-create-name-` + filesystem.id + `").removeClass("has-error").addClass("hidden").text(""); - - if ($(this).prop("checked")) { - $("#input-storagepool-filesystem-snapshot-create-name-` + filesystem.id + `").val("").prop("readonly", false).focus(); - } else { - $("#input-storagepool-filesystem-snapshot-create-name-` + filesystem.id + `").val("YYYY.MM.DD-HH.MM.SS").prop("readonly", true);; - } - }); - - $("#btn-storagepool-filesystem-snapshot-create-apply-` + filesystem.id + `").on("click", function () { - $("#spinner-storagepool-filesystem-snapshot-create-` + filesystem.id + `").removeClass("hidden"); - $(this).prop("disabled", true); - - let snapshot = { - name: "", - id: "", - recursive: false - }; - let validation = { - name: false - }; - - if ($("#input-storagepool-filesystem-snapshot-create-name-` + filesystem.id + `").val().length == 0) { - $("#helpblock-storagepool-filesystem-snapshot-create-name-` + filesystem.id + `").addClass("has-error").removeClass("hidden").text("Name can not be empty."); - - validation.name = false; - } else if (/^[a-zA-Z0-9-_.: ]*$/.test($("#input-storagepool-filesystem-snapshot-create-name-` + filesystem.id + `").val()) == false) { - $("#helpblock-storagepool-filesystem-snapshot-create-name-` + filesystem.id + `").addClass("has-error").removeClass("hidden").text("Name contains invalid characters."); - - validation.name = false; - } else if (/^[.]/.test($("#input-storagepool-filesystem-snapshot-create-name-` + filesystem.id + `").val())) { - $("#helpblock-storagepool-filesystem-snapshot-create-name-` + filesystem.id + `").addClass("has-error").removeClass("hidden").text("Name can not begin with a period (.)."); - - validation.name = false; - } else if (/^[_]/.test($("#input-storagepool-filesystem-snapshot-create-name-` + filesystem.id + `").val())) { - $("#helpblock-storagepool-filesystem-snapshot-create-name-` + filesystem.id + `").addClass("has-error").removeClass("hidden").text("Name can not begin with an underscore (_)."); - - validation.name = false; - } else if (/^[-]/.test($("#input-storagepool-filesystem-snapshot-create-name-` + filesystem.id + `").val())) { - $("#helpblock-storagepool-filesystem-snapshot-create-name-` + filesystem.id + `").addClass("has-error").removeClass("hidden").text("Name can not begin with a hypen (-)."); - - validation.name = false; - } else if (/^[:]/.test($("#input-storagepool-filesystem-snapshot-create-name-` + filesystem.id + `").val())) { - $("#helpblock-storagepool-filesystem-snapshot-create-name-` + filesystem.id + `").addClass("has-error").removeClass("hidden").text("Name can not begin with an colon (:)."); - - validation.name = false; - } else if (/^[ ]/.test($("#input-storagepool-filesystem-snapshot-create-name-` + filesystem.id + `").val())) { - $("#helpblock-storagepool-filesystem-snapshot-create-name-` + filesystem.id + `").addClass("has-error").removeClass("hidden").text("Name can not begin with whitespace ( )."); - - validation.name = false; - } else if (/[ ]$/.test($("#input-storagepool-filesystem-snapshot-create-name-` + filesystem.id + `").val())) { - $("#helpblock-storagepool-filesystem-snapshot-create-name-` + filesystem.id + `").addClass("has-error").removeClass("hidden").text("Name can not end with whitespace ( )."); - - validation.name = false; - } else { - $("#validationwrapper-storagepool-filesystem-snapshot-create-name-` + filesystem.id + `").removeClass("has-error"); - $("#helpblock-storagepool-filesystem-snapshot-create-name-` + filesystem.id + `").addClass("hidden").text(""); - - validation.name = true; - } - - if (!validation.name) { - $("#validationwrapper-storagepool-filesystem-snapshot-create-name-` + filesystem.id + `").addClass("has-error"); - $("#input-storagepool-filesystem-snapshot-create-name-` + filesystem.id + `").focus(); - - $("#spinner-storagepool-filesystem-snapshot-create-` + filesystem.id + `").addClass("hidden"); - $(this).prop("disabled", false); - } - - if (validation.name) { - snapshot.name = "` + filesystem.name + `" + "@" + $("#input-storagepool-filesystem-snapshot-create-name-` + filesystem.id + `").val(); - snapshot.id = FnGenerateId({ at: true, colon: true, forwardslash: true, period: true, underscore: true, whitespace: true }, { name: snapshot.name, attribute: true }); - snapshot.recursive = $("#switch-storagepool-filesystem-snapshot-create-recursive-` + filesystem.id + ` input").prop("checked"); - - if ($("#switch-storagepool-filesystem-snapshot-create-customname-` + filesystem.id + ` input").prop("checked")) { - FnSnapshotCreate({ name: "` + pool.name + `", id: "` + pool.id + `" }, { name: snapshot.name, id: snapshot.id, recursive: snapshot.recursive }, { name: "storagepool-filesystem-snapshot-create", id: "` + filesystem.id + `"}); - } else { - FnSnapshotCreateDateGet({ name: "` + pool.name + `", id: "` + pool.id + `" }, { name: snapshot.name, id: snapshot.id, recursive: snapshot.recursive }, { name: "storagepool-filesystem-snapshot-create", id: "` + filesystem.id + `"}); - } - } - }); - \x3C/script> - `; - - modal.id.empty().append(modal.content); -} - -function FnModalFileSystemUnlock(pool = { name, id, altroot: false, readonly: false }, filesystem = { name, id, sharesmb: false, type }) { - let modal = { - window: "" - }; - - modal.window = ` - - - \x3Cscript nonce="1t55lZ7tzuKTreHVNwE66Ox32Mc="> - $("#btn-storagepool-filesystem-unlock-` + filesystem.id + `").on("click", function () { - FnModalFileSystemUnlockContent({ name: "` + pool.name + `", id: "` + pool.id + `", altroot: ` + pool.altroot + `, readonly: ` + pool.readonly + ` }, { name: "` + filesystem.name + `", id: "` + filesystem.id + `", sharesmb: ` + filesystem.sharesmb + `, type: "` + filesystem.type + `" }, { id: $("#modal-storagepool-filesystem-unlock-` + filesystem.id + `") }); - - setTimeout(function() { - $("#input-storagepool-filesystem-unlock-passphrase-` + filesystem.id + `").focus(); - }, 600); - }); - \x3C/script> - `; - - $("#modals-storagepool-filesystem-" + pool.id).append(modal.window); -} - -function FnModalFileSystemUnlockContent(pool = { name, id, altroot: false, readonly: false }, filesystem = { name, id, sharesmb: false, type }, modal = { id }) { - modal.content = ` - - - \x3Cscript nonce="1t55lZ7tzuKTreHVNwE66Ox32Mc="> - $("#switch-storagepool-filesystem-unlock-mount-` + filesystem.id + ` input").on("click", function () { - if ($(this).prop("checked")) { - $("#switch-storagepool-filesystem-unlock-overlay-` + filesystem.id + `").parent().removeClass("hidden"); - } else { - $("#switch-storagepool-filesystem-unlock-overlay-` + filesystem.id + `").parent().addClass("hidden"); - } - }); - - $("#btn-storagepool-filesystem-unlock-apply-` + filesystem.id + `").on("click", function () { - $("#spinner-storagepool-filesystem-unlock-` + filesystem.id + `").removeClass("hidden"); - $(this).prop("disabled", true); - - let filesystem = { - mount: true, - passphrase: "" - }; - let samba = { - enable: false - }; - let validation = { - passphrase: false - }; - - if ($("#input-storagepool-filesystem-unlock-passphrase-` + filesystem.id + `").val().length == 0) { - $("#helpblock-storagepool-filesystem-unlock-passphrase-` + filesystem.id + `").addClass("has-error").removeClass("hidden").text("Passphrase can not be empty."); - - validation.passphrase = false; - } else if ($("#input-storagepool-filesystem-unlock-passphrase-` + filesystem.id + `").val().length < 8) { - $("#helpblock-storagepool-filesystem-unlock-passphrase-` + filesystem.id + `").addClass("has-error").removeClass("hidden").text("Passphrase requires a minimum of 8 characters."); - - validation.passphrase = false; - } else if (/^[a-zA-Z0-9-_. \`~!@#$%^\(\)+\\[\\]{}:',/?]*$/.test($("#input-storagepool-filesystem-unlock-passphrase-` + filesystem.id + `").val()) == false) { - $("#helpblock-storagepool-filesystem-unlock-passphrase-` + filesystem.id + `").addClass("has-error").removeClass("hidden").text("Passphrase contains invalid characters."); - - validation.passphrase = false; - } else { - $("#validationwrapper-storagepool-filesystem-unlock-passphrase-` + filesystem.id + `").removeClass("has-error"); - $("#helpblock-storagepool-filesystem-unlock-passphrase-` + filesystem.id + `").removeClass("has-error").addClass("hidden").text(""); - - validation.passphrase = true; - } - - if (!validation.passphrase) { - $("#validationwrapper-storagepool-filesystem-unlock-passphrase-` + filesystem.id + `").addClass("has-error"); - $("#input-storagepool-filesystem-unlock-passphrase-` + filesystem.id + `").focus(); - - $("#spinner-storagepool-filesystem-unlock-` + filesystem.id + `").addClass("hidden"); - $(this).prop("disabled", false); - } - - if (validation.passphrase) { - filesystem.mount = $("#switch-storagepool-filesystem-unlock-mount-` + filesystem.id + ` input").prop("checked"); - filesystem.overlay = $("#switch-storagepool-filesystem-unlock-overlay-` + filesystem.id + ` input").prop("checked"); - filesystem.passphrase = $("#input-storagepool-filesystem-unlock-passphrase-` + filesystem.id + `").val(); - - samba.enable = ` + ((pool.readonly || filesystem.sharesmb) ? false : `$("#switch-storagepool-filesystem-unlock-samba-enable-` + filesystem.id + ` input").prop("checked")`) + `; - - FnFileSystemUnlock({ name: "` + pool.name + `", id: "` + pool.id + `", altroot: ` + pool.altroot + `, readonly: ` + pool.readonly + ` }, { name: "` + filesystem.name + `", id: "` + filesystem.id + `", mount: filesystem.mount, overlay: filesystem.overlay, passphrase: filesystem.passphrase, type: "` + filesystem.type + `" }, { enable: samba.enable }, { name: "storagepool-filesystem-unlock", id: "` + filesystem.id + `" }, { refresh: true }); - } - }); - \x3C/script> - `; - - modal.id.empty().append(modal.content); -} - -function FnModalFileSystemUnmount(pool = { name, id, altroot: false, readonly: false }, filesystem = { name, id, encryptionroot, keystatus, sharesmb: false, type }) { - let modal = { - window: "" - }; - - modal.window = ` - - - \x3Cscript nonce="1t55lZ7tzuKTreHVNwE66Ox32Mc="> - $("#btn-storagepool-filesystem-unmount-` + filesystem.id + `").on("click", function () { - FnModalFileSystemUnmountContent({ name: "` + pool.name + `", id: "` + pool.id + `", altroot: ` + pool.altroot + `, readonly: ` + pool.readonly + ` }, { name: "` + filesystem.name + `", id: "` + filesystem.id + `", encryptionroot: "` + filesystem.encryptionroot + `", keystatus: "` + filesystem.keystatus + `", sharesmb: ` + filesystem.sharesmb + `, type: "` + filesystem.type + `" }, { id: $("#modal-storagepool-filesystem-unmount-` + filesystem.id + `") }); - FnFileSystemsMountedGet({ name: "` + pool.name + `", id: "` + pool.id + `" }, { name: "` + filesystem.name + `", id: "` + filesystem.id + `" }, { alert: { id: $("#div-storagepool-filesystem-unmount-warning-` + filesystem.id + `"), mount: false } }); - }); - \x3C/script> - `; - - $("#modals-storagepool-filesystem-" + pool.id).append(modal.window); -} - -function FnModalFileSystemUnmountContent(pool = { name, id, altroot: false, readonly: false }, filesystem = { name, id, encryptionroot, keystatus, sharesmb: false, type }, modal = { id }) { - modal.content = ` - - - \x3Cscript nonce="1t55lZ7tzuKTreHVNwE66Ox32Mc="> - $("#btn-storagepool-filesystem-unmount-apply-` + filesystem.id + `").on("click", function () { - $("#spinner-storagepool-filesystem-unmount-` + filesystem.id + `").removeClass("hidden"); - $(this).prop("disabled", true); - - let filesystem = { - force: $("#switch-storagepool-filesystem-unmount-force-` + filesystem.id + ` input").prop("checked"), - lock: ` + (filesystem.keystatus == "available" && filesystem.encryptionroot == filesystem.name ? `$("#switch-storagepool-filesystem-unmount-lock-` + filesystem.id + ` input").prop("checked")` : false) + ` - }; - let samba = { - disable: ` + ((!pool.readonly && filesystem.sharesmb) ? `$("#switch-storagepool-filesystem-unmount-samba-disable-` + filesystem.id + ` input").prop("checked")` : false) + `, - restart: $("#switch-storagepool-filesystem-unmount-samba-restart-` + filesystem.id + ` input").prop("checked") - }; - - FnFileSystemUnmount({ name: "` + pool.name + `", id: "` + pool.id + `", altroot: ` + pool.altroot + `, readonly: ` + pool.readonly + ` }, { name: "` + filesystem.name + `", id: "` + filesystem.id + `", force: filesystem.force, lock: filesystem.lock, type: "` + filesystem.type + `" }, { disable: samba.disable, restart: samba.restart }); - }); - \x3C/script> - `; - - modal.id.empty().append(modal.content); -} - -//#endregion - -//#region Modal Snapshots - -function FnModalSnaphshotsCreate(pool = { name, id }) { - let modal = { - window: "" - }; - - modal.window = ` - - - \x3Cscript nonce="1t55lZ7tzuKTreHVNwE66Ox32Mc="> - $("#btn-storagepool-snapshots-create-` + pool.id + `").on("click", function () { - FnModalSnaphshotsCreateContent({ name: "` + pool.name + `", id: "` + pool.id + `" }, { id: $("#modal-storagepool-snapshots-create-` + pool.id + `") }); - FnFileSystemsNamesGet({ name: "` + pool.name + `", id: "` + pool.id + `" }, { existing: { name: null, clone: false, encryption: false, encryptionroot: null, origin: null }, override: true }, { dropdown: { id: $("#dropdown-storagepool-snapshots-create-filesystem-` + pool.id + `"), selected: "` + pool.name + `" } }); - }); - \x3C/script> - `; - - $("#modals-storagepool-snapshots-" + pool.id).append(modal.window); -} - -function FnModalSnaphshotsCreateContent(pool = { name, id }, modal = { id }) { - modal.content = ` - - - \x3Cscript nonce="1t55lZ7tzuKTreHVNwE66Ox32Mc="> - $("#switch-storagepool-snapshots-create-customname-` + pool.id + ` input").on("click", function () { - $("#validationwrapper-storagepool-snapshots-create-name-` + pool.id + `").removeClass("has-error"); - $("#helpblock-storagepool-snapshots-create-name-` + pool.id + `").removeClass("has-error").addClass("hidden").text(""); - - if ($(this).prop("checked")) { - $("#input-storagepool-snapshots-create-name-` + pool.id + `").val("").prop("readonly", false).focus(); - } else { - $("#input-storagepool-snapshots-create-name-` + pool.id + `").val("YYYY.MM.DD-HH.MM.SS").prop("readonly", true);; - } - }); - - $("#btn-storagepool-snapshots-create-apply-` + pool.id + `").on("click", function () { - $("#spinner-storagepool-snapshots-create-` + pool.id + `").removeClass("hidden"); - $(this).prop("disabled", true); - - let snapshot = { - name: "", - id: "", - recursive: false - }; - let validation = { - name: false - }; - - if ($("#input-storagepool-snapshots-create-name-` + pool.id + `").val().length == 0) { - $("#helpblock-storagepool-snapshots-create-name-` + pool.id + `").addClass("has-error").removeClass("hidden").text("Name can not be empty."); - - validation.name = false; - } else if (/^[a-zA-Z0-9-_.: ]*$/.test($("#input-storagepool-snapshots-create-name-` + pool.id + `").val()) == false) { - $("#helpblock-storagepool-snapshots-create-name-` + pool.id + `").addClass("has-error").removeClass("hidden").text("Name contains invalid characters."); - - validation.name = false; - } else if (/^[.]/.test($("#input-storagepool-snapshots-create-name-` + pool.id + `").val())) { - $("#helpblock-storagepool-snapshots-create-name-` + pool.id + `").addClass("has-error").removeClass("hidden").text("Name can not begin with a period (.)."); - - validation.name = false; - } else if (/^[_]/.test($("#input-storagepool-snapshots-create-name-` + pool.id + `").val())) { - $("#helpblock-storagepool-snapshots-create-name-` + pool.id + `").addClass("has-error").removeClass("hidden").text("Name can not begin with an underscore (_)."); - - validation.name = false; - } else if (/^[-]/.test($("#input-storagepool-snapshots-create-name-` + pool.id + `").val())) { - $("#helpblock-storagepool-snapshots-create-name-` + pool.id + `").addClass("has-error").removeClass("hidden").text("Name can not begin with a hypen (-)."); - - validation.name = false; - } else if (/^[:]/.test($("#input-storagepool-snapshots-create-name-` + pool.id + `").val())) { - $("#helpblock-storagepool-snapshots-create-name-` + pool.id + `").addClass("has-error").removeClass("hidden").text("Name can not begin with an colon (:)."); - - validation.name = false; - } else if (/^[ ]/.test($("#input-storagepool-snapshots-create-name-` + pool.id + `").val())) { - $("#helpblock-storagepool-snapshots-create-name-` + pool.id + `").addClass("has-error").removeClass("hidden").text("Name can not begin with whitespace ( )."); - - validation.name = false; - } else if (/[ ]$/.test($("#input-storagepool-snapshots-create-name-` + pool.id + `").val())) { - $("#helpblock-storagepool-snapshots-create-name-` + pool.id + `").addClass("has-error").removeClass("hidden").text("Name can not end with whitespace ( )."); - - validation.name = false; - } else { - $("#validationwrapper-storagepool-snapshots-create-name-` + pool.id + `").removeClass("has-error"); - $("#helpblock-storagepool-snapshots-create-name-` + pool.id + `").addClass("hidden").text(""); - - validation.name = true; - } - - if (!validation.name) { - $("#validationwrapper-storagepool-snapshots-create-name-` + pool.id + `").addClass("has-error"); - $("#input-storagepool-snapshots-create-name-` + pool.id + `").focus(); - - $("#spinner-storagepool-snapshots-create-` + pool.id + `").addClass("hidden"); - $(this).prop("disabled", false); - } - - if (validation.name) { - snapshot.name = $("#btnspan-storagepool-snapshots-create-filesystem-` + pool.id + `").attr("data-field-value") + "@" + $("#input-storagepool-snapshots-create-name-` + pool.id + `").val(); - snapshot.id = FnGenerateId({ at: true, colon: true, forwardslash: true, period: true, underscore: true, whitespace: true }, { name: snapshot.name, attribute: true }); - snapshot.recursive = $("#switch-storagepool-snapshots-create-recursive-` + pool.id + ` input").prop("checked"); - - if ($("#switch-storagepool-snapshots-create-customname-` + pool.id + ` input").prop("checked")) { - FnSnapshotCreate({ name: "` + pool.name + `", id: "` + pool.id + `" }, { name: snapshot.name, id: snapshot.id, recursive: snapshot.recursive }, { name: "storagepool-snapshots-create", id: "` + pool.id + `"}); - } else { - FnSnapshotCreateDateGet({ name: "` + pool.name + `", id: "` + pool.id + `" }, { name: snapshot.name, id: snapshot.id, recursive: snapshot.recursive }, { name: "storagepool-snapshots-create", id: "` + pool.id + `"}); - } - } - }); - - $("#dropdown-storagepool-snapshots-create-filesystem-` + pool.id + `").on("click", "li a", function () { - $("#btnspan-storagepool-snapshots-create-filesystem-` + pool.id + `").text($(this).text()).attr("data-field-value", $(this).parent().attr("value")); - $(this).parent().siblings().removeClass("active"); - $(this).parent().addClass("active"); - }); - \x3C/script> - `; - - modal.id.empty().append(modal.content); -} - -//#endregion - -//#region Modal Snapshot - -function FnModalSnapshotClone(pool = { name, id, altroot: false }, snapshot = { name, id, encryption: false, encryptionroot }) { - let modal = { - window: "" - }; - - modal.window = ` - - - \x3Cscript nonce="1t55lZ7tzuKTreHVNwE66Ox32Mc="> - $("#btn-storagepool-snapshot-clone-` + snapshot.id + `").on("click", function () { - FnModalSnapshotCloneContent({ name: "` + pool.name + `", id: "` + pool.id + `", altroot: ` + pool.altroot + ` }, { name: "` + snapshot.name + `", id: "` + snapshot.id + `", encryption: ` + snapshot.encryption + ` }, { id: $("#modal-storagepool-snapshot-clone-` + snapshot.id + `") }); - FnFileSystemsNamesGet({ name: "` + pool.name + `", id: "` + pool.id + `" }, { existing: { name: null, clone: false, encryption: ` + snapshot.encryption + `, encryptionroot: "` + snapshot.encryptionroot + `", origin: null }, override: false }, { dropdown: { id: $("#dropdown-storagepool-snapshot-clone-parentfilesystem-` + snapshot.id + `"), selected: "` + snapshot.name.replace(/^(.*)\@.*$/, "$1") + `" } }); - - setTimeout(function() { - $("#input-storagepool-snapshot-clone-name-` + snapshot.id + `").focus(); - }, 600); - }); - \x3C/script> - `; - - $("#modals-storagepool-snapshot-" + pool.id).append(modal.window); -} - -function FnModalSnapshotCloneContent(pool = { name, id, altroot: false }, snapshot = { name, id, encryption: false }, modal = { id }) { - modal.content = ` - - - \x3Cscript nonce="1t55lZ7tzuKTreHVNwE66Ox32Mc="> - $("#btn-storagepool-snapshot-clone-apply-` + snapshot.id + `").on("click", function () { - $("#spinner-storagepool-snapshot-clone-` + snapshot.id + `").removeClass("hidden"); - $(this).prop("disabled", true); - - let snapshot = { - clone: { - createnonexistparents: false, - name: "", - parent: "" - } - }; - let validation = { - name: false - }; - - if ($("#input-storagepool-snapshot-clone-name-` + snapshot.id + `").val().length == 0) { - $("#helpblock-storagepool-snapshot-clone-name-` + snapshot.id + `").addClass("has-error").removeClass("hidden").text("Name can not be empty."); - - validation.name = false; - } else if (/^[a-zA-Z0-9-_.:/ ]*$/.test($("#input-storagepool-snapshot-clone-name-` + snapshot.id + `").val()) == false) { - $("#helpblock-storagepool-snapshot-clone-name-` + snapshot.id + `").addClass("has-error").removeClass("hidden").text("Name contains invalid characters."); - - validation.name = false; - } else if (/^[.]/.test($("#input-storagepool-snapshot-clone-name-` + snapshot.id + `").val())) { - $("#helpblock-storagepool-snapshot-clone-name-` + snapshot.id + `").addClass("has-error").removeClass("hidden").text("Name can not begin with a period (.)."); - - validation.name = false; - } else if (/^[_]/.test($("#input-storagepool-snapshot-clone-name-` + snapshot.id + `").val())) { - $("#helpblock-storagepool-snapshot-clone-name-` + snapshot.id + `").addClass("has-error").removeClass("hidden").text("Name can not begin with an underscore (_)."); - - validation.name = false; - } else if (/^[-]/.test($("#input-storagepool-snapshot-clone-name-` + snapshot.id + `").val())) { - $("#helpblock-storagepool-snapshot-clone-name-` + snapshot.id + `").addClass("has-error").removeClass("hidden").text("Name can not begin with a hypen (-)."); - - validation.name = false; - } else if (/^[:]/.test($("#input-storagepool-snapshot-clone-name-` + snapshot.id + `").val())) { - $("#helpblock-storagepool-snapshot-clone-name-` + snapshot.id + `").addClass("has-error").removeClass("hidden").text("Name can not begin with an colon (:)."); - - validation.name = false; - } else if (/^[/]/.test($("#input-storagepool-snapshot-clone-name-` + snapshot.id + `").val())) { - $("#helpblock-storagepool-snapshot-clone-name-` + snapshot.id + `").addClass("has-error").removeClass("hidden").text("Name can not begin with a forward slash (/)."); - - validation.name = false; - } else if (/[/]$/.test($("#input-storagepool-snapshot-clone-name-` + snapshot.id + `").val())) { - $("#helpblock-storagepool-snapshot-clone-name-` + snapshot.id + `").addClass("has-error").removeClass("hidden").text("Name can not end with a forward slash (/)."); - - validation.name = false; - } else if (/^ |\\/ /.test($("#input-storagepool-snapshot-clone-name-` + snapshot.id + `").val())) { - $("#helpblock-storagepool-snapshot-clone-name-` + snapshot.id + `").addClass("has-error").removeClass("hidden").text("Name can not begin with whitespace ( )."); - - validation.name = false; - } else if (/ $| \\//.test($("#input-storagepool-snapshot-clone-name-` + snapshot.id + `").val())) { - $("#helpblock-storagepool-snapshot-clone-name-` + snapshot.id + `").addClass("has-error").removeClass("hidden").text("Name can not end with whitespace ( )."); - - validation.name = false; - } else { - $("#validationwrapper-storagepool-snapshot-clone-name-` + snapshot.id + `").removeClass("has-error"); - $("#helpblock-storagepool-snapshot-clone-name-` + snapshot.id + `").removeClass("has-error").addClass("hidden").text(""); - - validation.name = true; - } - - if (!validation.name) { - $("#validationwrapper-storagepool-snapshot-clone-name-` + snapshot.id + `").addClass("has-error"); - $("#input-storagepool-snapshot-clone-name-` + snapshot.id + `").focus(); - - $("#spinner-storagepool-snapshot-clone-` + snapshot.id + `").addClass("hidden"); - $(this).prop("disabled", false); - } - - if (validation.name) { - snapshot.clone.createnonexistparents = $("#switch-storagepool-snapshot-clone-createnonexistparents-` + snapshot.id + ` input").prop("checked"); - snapshot.clone.name = $("#btnspan-storagepool-snapshot-clone-parentfilesystem-` + snapshot.id + `").attr("data-field-value") + "/" + $("#input-storagepool-snapshot-clone-name-` + snapshot.id + `").val(); - snapshot.clone.parent = $("#btnspan-storagepool-snapshot-clone-parentfilesystem-` + snapshot.id + `").attr("data-field-value"); - - FnSnapshotClone({ name: "` + pool.name + `", id: "` + pool.id + `", altroot: ` + pool.altroot + ` }, { name: "` + snapshot.name + `", id: "` + snapshot.id + `", clone: { name: snapshot.clone.name, createnonexistparents: snapshot.clone.createnonexistparents, parent: snapshot.clone.parent } }); - } - }); - - $("#dropdown-storagepool-snapshot-clone-parentfilesystem-` + snapshot.id + `").on("click", "li a", function () { - $("#btnspan-storagepool-snapshot-clone-parentfilesystem-` + snapshot.id + `").text($(this).text()).attr("data-field-value", $(this).parent().attr("value")); - $(this).parent().siblings().removeClass("active"); - $(this).parent().addClass("active"); - }); - \x3C/script> - `; - - modal.id.empty().append(modal.content); -} - -function FnModalSnapshotDestroy(pool = { name, id, altroot: false, readonly: false }, snapshot = { name, id, clones: [] }) { - let modal = { - window: "" - }; - - modal.window = ` - - - \x3Cscript nonce="1t55lZ7tzuKTreHVNwE66Ox32Mc="> - $("#btn-storagepool-snapshot-destroy-` + snapshot.id + `").on("click", function () { - FnModalSnapshotDestroyContent({ name: "` + pool.name + `", id: "` + pool.id + `", altroot: ` + pool.altroot + `, readonly: ` + pool.readonly + ` }, { name: "` + snapshot.name + `", id: "` + snapshot.id + `", clones: [` + (snapshot.clones.length > 0 ? `"` + snapshot.clones.join(`","`) + `"` : ``) + `] }, { id: $("#modal-storagepool-snapshot-destroy-` + snapshot.id + `") }); - ` + (snapshot.clones.length > 0 ? `FnSnapshotChildFileSystemsGet({ name: "` + pool.name + `", id: "` + pool.id + `" }, { name: "` + snapshot.name + `", id: "` + snapshot.id + `" }, { id: ` + (snapshot.clones.length > 0 ? `["` + snapshot.clones.join(`", "`) + `"]` : `[]`) + ` }, { name: "storagepool-snapshot-destroy", id: "` + snapshot.id + `" });` : ``) + ` - FnSnapshotChildSnapshotsGet({ name: "` + pool.name + `", id: "` + pool.id + `" }, { name: "` + snapshot.name + `", id: "` + snapshot.id + `", exclude: false }, { id: ` + (snapshot.clones.length > 0 ? `["` + snapshot.clones.join(`", "`) + `"]` : `[]`) + ` }, { name: "storagepool-snapshot-destroy", id: "` + snapshot.id + `" }); - }); - \x3C/script> - `; - - $("#modals-storagepool-snapshot-" + pool.id).append(modal.window); -} - -function FnModalSnapshotDestroyContent(pool = { name, id, altroot: false, readonly: false }, snapshot = { name, id, clones: [] }, modal = { id }) { - modal.content = ` - - - \x3Cscript nonce="1t55lZ7tzuKTreHVNwE66Ox32Mc="> - $("#switch-storagepool-snapshot-destroy-recursive-` + snapshot.id + ` input").on("click", function () { - if ($(this).prop("checked") && $("#switch-storagepool-snapshot-destroy-recursiveall-` + snapshot.id + ` input").prop("checked")) { - $("#switch-storagepool-snapshot-destroy-recursiveall-` + snapshot.id + ` input").click(); - } - - $("#panel-storagepool-snapshot-destroy-child-filesystems-` + snapshot.id + `").addClass("hidden"); - $("#panel-storagepool-snapshot-destroy-child-filesystems-` + snapshot.id + ` .collapse").collapse("hide"); - $("#panel-storagepool-snapshot-destroy-child-snapshotswithclones-` + snapshot.id + `").addClass("hidden"); - $("#panel-storagepool-snapshot-destroy-child-snapshotswithclones-` + snapshot.id + ` .collapse").collapse("hide"); - - if ($(this).prop("checked") && $("#panelgroup-storagepool-snapshot-destroy-` + snapshot.id + `").attr("data-snapshot-child-snapshots") > 0) { - $("#panel-storagepool-snapshot-destroy-child-snapshots-` + snapshot.id + `").removeClass("hidden"); - } else { - $("#panel-storagepool-snapshot-destroy-child-snapshots-` + snapshot.id + `").addClass("hidden"); - $("#panel-storagepool-snapshot-destroy-child-snapshots-` + snapshot.id + ` .collapse").collapse("hide"); - } - if ($(this).prop("checked") && $("#panelgroup-storagepool-snapshot-destroy-` + snapshot.id + `").attr("data-snapshot-child-snapshots") > 0) { - $("#panelgroup-storagepool-snapshot-destroy-` + snapshot.id + `").addClass("modal-ct-bodytext-1"); - } else { - $("#panelgroup-storagepool-snapshot-destroy-` + snapshot.id + `").removeClass("modal-ct-bodytext-1"); - } - }); - - $("#switch-storagepool-snapshot-destroy-recursiveall-` + snapshot.id + ` input").on("click", function () { - if ($(this).prop("checked") && $("#switch-storagepool-snapshot-destroy-recursive-` + snapshot.id + ` input").prop("checked")) { - $("#switch-storagepool-snapshot-destroy-recursive-` + snapshot.id + ` input").click(); - } - - $("#panel-storagepool-snapshot-destroy-child-filesystems-` + snapshot.id + `").addClass("hidden"); - $("#panel-storagepool-snapshot-destroy-child-filesystems-` + snapshot.id + ` .collapse").collapse("hide"); - $("#panel-storagepool-snapshot-destroy-child-snapshots-` + snapshot.id + `").addClass("hidden"); - $("#panel-storagepool-snapshot-destroy-child-snapshots-` + snapshot.id + ` .collapse").collapse("hide"); - - if ($(this).prop("checked") && $("#panelgroup-storagepool-snapshot-destroy-` + snapshot.id + `").attr("data-snapshot-child-filesystems") > 0) { - $("#panel-storagepool-snapshot-destroy-child-filesystems-` + snapshot.id + `").removeClass("hidden"); - } else { - $("#panel-storagepool-snapshot-destroy-child-filesystems-` + snapshot.id + `").addClass("hidden"); - $("#panel-storagepool-snapshot-destroy-child-filesystems-` + snapshot.id + ` .collapse").collapse("hide"); - } - if ($(this).prop("checked") && $("#panelgroup-storagepool-snapshot-destroy-` + snapshot.id + `").attr("data-snapshot-child-snapshotswithclones") > 0) { - $("#panel-storagepool-snapshot-destroy-child-snapshotswithclones-` + snapshot.id + `").removeClass("hidden"); - } else { - $("#panel-storagepool-snapshot-destroy-child-snapshotswithclones-` + snapshot.id + `").addClass("hidden"); - $("#panel-storagepool-snapshot-destroy-child-snapshotswithclones-` + snapshot.id + ` .collapse").collapse("hide"); - } - if ($(this).prop("checked") && ($("#panelgroup-storagepool-snapshot-destroy-` + snapshot.id + `").attr("data-snapshot-child-snapshotswithclones") > 0 || $("#panelgroup-storagepool-snapshot-destroy-` + snapshot.id + `").attr("data-snapshot-child-snapshotswithclones") > 0)) { - $("#panelgroup-storagepool-snapshot-destroy-` + snapshot.id + `").addClass("modal-ct-bodytext-1"); - } else { - $("#panelgroup-storagepool-snapshot-destroy-` + snapshot.id + `").removeClass("modal-ct-bodytext-1"); - } - }); - - $("#btn-storagepool-snapshot-destroy-apply-` + snapshot.id + `").on("click", function () { - $("#spinner-storagepool-snapshot-destroy-` + snapshot.id + `").removeClass("hidden"); - $(this).prop("disabled", true); - - let snapshot = { - recursive: $("#switch-storagepool-snapshot-destroy-recursive-` + snapshot.id + ` input").prop("checked"), - recursiveall: $("#switch-storagepool-snapshot-destroy-recursiveall-` + snapshot.id + ` input").prop("checked") - }; - let samba = { - restart: $("#switch-storagepool-snapshot-destroy-samba-restart-` + snapshot.id + ` input").prop("checked") - }; - - FnSnapshotDestroy({ name: "` + pool.name + `", id: "` + pool.id + `", altroot: ` + pool.altroot + `, readonly: ` + pool.readonly + ` }, { name: "` + snapshot.name + `", id: "` + snapshot.id + `", clones: ` + (snapshot.clones.length > 0 ? `["` + snapshot.clones.join(`", "`) + `"]` : `[]`) + `, recursive: snapshot.recursive, recursiveall: snapshot.recursiveall }, { restart: samba.restart }); - }); - \x3C/script> - `; - - modal.id.empty().append(modal.content); -} - -function FnModalSnapshotRename(pool = { name, id }, snapshot = { name, id, creation }) { - let modal = { - window: "" - }; - - modal.window = ` - - - \x3Cscript nonce="1t55lZ7tzuKTreHVNwE66Ox32Mc="> - $("#btn-storagepool-snapshot-rename-` + snapshot.id + `").on("click", function () { - FnModalSnapshotRenameContent({ name: "` + pool.name + `", id: "` + pool.id + `" }, { name: "` + snapshot.name + `", id: "` + snapshot.id + `", creation: "` + snapshot.creation + `" }, { id: $("#modal-storagepool-snapshot-rename-` + snapshot.id + `") }); - - setTimeout(function() { - $("#input-storagepool-snapshot-rename-name-` + snapshot.id + `").focus(); - }, 600); - }); - \x3C/script> - `; - - $("#modals-storagepool-snapshot-" + pool.id).append(modal.window); -} - -function FnModalSnapshotRenameContent(pool = { name, id }, snapshot = { name, id, creation }, modal = { id }) { - modal.content = ` - - - \x3Cscript nonce="1t55lZ7tzuKTreHVNwE66Ox32Mc="> - $("#switch-storagepool-snapshot-rename-creationdate-` + snapshot.id + ` input").on("click", function () { - if ($(this).prop("checked")) { - $("#input-storagepool-snapshot-rename-name-` + snapshot.id + `").val("` + FnDateTimeSnapshot({ date: new Date(snapshot.creation * 1000) }) + `").prop("readonly", true); - } else { - $("#input-storagepool-snapshot-rename-name-` + snapshot.id + `").val("` + snapshot.name.replace(/^.*\@(.*)$/, "$1") + `").prop("readonly", false).focus(); - } - }); - - $("#btn-storagepool-snapshot-rename-apply-` + snapshot.id + `").on("click", function () { - $("#spinner-storagepool-snapshot-rename-` + snapshot.id + `").removeClass("hidden"); - $(this).prop("disabled", true); - - let snapshot = { - namenew: "", - recursive: false - }; - let validation = { - name: false - }; - - if ("` + snapshot.name.replace(/^(.*)\@.*$/, "$1") + `" + "@" + $("#input-storagepool-snapshot-rename-name-` + snapshot.id + `").val() == "` + snapshot.name + `") { - $("#helpblock-storagepool-snapshot-rename-name-` + snapshot.id + `").addClass("has-error").removeClass("hidden").text("Name must be different."); - - validation.name = false; - } else if ($("#input-storagepool-snapshot-rename-name-` + snapshot.id + `").val().length == 0) { - $("#helpblock-storagepool-snapshot-rename-name-` + snapshot.id + `").addClass("has-error").removeClass("hidden").text("Name can not be empty."); - - validation.name = false; - } else if (/^[a-zA-Z0-9-_.: ]*$/.test($("#input-storagepool-snapshot-rename-name-` + snapshot.id + `").val()) == false) { - $("#helpblock-storagepool-snapshot-rename-name-` + snapshot.id + `").addClass("has-error").removeClass("hidden").text("Name contains invalid characters."); - - validation.name = false; - } else if (/^[.]/.test($("#input-storagepool-snapshot-rename-name-` + snapshot.id + `").val())) { - $("#helpblock-storagepool-snapshot-rename-name-` + snapshot.id + `").addClass("has-error").removeClass("hidden").text("Name can not begin with a period (.)."); - - validation.name = false; - } else if (/^[_]/.test($("#input-storagepool-snapshot-rename-name-` + snapshot.id + `").val())) { - $("#helpblock-storagepool-snapshot-rename-name-` + snapshot.id + `").addClass("has-error").removeClass("hidden").text("Name can not begin with an underscore (_)."); - - validation.name = false; - } else if (/^[-]/.test($("#input-storagepool-snapshot-rename-name-` + snapshot.id + `").val())) { - $("#helpblock-storagepool-snapshot-rename-name-` + snapshot.id + `").addClass("has-error").removeClass("hidden").text("Name can not begin with a hypen (-)."); - - validation.name = false; - } else if (/^[:]/.test($("#input-storagepool-snapshot-rename-name-` + snapshot.id + `").val())) { - $("#helpblock-storagepool-snapshot-rename-name-` + snapshot.id + `").addClass("has-error").removeClass("hidden").text("Name can not begin with an colon (:)."); - - validation.name = false; - } else if (/^[ ]/.test($("#input-storagepool-snapshot-rename-name-` + snapshot.id + `").val())) { - $("#helpblock-storagepool-snapshot-rename-name-` + snapshot.id + `").addClass("has-error").removeClass("hidden").text("Name can not begin with whitespace ( )."); - - validation.name = false; - } else if (/[ ]$/.test($("#input-storagepool-snapshot-rename-name-` + snapshot.id + `").val())) { - $("#helpblock-storagepool-snapshot-rename-name-` + snapshot.id + `").addClass("has-error").removeClass("hidden").text("Name can not end with whitespace ( )."); - - validation.name = false; - } else { - $("#validationwrapper-storagepool-snapshot-rename-name-` + snapshot.id + `").removeClass("has-error"); - $("#helpblock-storagepool-snapshot-rename-name-` + snapshot.id + `").removeClass("has-error").addClass("hidden").text(""); - - validation.name = true; - } - - if (!validation.name) { - $("#validationwrapper-storagepool-snapshot-rename-name-` + snapshot.id + `").addClass("has-error"); - $("#input-storagepool-snapshot-rename-name-` + snapshot.id + `").focus(); - - $("#spinner-storagepool-snapshot-rename-` + snapshot.id + `").addClass("hidden"); - $(this).prop("disabled", false); - } - - if (validation.name) { - snapshot.namenew = "` + snapshot.name.replace(/^(.*)\@.*$/, "$1") + `" + "@" + $("#input-storagepool-snapshot-rename-name-` + snapshot.id + `").val(); - snapshot.recursive = $("#switch-storagepool-snapshot-rename-recursive-` + snapshot.id + ` input").prop("checked"); - - FnSnapshotRename({ name: "` + pool.name + `", id: "` + pool.id + `" }, { name: "` + snapshot.name + `", id: "` + snapshot.id + `", namenew: snapshot.namenew, recursive: snapshot.recursive }); - } - }); - \x3C/script> - `; - - modal.id.empty().append(modal.content); -} - -function FnModalSnapshotRollBack(pool = { name, id, altroot: false, readonly: false }, snapshot = { name, id, creation }) { - let modal = { - window: "" - }; - - modal.window = ` - - - \x3Cscript nonce="1t55lZ7tzuKTreHVNwE66Ox32Mc="> - $("#btn-storagepool-snapshot-rollback-` + snapshot.id + `").on("click", function () { - FnModalSnapshotRollBackContent({ name: "` + pool.name + `", id: "` + pool.id + `", altroot: ` + pool.altroot + `, readonly: ` + pool.readonly + ` }, { name: "` + snapshot.name + `", id: "` + snapshot.id + `", creation: "` + snapshot.creation + `" }, { id: $("#modal-storagepool-snapshot-rollback-` + snapshot.id + `") }); - FnSnapshotRollBackSnapshotsGet({ name: "` + pool.name + `", id: "` + pool.id + `" }, { name: "` + snapshot.name + `", id: "` + snapshot.id + `", creation: "` + snapshot.creation + `" }, { name: "storagepool-snapshot-rollback", id: "` + snapshot.id + `" }); - }); - \x3C/script> - `; - - $("#modals-storagepool-snapshot-" + pool.id).append(modal.window); -} - -function FnModalSnapshotRollBackContent(pool = { name, id, altroot: false, readonly: false }, snapshot = { name, id, creation }, modal = { id }) { - modal.content = ` - - - \x3Cscript nonce="1t55lZ7tzuKTreHVNwE66Ox32Mc="> - $("#switch-storagepool-snapshot-rollback-recursive-` + snapshot.id + ` input").on("click", function () { - if ($(this).prop("checked") && $("#switch-storagepool-snapshot-rollback-recursiveall-` + snapshot.id + ` input").prop("checked")) { - $("#switch-storagepool-snapshot-rollback-recursiveall-` + snapshot.id + ` input").click(); - } - - $("#panel-storagepool-snapshot-rollback-child-filesystems-` + snapshot.id + `").addClass("hidden"); - $("#panel-storagepool-snapshot-rollback-child-filesystems-` + snapshot.id + ` .collapse").collapse("hide"); - $("#panel-storagepool-snapshot-rollback-child-snapshotswithclones-` + snapshot.id + `").addClass("hidden"); - $("#panel-storagepool-snapshot-rollback-child-snapshotswithclones-` + snapshot.id + ` .collapse").collapse("hide"); - - if ($(this).prop("checked") && $("#panelgroup-storagepool-snapshot-rollback-` + snapshot.id + `").attr("data-snapshot-snapshots") > 0) { - $("#panel-storagepool-snapshot-rollback-snapshots-` + snapshot.id + `").removeClass("hidden"); - } else { - $("#panel-storagepool-snapshot-rollback-snapshots-` + snapshot.id + `").addClass("hidden"); - $("#panel-storagepool-snapshot-rollback-snapshots-` + snapshot.id + ` .collapse").collapse("hide"); - } - }); - - $("#switch-storagepool-snapshot-rollback-recursiveall-` + snapshot.id + ` input").on("click", function () { - if ($(this).prop("checked") && $("#switch-storagepool-snapshot-rollback-recursive-` + snapshot.id + ` input").prop("checked")) { - $("#switch-storagepool-snapshot-rollback-recursive-` + snapshot.id + ` input").click(); - } - - if ($(this).prop("checked")) { - $("#switch-storagepool-snapshot-rollback-force-` + snapshot.id + `").parent().removeClass("hidden"); - } else { - $("#switch-storagepool-snapshot-rollback-force-` + snapshot.id + `").parent().addClass("hidden"); - - if ($("#switch-storagepool-snapshot-rollback-force-` + snapshot.id + ` input").prop("checked")) { - $("#switch-storagepool-snapshot-rollback-force-` + snapshot.id + ` input").click(); - } - } - - $("#panel-storagepool-snapshot-rollback-child-filesystems-` + snapshot.id + `").addClass("hidden"); - $("#panel-storagepool-snapshot-rollback-child-filesystems-` + snapshot.id + ` .collapse").collapse("hide"); - $("#panel-storagepool-snapshot-rollback-snapshots-` + snapshot.id + `").addClass("hidden"); - $("#panel-storagepool-snapshot-rollback-snapshots-` + snapshot.id + ` .collapse").collapse("hide"); - - if ($(this).prop("checked") && $("#panelgroup-storagepool-snapshot-rollback-` + snapshot.id + `").attr("data-snapshot-child-filesystems") > 0) { - $("#panel-storagepool-snapshot-rollback-child-filesystems-` + snapshot.id + `").removeClass("hidden"); - } else { - $("#panel-storagepool-snapshot-rollback-child-filesystems-` + snapshot.id + `").addClass("hidden"); - $("#panel-storagepool-snapshot-rollback-child-filesystems-` + snapshot.id + ` .collapse").collapse("hide"); - } - if ($(this).prop("checked") && $("#panelgroup-storagepool-snapshot-rollback-` + snapshot.id + `").attr("data-snapshot-child-snapshotswithclones") > 0) { - $("#panel-storagepool-snapshot-rollback-child-snapshotswithclones-` + snapshot.id + `").removeClass("hidden"); - } else { - $("#panel-storagepool-snapshot-rollback-child-snapshotswithclones-` + snapshot.id + `").addClass("hidden"); - $("#panel-storagepool-snapshot-rollback-child-snapshotswithclones-` + snapshot.id + ` .collapse").collapse("hide"); - } - }); - - $("#btn-storagepool-snapshot-rollback-apply-` + snapshot.id + `").on("click", function () { - $("#spinner-storagepool-snapshot-rollback-` + snapshot.id + `").removeClass("hidden"); - $(this).prop("disabled", true); - - let snapshot = { - force: ($("#switch-storagepool-snapshot-rollback-recursiveall-` + snapshot.id + ` input").prop("checked") ? $("#switch-storagepool-snapshot-rollback-force-` + snapshot.id + ` input").prop("checked") : false), - recursive: $("#switch-storagepool-snapshot-rollback-recursive-` + snapshot.id + ` input").prop("checked"), - recursiveall: $("#switch-storagepool-snapshot-rollback-recursiveall-` + snapshot.id + ` input").prop("checked") - }; - let samba = { - restart: $("#switch-storagepool-snapshot-rollback-samba-restart-` + snapshot.id + ` input").prop("checked") - }; - - FnSnapshotRollBack({ name: "` + pool.name + `", id: "` + pool.id + `", altroot: ` + pool.altroot + `, readonly: ` + pool.readonly + ` }, { name: "` + snapshot.name + `", id: "` + snapshot.id + `", creation: "` + snapshot.creation + `", force: snapshot.force, recursive: snapshot.recursive, recursiveall: snapshot.recursiveall }, { restart: samba.restart }); - }); - \x3C/script> - `; - - modal.id.empty().append(modal.content); -} - -//#endregion - -//#region Modal Status - -function FnModalStatusDiskAttach(pool = { name, id, status: { config: { items: { index: 0 }, tier: { name, dedup: false, logs: false, special: false } } } }, virtualdevice = { id, disk: true }) { - let modal = { - tiername: (pool.status.config.tier.dedup ? "Dedup" : (pool.status.config.tier.logs ? "Log" : (pool.status.config.tier.special ? "Special" : pool.status.config.tier.name))), - window: "" - }; - - modal.window = ` - - - \x3Cscript nonce="1t55lZ7tzuKTreHVNwE66Ox32Mc="> - $("#btn-storagepool-status-disk-attach-` + pool.status.config.items.index + `-` + pool.id + `").on("click", function () { - FnStoragePoolRefreshAutoDisable({ name: "` + pool.name + `", id: "` + pool.id + `" }); - FnModalStatusDiskAttachContent({ name: "` + pool.name + `", id: "` + pool.id + `", status: { config: { items: { index: ` + pool.status.config.items.index + ` } } } }, { id: "` + virtualdevice.id + `" , disk: ` + virtualdevice.disk + ` }, { id: $("#modal-storagepool-status-disk-attach-` + pool.status.config.items.index + `-` + pool.id + `"), tiername: "` + modal.tiername + `" }); - FnDisksAvailableGet({ name: "storagepool-status-disk-attach-disks", id: "` + pool.status.config.items.index + `-` + pool.id + `", default: true }); - }); - \x3C/script> - `; - - $("#modals-storagepool-status-" + pool.id).append(modal.window); -} - -function FnModalStatusDiskAttachContent(pool = { name, id, status: { config: { items: { index: 0 } } } }, virtualdevice = { id, disk: true }, modal = { id, tiername }) { - modal.content = ` - - - \x3Cscript nonce="1t55lZ7tzuKTreHVNwE66Ox32Mc="> - $("#switch-storagepool-status-disk-attach-disks-wwn-` + pool.status.config.items.index + `-` + pool.id + ` input").on("click", function () { - $("#btnspan-storagepool-status-disk-attach-disks-identifier-` + pool.status.config.items.index + `-` + pool.id + `").text("Block Device"); - $("#dropdown-storagepool-status-disk-attach-disks-identifier-` + pool.status.config.items.index + `-` + pool.id + ` li").siblings().removeClass("active"); - $("#dropdown-storagepool-status-disk-attach-disks-identifier-` + pool.status.config.items.index + `-` + pool.id + ` li[value='blockdevice']").addClass("active"); - $("#helpblock-storagepool-status-disk-attach-disks-identifierwarning-` + pool.status.config.items.index + `-` + pool.id + `").addClass("hidden").text(""); - ` + (zfsmanager.zfs.warnings.nvmevdev ? `$("#helpblock-storagepool-status-disk-attach-disks-identifierwarningzfs-` + pool.status.config.items.index + `-` + pool.id + `").addClass("hidden");` : ``) + ` - - let disk = { - identifier: ($(this).prop("checked") ? "wwn" : "blockdevice"), - identifiertext: ($(this).prop("checked") ? "WWN" : "Block Device") - }; - - if ($(this).prop("checked")) { - $("#controllabel-storagepool-status-disk-attach-disks-identifier-` + pool.status.config.items.index + `-` + pool.id + `").addClass("hidden"); - $("#validationwrapper-storagepool-status-disk-attach-disks-identifier-` + pool.status.config.items.index + `-` + pool.id + `").addClass("hidden"); - } else { - $("#controllabel-storagepool-status-disk-attach-disks-identifier-` + pool.status.config.items.index + `-` + pool.id + `").removeClass("hidden"); - $("#validationwrapper-storagepool-status-disk-attach-disks-identifier-` + pool.status.config.items.index + `-` + pool.id + `").removeClass("hidden"); - } - - $("#listgroup-storagepool-status-disk-attach-disks-` + pool.status.config.items.index + `-` + pool.id + ` input[name='checkbox-storagepool-status-disk-attach-disks-` + pool.status.config.items.index + `-` + pool.id + `']").map(function () { - if ($(this).attr("data-disk-id-" + disk.identifier)) { - $(this).next().find(".select-ct-disk-row-id").text((disk.identifier == "blockdevice" ? "/dev/" : "") + $(this).attr("data-disk-id-" + disk.identifier)); - $(this).attr("data-disk-name", $(this).attr("data-disk-id-" + disk.identifier)); - } else { - $(this).next().find(".select-ct-disk-row-id").text("/dev/" + $(this).attr("data-disk-id-blockdevice")); - $(this).attr("data-disk-name", $(this).attr("data-disk-id-blockdevice")); - $("#helpblock-storagepool-status-disk-attach-disks-identifierwarning-` + pool.status.config.items.index + `-` + pool.id + `").removeClass("hidden").text("One or more disks is missing a " + disk.identifiertext + " identifier."); - } - }); - }); - - $("#btn-storagepool-status-disk-attach-apply-` + pool.status.config.items.index + `-` + pool.id + `").on("click", function () { - $("#spinner-storagepool-status-disk-attach-` + pool.status.config.items.index + `-` + pool.id + `").removeClass("hidden"); - $(this).prop("disabled", true); - - let disk = { - idnew: [] - }; - let modal = { - name: "", - id: "" - }; - let pool = { - force: false - }; - let validation = { - disks: false - }; - - $("#listgroup-storagepool-status-disk-attach-disks-` + pool.status.config.items.index + `-` + pool.id + ` input[name='checkbox-storagepool-status-disk-attach-disks-` + pool.status.config.items.index + `-` + pool.id + `']:checked").map(function () { - disk.idnew.push($(this).attr("data-disk-name")); - }); - - if (disk.idnew.length != 1) { - $("#helpblock-storagepool-status-disk-attach-disks-` + pool.status.config.items.index + `-` + pool.id + `").removeClass("hidden").text("One disk is needed."); - - validation.disks = false; - } else { - $("#validationwrapper-storagepool-status-disk-attach-disks-` + pool.status.config.items.index + `-` + pool.id + `").removeClass("has-error"); - $("#helpblock-storagepool-status-disk-attach-disks-` + pool.status.config.items.index + `-` + pool.id + `").removeClass("hidden").text(""); - - validation.disks = true; - } - - if (!validation.disks) { - $("#validationwrapper-storagepool-status-disk-attach-disks-` + pool.status.config.items.index + `-` + pool.id + `").addClass("has-error"); - - $("#spinner-storagepool-status-disk-attach-` + pool.status.config.items.index + `-` + pool.id + `").addClass("hidden"); - $(this).prop("disabled", false); - } - - if (validation.disks) { - modal.name = "storagepool-status-disk-attach"; - modal.id = "` + pool.status.config.items.index + `-` + pool.id + `"; - - pool.force = $("#switch-storagepool-status-disk-attach-force-` + pool.status.config.items.index + `-` + pool.id + ` input").prop("checked"); - - $("[id^=btn-storagepool-status-dropdown-][id$=` + pool.id + `]").addClass("disabled"); - $("#spinner-storagepool-status-` + pool.status.config.items.index + `-` + pool.id + `").removeClass("hidden"); - - FnStoragePoolDiskAttach({ name: "` + pool.name + `", id: "` + pool.id + `", force: pool.force }, { id: "` + virtualdevice.id + `", disk: ` + virtualdevice.disk + ` }, { idnew: disk.idnew }, { name: modal.name, id: modal.id }); - } - }); - - $("#dropdown-storagepool-status-disk-attach-disks-identifier-` + pool.status.config.items.index + `-` + pool.id + `").on("click", "li a", function () { - $("#btnspan-storagepool-status-disk-attach-disks-identifier-` + pool.status.config.items.index + `-` + pool.id + `").text($(this).text()).attr("data-field-value", $(this).parent().attr("value")); - $(this).parent().siblings().removeClass("active"); - $(this).parent().addClass("active"); - - $("#helpblock-storagepool-status-disk-attach-disks-identifierwarning-` + pool.status.config.items.index + `-` + pool.id + `").addClass("hidden").text(""); - ` + (zfsmanager.zfs.warnings.nvmevdev ? `$("#helpblock-storagepool-status-disk-attach-disks-identifierwarningzfs-` + pool.status.config.items.index + `-` + pool.id + `").addClass("hidden");` : ``) + ` - - let disk = { - identifier: $(this).parent().attr("value"), - identifiertext: $(this).parent().text() - }; - - $("#listgroup-storagepool-status-disk-attach-disks-` + pool.status.config.items.index + `-` + pool.id + ` input[name='checkbox-storagepool-status-disk-attach-disks-` + pool.status.config.items.index + `-` + pool.id + `']").map(function () { - if ($(this).attr("data-disk-id-" + disk.identifier)) { - $(this).next().find(".select-ct-disk-row-id").text((disk.identifier == "blockdevice" ? "/dev/" : "") + $(this).attr("data-disk-id-" + disk.identifier)); - $(this).attr("data-disk-name", $(this).attr("data-disk-id-" + disk.identifier)); - } else { - $(this).next().find(".select-ct-disk-row-id").text("/dev/" + $(this).attr("data-disk-id-blockdevice")); - $(this).attr("data-disk-name", $(this).attr("data-disk-id-blockdevice")); - $("#helpblock-storagepool-status-disk-attach-disks-identifierwarning-` + pool.status.config.items.index + `-` + pool.id + `").removeClass("hidden").text("One or more disks is missing a " + disk.identifiertext + " identifier."); - - ` + (zfsmanager.zfs.warnings.nvmevdev ? ` - if (disk.identifier == "vdev" && /^nvme/gi.test($(this).attr("data-disk-id-blockdevice"))) { - $("#helpblock-storagepool-status-disk-attach-disks-identifierwarningzfs-` + pool.status.config.items.index + `-` + pool.id + `").removeClass("hidden"); - } - ` : ``) + ` - } - }); - }); - \x3C/script> - `; - - modal.id.empty().append(modal.content); -} - -function FnModalStatusDiskClear(pool = { name, id, status: { config: { items: { index: 0 } } } }, disk = { id }) { - let modal = { - window: "" - }; - - modal.window = ` - - - \x3Cscript nonce="1t55lZ7tzuKTreHVNwE66Ox32Mc="> - $("#btn-storagepool-status-disk-clear-` + pool.status.config.items.index + `-` + pool.id + `").on("click", function () { - FnStoragePoolRefreshAutoDisable({ name: "` + pool.name + `", id: "` + pool.id + `" }); - FnModalStatusDiskClearContent({ name: "` + pool.name + `", id: "` + pool.id + `", status: { config: { items: { index: ` + pool.status.config.items.index + ` } } } }, { id: "` + disk.id + `" }, { id: $("#modal-storagepool-status-disk-clear-` + pool.status.config.items.index + `-` + pool.id + `") }); - }); - \x3C/script> - `; - - $("#modals-storagepool-status-" + pool.id).append(modal.window); -} - -function FnModalStatusDiskClearContent(pool = { name, id, status: { config: { items: { index: 0 } } } }, disk = { id }, modal = { id }) { - modal.content = ` - - - \x3Cscript nonce="1t55lZ7tzuKTreHVNwE66Ox32Mc="> - $("#btn-storagepool-status-disk-clear-apply-` + pool.status.config.items.index + `-` + pool.id + `").on("click", function () { - $("#spinner-storagepool-status-disk-clear-` + pool.status.config.items.index + `-` + pool.id + `").removeClass("hidden"); - $(this).prop("disabled", true); - - let modal = { - name: "storagepool-status-disk-clear", - id: "` + pool.status.config.items.index + `-` + pool.id + `" - }; - - $("[id^=btn-storagepool-status-dropdown-][id$=` + pool.id + `]").addClass("disabled"); - $("#spinner-storagepool-status-` + pool.status.config.items.index + `-` + pool.id + `").removeClass("hidden"); - - FnStoragePoolDiskClear({ name: "` + pool.name + `", id: "` + pool.id + `" }, { id: "` + disk.id + `" }, { name: modal.name, id: modal.id }); - }); - \x3C/script> - `; - - modal.id.empty().append(modal.content); -} - -function FnModalStatusDiskDetach(pool = { name, id, status: { config: { items: { index: 0 } } } }, disk = { id }) { - let modal = { - window: "" - }; - - modal.window = ` - - - \x3Cscript nonce="1t55lZ7tzuKTreHVNwE66Ox32Mc="> - $("#btn-storagepool-status-disk-detach-` + pool.status.config.items.index + `-` + pool.id + `").on("click", function () { - FnStoragePoolRefreshAutoDisable({ name: "` + pool.name + `", id: "` + pool.id + `" }); - FnModalStatusDiskDetachContent({ name: "` + pool.name + `", id: "` + pool.id + `", status: { config: { items: { index: ` + pool.status.config.items.index + ` } } } }, { id: "` + disk.id + `" }, { id: $("#modal-storagepool-status-disk-detach-` + pool.status.config.items.index + `-` + pool.id + `") }); - }); - \x3C/script> - `; - - $("#modals-storagepool-status-" + pool.id).append(modal.window); -} - -function FnModalStatusDiskDetachContent(pool = { name, id, status: { config: { items: { index: 0 } } } }, disk = { id }, modal = { id }) { - modal.content = ` - - - \x3Cscript nonce="1t55lZ7tzuKTreHVNwE66Ox32Mc="> - $("#btn-storagepool-status-disk-detach-apply-` + pool.status.config.items.index + `-` + pool.id + `").on("click", function () { - $("#spinner-storagepool-status-disk-detach-` + pool.status.config.items.index + `-` + pool.id + `").removeClass("hidden"); - $(this).prop("disabled", true); - - let disk = { - labelclear: $("#switch-storagepool-status-disk-detach-labelclear-` + pool.status.config.items.index + `-` + pool.id + ` input").prop("checked") - }; - let modal = { - name: "storagepool-status-disk-detach", - id: "` + pool.status.config.items.index + `-` + pool.id + `" - }; - - $("[id^=btn-storagepool-status-dropdown-][id$=` + pool.id + `]").addClass("disabled"); - $("#spinner-storagepool-status-` + pool.status.config.items.index + `-` + pool.id + `").removeClass("hidden"); - - FnStoragePoolDiskDetach({ name: "` + pool.name + `", id: "` + pool.id + `"}, { id: "` + disk.id + `", labelclear: disk.labelclear }, { name: modal.name, id: modal.id }); - }); - \x3C/script> - `; - - modal.id.empty().append(modal.content); -} - -function FnModalStatusDiskOffline(pool = { name, id, status: { config: { items: { index: 0 } } } }, disk = { id }) { - let modal = { - window: "" - }; - - modal.window = ` - - - \x3Cscript nonce="1t55lZ7tzuKTreHVNwE66Ox32Mc="> - $("#btn-storagepool-status-disk-offline-` + pool.status.config.items.index + `-` + pool.id + `").on("click", function () { - FnStoragePoolRefreshAutoDisable({ name: "` + pool.name + `", id: "` + pool.id + `" }); - FnModalStatusDiskOfflineContent({ name: "` + pool.name + `", id: "` + pool.id + `", status: { config: { items: { index: ` + pool.status.config.items.index + ` } } } }, { id: "` + disk.id + `" }, { id: $("#modal-storagepool-status-disk-offline-` + pool.status.config.items.index + `-` + pool.id + `") }); - }); - \x3C/script> - `; - - $("#modals-storagepool-status-" + pool.id).append(modal.window); -} - -function FnModalStatusDiskOfflineContent(pool = { name, id, status: { config: { items: { index: 0 } } } }, disk = { id }, modal = { id }) { - modal.content = ` - - - \x3Cscript nonce="1t55lZ7tzuKTreHVNwE66Ox32Mc="> - $("#btn-storagepool-status-disk-offline-apply-` + pool.status.config.items.index + `-` + pool.id + `").on("click", function () { - $("#spinner-storagepool-status-disk-offline-` + pool.status.config.items.index + `-` + pool.id + `").removeClass("hidden"); - $(this).prop("disabled", true); - - let disk = { - force: $("#switch-storagepool-status-disk-offline-force-` + pool.status.config.items.index + `-` + pool.id + ` input").prop("checked"), - temporary: $("#switch-storagepool-status-disk-offline-temporary-` + pool.status.config.items.index + `-` + pool.id + ` input").prop("checked") - }; - let modal = { - name: "storagepool-status-disk-offline", - id: "` + pool.status.config.items.index + `-` + pool.id + `" - }; - - $("[id^=btn-storagepool-status-dropdown-][id$=` + pool.id + `]").addClass("disabled"); - $("#spinner-storagepool-status-` + pool.status.config.items.index + `-` + pool.id + `").removeClass("hidden"); - - FnStoragePoolDiskOffline({ name: "` + pool.name + `", id: "` + pool.id + `" }, { id: "` + disk.id + `", force: disk.force, temporary: disk.temporary }, { name: modal.name, id: modal.id }); - }); - \x3C/script> - `; - - modal.id.empty().append(modal.content); -} - -function FnModalStatusDiskOnline(pool = { name, id, status: { config: { items: { index: 0 } } } }, disk = { id }) { - let modal = { - window: "" - }; - - modal.window = ` - - - \x3Cscript nonce="1t55lZ7tzuKTreHVNwE66Ox32Mc="> - $("#btn-storagepool-status-disk-online-` + pool.status.config.items.index + `-` + pool.id + `").on("click", function () { - FnStoragePoolRefreshAutoDisable({ name: "` + pool.name + `", id: "` + pool.id + `" }); - FnModalStatusDiskOnlineContent({ name: "` + pool.name + `", id: "` + pool.id + `", status: { config: { items: { index: ` + pool.status.config.items.index + ` } } } }, { id: "` + disk.id + `" }, { id: $("#modal-storagepool-status-disk-online-` + pool.status.config.items.index + `-` + pool.id + `") }); - }); - \x3C/script> - `; - - $("#modals-storagepool-status-" + pool.id).append(modal.window); - -} - -function FnModalStatusDiskOnlineContent(pool = { name, id, status: { config: { items: { index: 0 } } } }, disk = { id }, modal = { id }) { - modal.content = ` - - - \x3Cscript nonce="1t55lZ7tzuKTreHVNwE66Ox32Mc="> - $("#btn-storagepool-status-disk-online-apply-` + pool.status.config.items.index + `-` + pool.id + `").on("click", function () { - $("#spinner-storagepool-status-disk-online-` + pool.status.config.items.index + `-` + pool.id + `").removeClass("hidden"); - $(this).prop("disabled", true); - - let disk = { - expand: $("#switch-storagepool-status-disk-online-expand-` + pool.status.config.items.index + `-` + pool.id + ` input").prop("checked") - }; - let modal = { - name: "storagepool-status-disk-online", - id: "` + pool.status.config.items.index + `-` + pool.id + `" - }; - let pool = { - scrub: $("#switch-storagepool-status-disk-online-scrub-` + pool.status.config.items.index + `-` + pool.id + ` input").prop("checked") - }; - - $("[id^=btn-storagepool-status-dropdown-][id$=` + pool.id + `]").addClass("disabled"); - $("#spinner-storagepool-status-` + pool.status.config.items.index + `-` + pool.id + `").removeClass("hidden"); - - FnStoragePoolDiskOnline({ name: "` + pool.name + `", id: "` + pool.id + `", scrub: pool.scrub }, { id: "` + disk.id + `", expand: disk.expand }, { name: modal.name, id: modal.id }); - }); - \x3C/script> - `; - - modal.id.empty().append(modal.content); -} - -function FnModalStatusDiskReplace(pool = { name, id, status: { config: { items: { index: 0 } } } }, disk = { id }) { - let modal = { - window: "" - }; - - modal.window = ` - - - \x3Cscript nonce="1t55lZ7tzuKTreHVNwE66Ox32Mc="> - $("#btn-storagepool-status-disk-replace-` + pool.status.config.items.index + `-` + pool.id + `").on("click", function () { - FnStoragePoolRefreshAutoDisable({ name: "` + pool.name + `", id: "` + pool.id + `" }); - FnModalStatusDiskReplaceContent({ name: "` + pool.name + `", id: "` + pool.id + `", status: { config: { items: { index: ` + pool.status.config.items.index + ` } } } }, { id: "` + disk.id + `" }, { id: $("#modal-storagepool-status-disk-replace-` + pool.status.config.items.index + `-` + pool.id + `") }); - FnDisksAvailableGet({ name: "storagepool-status-disk-replace-disks", id: "` + pool.status.config.items.index + `-` + pool.id + `", default: true }); - }); - \x3C/script> - `; - - $("#modals-storagepool-status-" + pool.id).append(modal.window); -} - -function FnModalStatusDiskReplaceContent(pool = { name, id, status: { config: { items: { index: 0 } } } }, disk = { id }, modal = { id }) { - modal.content = ` - - - \x3Cscript nonce="1t55lZ7tzuKTreHVNwE66Ox32Mc="> - $("#switch-storagepool-status-disk-replace-disks-wwn-` + pool.status.config.items.index + `-` + pool.id + ` input").on("click", function () { - $("#btnspan-storagepool-status-disk-replace-disks-identifier-` + pool.status.config.items.index + `-` + pool.id + `").text("Block Device"); - $("#dropdown-storagepool-status-disk-replace-disks-identifier-` + pool.status.config.items.index + `-` + pool.id + ` li").siblings().removeClass("active"); - $("#dropdown-storagepool-status-disk-replace-disks-identifier-` + pool.status.config.items.index + `-` + pool.id + ` li[value='blockdevice']").addClass("active"); - $("#helpblock-storagepool-status-disk-replace-disks-identifierwarning-` + pool.status.config.items.index + `-` + pool.id + `").addClass("hidden").text(""); - ` + (zfsmanager.zfs.warnings.nvmevdev ? `$("#helpblock-storagepool-status-disk-replace-disks-identifierwarningzfs-` + pool.status.config.items.index + `-` + pool.id + `").addClass("hidden");` : ``) + ` - - let disk = { - identifier: ($(this).prop("checked") ? "wwn" : "blockdevice"), - identifiertext: ($(this).prop("checked") ? "WWN" : "Block Device") - }; - - if ($(this).prop("checked")) { - $("#controllabel-storagepool-status-disk-replace-disks-identifier-` + pool.status.config.items.index + `-` + pool.id + `").addClass("hidden"); - $("#validationwrapper-storagepool-status-disk-replace-disks-identifier-` + pool.status.config.items.index + `-` + pool.id + `").addClass("hidden"); - } else { - $("#controllabel-storagepool-status-disk-replace-disks-identifier-` + pool.status.config.items.index + `-` + pool.id + `").removeClass("hidden"); - $("#validationwrapper-storagepool-status-disk-replace-disks-identifier-` + pool.status.config.items.index + `-` + pool.id + `").removeClass("hidden"); - } - - $("#listgroup-storagepool-status-disk-replace-disks-` + pool.status.config.items.index + `-` + pool.id + ` input[name='checkbox-storagepool-status-disk-replace-disks-` + pool.status.config.items.index + `-` + pool.id + `']").map(function () { - if ($(this).attr("data-disk-id-" + disk.identifier)) { - $(this).next().find(".select-ct-disk-row-id").text((disk.identifier == "blockdevice" ? "/dev/" : "") + $(this).attr("data-disk-id-" + disk.identifier)); - $(this).attr("data-disk-name", $(this).attr("data-disk-id-" + disk.identifier)); - } else { - $(this).next().find(".select-ct-disk-row-id").text("/dev/" + $(this).attr("data-disk-id-blockdevice")); - $(this).attr("data-disk-name", $(this).attr("data-disk-id-blockdevice")); - $("#helpblock-storagepool-status-disk-replace-disks-identifierwarning-` + pool.status.config.items.index + `-` + pool.id + `").removeClass("hidden").text("One or more disks is missing a " + disk.identifiertext + " identifier."); - } - }); - }); - - $("#btn-storagepool-status-disk-replace-apply-` + pool.status.config.items.index + `-` + pool.id + `").on("click", function () { - $("#spinner-storagepool-status-disk-replace-` + pool.status.config.items.index + `-` + pool.id + `").removeClass("hidden"); - $(this).prop("disabled", true); - - let disk = { - idnew: [] - }; - let modal = { - name: "", - id: "" - }; - let pool = { - force: false - }; - let validation = { - disks: false - }; - - $("#listgroup-storagepool-status-disk-replace-disks-` + pool.status.config.items.index + `-` + pool.id + ` input[name='checkbox-storagepool-status-disk-replace-disks-` + pool.status.config.items.index + `-` + pool.id + `']:checked").map(function () { - disk.idnew.push($(this).attr("data-disk-name")); - }); - - if (disk.idnew.length != 1) { - $("#helpblock-storagepool-status-disk-replace-disks-` + pool.status.config.items.index + `-` + pool.id + `").removeClass("hidden").text("One disk is needed."); - - validation.disks = false; - } else { - $("#validationwrapper-storagepool-status-disk-replace-disks-` + pool.status.config.items.index + `-` + pool.id + `").removeClass("has-error"); - $("#helpblock-storagepool-status-disk-replace-disks-` + pool.status.config.items.index + `-` + pool.id + `").removeClass("hidden").text(""); - - validation.disks = true; - } - - if (!validation.disks) { - $("#validationwrapper-storagepool-status-disk-replace-disks-` + pool.status.config.items.index + `-` + pool.id + `").addClass("has-error"); - - $("#spinner-storagepool-status-disk-replace-` + pool.status.config.items.index + `-` + pool.id + `").addClass("hidden"); - $(this).prop("disabled", false); - } - - if (validation.disks) { - modal.name = "storagepool-status-disk-replace"; - modal.id = "` + pool.status.config.items.index + `-` + pool.id + `"; - - pool.force = $("#switch-storagepool-status-disk-replace-force-` + pool.status.config.items.index + `-` + pool.id + ` input").prop("checked"); - - $("[id^=btn-storagepool-status-dropdown-][id$=` + pool.id + `]").addClass("disabled"); - $("#spinner-storagepool-status-` + pool.status.config.items.index + `-` + pool.id + `").removeClass("hidden"); - - FnStoragePoolDiskReplace({ name: "` + pool.name + `", id: "` + pool.id + `", force: pool.force }, { id: "` + disk.id + `", idnew: disk.idnew }, { name: modal.name, id: modal.id }); - } - }); - - $("#dropdown-storagepool-status-disk-replace-disks-identifier-` + pool.status.config.items.index + `-` + pool.id + `").on("click", "li a", function () { - $("#btnspan-storagepool-status-disk-replace-disks-identifier-` + pool.status.config.items.index + `-` + pool.id + `").text($(this).text()).attr("data-field-value", $(this).parent().attr("value")); - $(this).parent().siblings().removeClass("active"); - $(this).parent().addClass("active"); - - $("#helpblock-storagepool-status-disk-replace-disks-identifierwarning-` + pool.status.config.items.index + `-` + pool.id + `").addClass("hidden").text(""); - ` + (zfsmanager.zfs.warnings.nvmevdev ? `$("#helpblock-storagepool-status-disk-replace-disks-identifierwarningzfs-` + pool.status.config.items.index + `-` + pool.id + `").addClass("hidden");` : ``) + ` - - let disk = { - identifier: $(this).parent().attr("value"), - identifiertext: $(this).parent().text() - }; - - $("#listgroup-storagepool-status-disk-replace-disks-` + pool.status.config.items.index + `-` + pool.id + ` input[name='checkbox-storagepool-status-disk-replace-disks-` + pool.status.config.items.index + `-` + pool.id + `']").map(function () { - if ($(this).attr("data-disk-id-" + disk.identifier)) { - $(this).next().find(".select-ct-disk-row-id").text((disk.identifier == "blockdevice" ? "/dev/" : "") + $(this).attr("data-disk-id-" + disk.identifier)); - $(this).attr("data-disk-name", $(this).attr("data-disk-id-" + disk.identifier)); - } else { - $(this).next().find(".select-ct-disk-row-id").text("/dev/" + $(this).attr("data-disk-id-blockdevice")); - $(this).attr("data-disk-name", $(this).attr("data-disk-id-blockdevice")); - $("#helpblock-storagepool-status-disk-replace-disks-identifierwarning-` + pool.status.config.items.index + `-` + pool.id + `").removeClass("hidden").text("One or more disks is missing a " + disk.identifiertext + " identifier."); - - ` + (zfsmanager.zfs.warnings.nvmevdev ? ` - if (disk.identifier == "vdev" && /^nvme/gi.test($(this).attr("data-disk-id-blockdevice"))) { - $("#helpblock-storagepool-status-disk-replace-disks-identifierwarningzfs-` + pool.status.config.items.index + `-` + pool.id + `").removeClass("hidden"); - } - ` : ``) + ` - } - }); - }); - \x3C/script> - `; - - modal.id.empty().append(modal.content); -} - -function FnModalStatusDiskTrimStart(pool = { name, id, status: { config: { items: { index: 0 } } } }, disk = { id }) { - let modal = { - window: "" - }; - - modal.window = ` - - - \x3Cscript nonce="1t55lZ7tzuKTreHVNwE66Ox32Mc="> - $("#btn-storagepool-status-disk-trim-start-` + pool.status.config.items.index + `-` + pool.id + `").on("click", function () { - FnStoragePoolRefreshAutoDisable({ name: "` + pool.name + `", id: "` + pool.id + `" }); - FnModalStatusDiskTrimStartContent({ name: "` + pool.name + `", id: "` + pool.id + `", status: { config: { items: { index: ` + pool.status.config.items.index + ` } } } }, { id: "` + disk.id + `" }, { id: $("#modal-storagepool-status-disk-trim-start-` + pool.status.config.items.index + `-` + pool.id + `") }); - }); - \x3C/script> - `; - - $("#modals-storagepool-status-" + pool.id).append(modal.window); -} - -function FnModalStatusDiskTrimStartContent(pool = { name, id, status: { config: { items: { index: 0 } } } }, disk = { id }, modal = { id }) { - modal.content = ` - - - \x3Cscript nonce="1t55lZ7tzuKTreHVNwE66Ox32Mc="> - $("#btn-storagepool-status-disk-trim-start-apply-` + pool.status.config.items.index + `-` + pool.id + `").on("click", function () { - $("#spinner-storagepool-status-disk-trim-start-` + pool.status.config.items.index + `-` + pool.id + `").removeClass("hidden"); - $(this).prop("disabled", true); - - let modal = { - name: "storagepool-status-disk-trim-start", - id: "` + pool.status.config.items.index + `-` + pool.id + `" - }; - let trim = { - secure: $("#switch-storagepool-status-disk-trim-start-secure-` + pool.status.config.items.index + `-` + pool.id + ` input").prop("checked") - }; - - $("[id^=btn-storagepool-status-dropdown-][id$=` + pool.id + `]").addClass("disabled"); - $("#spinner-storagepool-status-` + pool.status.config.items.index + `-` + pool.id + `").removeClass("hidden"); - - FnStoragePoolTrimStart({ name: "` + pool.name + `", id: "` + pool.id + `" }, { id: "` + disk.id + `" }, { resume: false, secure: trim.secure }, { name: modal.name, id: modal.id }); - }); - \x3C/script> - `; - - modal.id.empty().append(modal.content); -} - -function FnModalStatusStoragePoolClear(pool = { name, id, status: { config: { items: { index: 0 } } } }) { - let modal = { - window: "" - }; - - modal.window = ` - - - \x3Cscript nonce="1t55lZ7tzuKTreHVNwE66Ox32Mc="> - $("#btn-storagepool-status-clear-` + pool.status.config.items.index + `-` + pool.id + `").on("click", function () { - FnStoragePoolRefreshAutoDisable({ name: "` + pool.name + `", id: "` + pool.id + `" }); - FnModalStatusStoragePoolClearContent({ name: "` + pool.name + `", id: "` + pool.id + `", status: { config: { items: { index: ` + pool.status.config.items.index + ` } } } }, { id: $("#modal-storagepool-status-clear-` + pool.status.config.items.index + `-` + pool.id + `") }); - }); - \x3C/script> - `; - - $("#modals-storagepool-status-" + pool.id).append(modal.window); -} - -function FnModalStatusStoragePoolClearContent(pool = { name, id, status: { config: { items: { index: 0 } } } }, modal = { id }) { - modal.content = ` - - - \x3Cscript nonce="1t55lZ7tzuKTreHVNwE66Ox32Mc="> - $("#btn-storagepool-status-clear-apply-` + pool.status.config.items.index + `-` + pool.id + `").on("click", function () { - $("#spinner-storagepool-status-clear-` + pool.status.config.items.index + `-` + pool.id + `").removeClass("hidden"); - $(this).prop("disabled", true); - - let modal = { - name: "storagepool-status-clear", - id: "` + pool.status.config.items.index + `-` + pool.id + `" - }; - - $("[id^=btn-storagepool-status-dropdown-][id$=` + pool.id + `]").addClass("disabled"); - $("#spinner-storagepool-status-` + pool.status.config.items.index + `-` + pool.id + `").removeClass("hidden"); - - FnStoragePoolClear({ name: "` + pool.name + `", id: "` + pool.id + `" }, { name: modal.name, id: modal.id }); - }); - \x3C/script> - `; - - modal.id.empty().append(modal.content); -} - -function FnModalStatusStoragePoolRegenerateGuid(pool = { name, id, guid, status: { config: { items: { index: 0 } } } }) { - let modal = { - window: "" - }; - - modal.window = ` - - - \x3Cscript nonce="1t55lZ7tzuKTreHVNwE66Ox32Mc="> - $("#btn-storagepool-status-regenerateguid-` + pool.status.config.items.index + `-` + pool.id + `").on("click", function () { - FnStoragePoolRefreshAutoDisable({ name: "` + pool.name + `", id: "` + pool.id + `" }); - FnModalStatusStoragePoolRegenerateGuidContent({ name: "` + pool.name + `", id: "` + pool.id + `", guid: "` + pool.guid + `", status: { config: { items: { index: ` + pool.status.config.items.index + ` } } } }, { id: $("#modal-storagepool-status-regenerateguid-` + pool.status.config.items.index + `-` + pool.id + `") }); - }); - \x3C/script> - `; - - $("#modals-storagepool-status-" + pool.id).append(modal.window); -} - -function FnModalStatusStoragePoolRegenerateGuidContent(pool = { name, id, guid, status: { config: { items: { index: 0 } } } }, modal = { id }) { - modal.content = ` - - - \x3Cscript nonce="1t55lZ7tzuKTreHVNwE66Ox32Mc="> - $("#btn-storagepool-status-regenerateguid-apply-` + pool.status.config.items.index + `-` + pool.id + `").on("click", function () { - $("#spinner-storagepool-status-regenerateguid-` + pool.status.config.items.index + `-` + pool.id + `").removeClass("hidden"); - $(this).prop("disabled", true); - - let modal = { - name: "storagepool-status-regenerateguid", - id: "` + pool.status.config.items.index + `-` + pool.id + `" - }; - - $("[id^=btn-storagepool-status-dropdown-][id$=` + pool.id + `]").addClass("disabled"); - $("#spinner-storagepool-status-` + pool.status.config.items.index + `-` + pool.id + `").removeClass("hidden"); - - FnStoragePoolRegenerateGuid({ name: "` + pool.name + `", id: "` + pool.id + `" }, { name: modal.name, id: modal.id }); - }); - \x3C/script> - `; - - modal.id.empty().append(modal.content); -} - -function FnModalStatusStoragePoolResilver(pool = { name, id, status: { config: { items: { index: 0 } }, resilver: { started: false } } }) { - let modal = { - window: "" - }; - - modal.window = ` - - - \x3Cscript nonce="1t55lZ7tzuKTreHVNwE66Ox32Mc="> - $("#btn-storagepool-status-resilver-` + pool.status.config.items.index + `-` + pool.id + `").on("click", function () { - FnStoragePoolRefreshAutoDisable({ name: "` + pool.name + `", id: "` + pool.id + `" }); - FnModalStatusStoragePoolResilverContent({ name: "` + pool.name + `", id: "` + pool.id + `", status: { config: { items: { index: ` + pool.status.config.items.index + ` } }, resilver: { started: ` + pool.status.resilver.started + ` } } }, { id: $("#modal-storagepool-status-resilver-` + pool.status.config.items.index + `-` + pool.id + `") }); - }); - \x3C/script> - `; - - $("#modals-storagepool-status-" + pool.id).append(modal.window); -} - -function FnModalStatusStoragePoolResilverContent(pool = { name, id, status: { config: { items: { index: 0 } }, resilver: { started: false } } }, modal = { id }) { - modal.content = ` - - - \x3Cscript nonce="1t55lZ7tzuKTreHVNwE66Ox32Mc="> - $("#btn-storagepool-status-resilver-apply-` + pool.status.config.items.index + `-` + pool.id + `").on("click", function () { - $("#spinner-storagepool-status-resilver-` + pool.status.config.items.index + `-` + pool.id + `").removeClass("hidden"); - $(this).prop("disabled", true); - - let modal = { - name: "storagepool-status-resilver", - id: "` + pool.status.config.items.index + `-` + pool.id + `" - }; - - $("[id^=btn-storagepool-status-dropdown-][id$=` + pool.id + `]").addClass("disabled"); - $("#spinner-storagepool-status-` + pool.status.config.items.index + `-` + pool.id + `").removeClass("hidden"); - - FnStoragePoolResilver({ name: "` + pool.name + `", id: "` + pool.id + `" }, { name: modal.name, id: modal.id }); - }); - \x3C/script> - `; - - modal.id.empty().append(modal.content); -} - -function FnModalStatusStoragePoolTrimStart(pool = { name, id, autotrim: false, status: { config: { items: { index: 0 } } } }) { - let modal = { - window: "" - }; - - modal.window = ` - - - \x3Cscript nonce="1t55lZ7tzuKTreHVNwE66Ox32Mc="> - $("#btn-storagepool-status-trim-start-` + pool.status.config.items.index + `-` + pool.id + `").on("click", function () { - FnStoragePoolRefreshAutoDisable({ name: "` + pool.name + `", id: "` + pool.id + `" }); - FnModalStatusStoragePoolTrimStartContent({ name: "` + pool.name + `", id: "` + pool.id + `", autotrim: ` + pool.autotrim + `, status: { config: { items: { index: ` + pool.status.config.items.index + ` } } } }, { id: $("#modal-storagepool-status-trim-start-` + pool.status.config.items.index + `-` + pool.id + `") }); - }); - \x3C/script> - `; - - $("#modals-storagepool-status-" + pool.id).append(modal.window); -} - -function FnModalStatusStoragePoolTrimStartContent(pool = { name, id, autotrim: false, status: { config: { items: { index: 0 } } } }, modal = { id }) { - modal.content = ` - - - \x3Cscript nonce="1t55lZ7tzuKTreHVNwE66Ox32Mc="> - $("#btn-storagepool-status-trim-start-apply-` + pool.status.config.items.index + `-` + pool.id + `").on("click", function () { - $("#spinner-storagepool-status-trim-start-` + pool.status.config.items.index + `-` + pool.id + `").removeClass("hidden"); - $(this).prop("disabled", true); - - let modal = { - name: "storagepool-status-trim-start", - id: "` + pool.status.config.items.index + `-` + pool.id + `" - }; - let trim = { - secure: $("#switch-storagepool-status-trim-start-secure-` + pool.status.config.items.index + `-` + pool.id + ` input").prop("checked") - }; - - $("[id^=btn-storagepool-status-dropdown-][id$=` + pool.id + `]").addClass("disabled"); - $("#spinner-storagepool-status-` + pool.status.config.items.index + `-` + pool.id + `").removeClass("hidden"); - - FnStoragePoolTrimStart({ name: "` + pool.name + `", id: "` + pool.id + `" }, { id: null }, { resume: false, secure: trim.secure }, { name: modal.name, id: modal.id }); - }); - \x3C/script> - `; - - modal.id.empty().append(modal.content); -} - -function FnModalStatusStoragePoolUpgrade(pool = { name, id, status: { config: { items: { index: 0 } } }, version }) { - let modal = { - window: "" - }; - - modal.window = ` - - - \x3Cscript nonce="1t55lZ7tzuKTreHVNwE66Ox32Mc="> - $("#btn-storagepool-status-upgrade-` + pool.status.config.items.index + `-` + pool.id + `").on("click", function () { - FnStoragePoolRefreshAutoDisable({ name: "` + pool.name + `", id: "` + pool.id + `" }); - FnModalStatusStoragePoolUpgradeContent({ name: "` + pool.name + `", id: "` + pool.id + `", status: { config: { items: { index: ` + pool.status.config.items.index + ` } } }, version: "` + pool.version + `" }, { id: $("#modal-storagepool-status-upgrade-` + pool.status.config.items.index + `-` + pool.id + `") }); - FnStoragePoolConfigurationFeaturesDisabledGet({ name: "` + pool.name + `", id: "` + pool.id + `" }, { name: "storagepool-status-upgrade", id: "` + pool.status.config.items.index + `-` + pool.id + `" }); - }); - \x3C/script> - `; - - $("#modals-storagepool-status-" + pool.id).append(modal.window); -} - -function FnModalStatusStoragePoolUpgradeContent(pool = { name, id, status: { config: { items: { index: 0 } } }, version }, modal = { id }) { - modal.content = ` - - - \x3Cscript nonce="1t55lZ7tzuKTreHVNwE66Ox32Mc="> - $("#btn-storagepool-status-upgrade-apply-` + pool.status.config.items.index + `-` + pool.id + `").on("click", function () { - $("#spinner-storagepool-status-upgrade-` + pool.status.config.items.index + `-` + pool.id + `").removeClass("hidden"); - $(this).prop("disabled", true); - - let modal = { - name: "storagepool-status-upgrade", - id: "` + pool.status.config.items.index + `-` + pool.id + `" - }; - - $("[id^=btn-storagepool-status-dropdown-][id$=` + pool.id + `]").addClass("disabled"); - $("#spinner-storagepool-status-` + pool.status.config.items.index + `-` + pool.id + `").removeClass("hidden"); - - FnStoragePoolUpgrade({ name: "` + pool.name + `", id: "` + pool.id + `" }, { name: modal.name, id: modal.id }); - }); - \x3C/script> - `; - - modal.id.empty().append(modal.content); -} - -function FnModalStatusVirtualDeviceAdd(pool = { name, id, feature: { allocation_classes: true }, status: { config: { items: { index: 0 } } } }) { - let modal = { - window: "" - }; - - modal.window = ` - - - \x3Cscript nonce="1t55lZ7tzuKTreHVNwE66Ox32Mc="> - $("#btn-storagepool-status-virtualdevice-add-` + pool.status.config.items.index + `-` + pool.id + `").on("click", function () { - FnStoragePoolRefreshAutoDisable({ name: "` + pool.name + `", id: "` + pool.id + `" }); - FnModalStatusVirtualDeviceAddContent({ name: "` + pool.name + `", id: "` + pool.id + `", feature: { allocation_classes: ` + pool.feature.allocation_classes + ` }, status: { config: { items: { index: ` + pool.status.config.items.index + ` } } } }, { id: $("#modal-storagepool-status-virtualdevice-add-` + pool.status.config.items.index + `-` + pool.id + `") }); - FnDisksAvailableGet({ name: "storagepool-status-virtualdevice-add-disks", id: "` + pool.status.config.items.index + `-` + pool.id + `", default: true }); - }); - \x3C/script> - `; - - $("#modals-storagepool-status-" + pool.id).append(modal.window); -} - -function FnModalStatusVirtualDeviceAddContent(pool = { name, id, feature: { allocation_classes: true }, status: { config: { items: { index: 0 } } } }, modal = { id }) { - modal.content = ` - - - \x3Cscript nonce="1t55lZ7tzuKTreHVNwE66Ox32Mc="> - $("#switch-storagepool-status-virtualdevice-add-disks-wwn-` + pool.status.config.items.index + `-` + pool.id + ` input").on("click", function () { - $("#btnspan-storagepool-status-virtualdevice-add-disks-identifier-` + pool.status.config.items.index + `-` + pool.id + `").text("Block Device"); - $("#dropdown-storagepool-status-virtualdevice-add-disks-identifier-` + pool.status.config.items.index + `-` + pool.id + ` li").siblings().removeClass("active"); - $("#dropdown-storagepool-status-virtualdevice-add-disks-identifier-` + pool.status.config.items.index + `-` + pool.id + ` li[value='blockdevice']").addClass("active"); - $("#helpblock-storagepool-status-virtualdevice-add-disks-identifierwarning-` + pool.status.config.items.index + `-` + pool.id + `").addClass("hidden").text(""); - ` + (zfsmanager.zfs.warnings.nvmevdev ? `$("#helpblock-storagepool-status-virtualdevice-add-disks-identifierwarningzfs-` + pool.status.config.items.index + `-` + pool.id + `").addClass("hidden");` : ``) + ` - - let disk = { - identifier: ($(this).prop("checked") ? "wwn" : "blockdevice"), - identifiertext: ($(this).prop("checked") ? "WWN" : "Block Device") - }; - - if ($(this).prop("checked")) { - $("#controllabel-storagepool-status-virtualdevice-add-disks-identifier-` + pool.status.config.items.index + `-` + pool.id + `").addClass("hidden"); - $("#validationwrapper-storagepool-status-virtualdevice-add-disks-identifier-` + pool.status.config.items.index + `-` + pool.id + `").addClass("hidden"); - } else { - $("#controllabel-storagepool-status-virtualdevice-add-disks-identifier-` + pool.status.config.items.index + `-` + pool.id + `").removeClass("hidden"); - $("#validationwrapper-storagepool-status-virtualdevice-add-disks-identifier-` + pool.status.config.items.index + `-` + pool.id + `").removeClass("hidden"); - } - - $("#listgroup-storagepool-status-virtualdevice-add-disks-` + pool.status.config.items.index + `-` + pool.id + ` input[name='checkbox-storagepool-status-virtualdevice-add-disks-` + pool.status.config.items.index + `-` + pool.id + `']").map(function () { - if ($(this).attr("data-disk-id-" + disk.identifier)) { - $(this).next().find(".select-ct-disk-row-id").text((disk.identifier == "blockdevice" ? "/dev/" : "") + $(this).attr("data-disk-id-" + disk.identifier)); - $(this).attr("data-disk-name", $(this).attr("data-disk-id-" + disk.identifier)); - } else { - $(this).next().find(".select-ct-disk-row-id").text("/dev/" + $(this).attr("data-disk-id-blockdevice")); - $(this).attr("data-disk-name", $(this).attr("data-disk-id-blockdevice")); - $("#helpblock-storagepool-status-virtualdevice-add-disks-identifierwarning-` + pool.status.config.items.index + `-` + pool.id + `").removeClass("hidden").text("One or more disks is missing a " + disk.identifiertext + " identifier."); - } - }); - }); - - $("#btn-storagepool-status-virtualdevice-add-apply-` + pool.status.config.items.index + `-` + pool.id + `").on("click", function () { - $("#spinner-storagepool-status-virtualdevice-add-` + pool.status.config.items.index + `-` + pool.id + `").removeClass("hidden"); - $(this).prop("disabled", true); - - let disks = { - id: [] - }; - let pool = { - force: false, - virtualdevice: "" - }; - let modal = { - name: "", - id: "" - }; - let validation = { - disks: false - }; - - $("#listgroup-storagepool-status-virtualdevice-add-disks-` + pool.status.config.items.index + `-` + pool.id + ` input[name='checkbox-storagepool-status-virtualdevice-add-disks-` + pool.status.config.items.index + `-` + pool.id + `']:checked").map(function () { - disks.id.push($(this).attr("data-disk-name")); - }); - - if (disks.id.length < 1 && $("#btnspan-storagepool-status-virtualdevice-add-virtualdevice-` + pool.status.config.items.index + `-` + pool.id + `").attr("data-field-value") == "cache") { - $("#helpblock-storagepool-status-virtualdevice-add-disks-` + pool.status.config.items.index + `-` + pool.id + `").removeClass("hidden").text("One or more disks is needed for Cache."); - - validation.disks = false; - } else if (disks.id.length < 1 && $("#btnspan-storagepool-status-virtualdevice-add-virtualdevice-` + pool.status.config.items.index + `-` + pool.id + `").attr("data-field-value") == "dedup" && !$("#switch-storagepool-status-virtualdevice-add-dedup-mirror-` + pool.status.config.items.index + `-` + pool.id + ` input").prop("checked")) { - $("#helpblock-storagepool-status-virtualdevice-add-disks-` + pool.status.config.items.index + `-` + pool.id + `").removeClass("hidden").text("One or more disks is needed for Dedup."); - - validation.disks = false; - } else if (disks.id.length < 2 && $("#btnspan-storagepool-status-virtualdevice-add-virtualdevice-` + pool.status.config.items.index + `-` + pool.id + `").attr("data-field-value") == "dedup" && $("#switch-storagepool-status-virtualdevice-add-dedup-mirror-` + pool.status.config.items.index + `-` + pool.id + ` input").prop("checked")) { - $("#helpblock-storagepool-status-virtualdevice-add-disks-` + pool.status.config.items.index + `-` + pool.id + `").removeClass("hidden").text("Two or more disks is needed for Dedup (Mirror)."); - - validation.disks = false; - } else if (disks.id.length < 1 && $("#btnspan-storagepool-status-virtualdevice-add-virtualdevice-` + pool.status.config.items.index + `-` + pool.id + `").attr("data-field-value") == "disk") { - $("#helpblock-storagepool-status-virtualdevice-add-disks-` + pool.status.config.items.index + `-` + pool.id + `").removeClass("hidden").text("One or more disks is needed for Disk."); - - validation.disks = false; - } else if (disks.id.length < 1 && $("#btnspan-storagepool-status-virtualdevice-add-virtualdevice-` + pool.status.config.items.index + `-` + pool.id + `").attr("data-field-value") == "log" && !$("#switch-storagepool-status-virtualdevice-add-log-mirror-` + pool.status.config.items.index + `-` + pool.id + ` input").prop("checked")) { - $("#helpblock-storagepool-status-virtualdevice-add-disks-` + pool.status.config.items.index + `-` + pool.id + `").removeClass("hidden").text("One or more disks is needed for Log."); - - validation.disks = false; - } else if (disks.id.length < 2 && $("#btnspan-storagepool-status-virtualdevice-add-virtualdevice-` + pool.status.config.items.index + `-` + pool.id + `").attr("data-field-value") == "log" && $("#switch-storagepool-status-virtualdevice-add-log-mirror-` + pool.status.config.items.index + `-` + pool.id + ` input").prop("checked")) { - $("#helpblock-storagepool-status-virtualdevice-add-disks-` + pool.status.config.items.index + `-` + pool.id + `").removeClass("hidden").text("Two or more disks is needed for Log (Mirror)."); - - validation.disks = false; - } else if (disks.id.length < 2 && $("#btnspan-storagepool-status-virtualdevice-add-virtualdevice-` + pool.status.config.items.index + `-` + pool.id + `").attr("data-field-value") == "mirror") { - $("#helpblock-storagepool-status-virtualdevice-add-disks-` + pool.status.config.items.index + `-` + pool.id + `").removeClass("hidden").text("Two or more disks is needed for Mirror."); - - validation.disks = false; - } else if (disks.id.length < 2 && $("#btnspan-storagepool-status-virtualdevice-add-virtualdevice-` + pool.status.config.items.index + `-` + pool.id + `").attr("data-field-value") == "raidz1") { - $("#helpblock-storagepool-status-virtualdevice-add-disks-` + pool.status.config.items.index + `-` + pool.id + `").removeClass("hidden").text("Two or more disks is needed for RaidZ1."); - - validation.disks = false; - } else if (disks.id.length < 3 && $("#btnspan-storagepool-status-virtualdevice-add-virtualdevice-` + pool.status.config.items.index + `-` + pool.id + `").attr("data-field-value") == "raidz2") { - $("#helpblock-storagepool-status-virtualdevice-add-disks-` + pool.status.config.items.index + `-` + pool.id + `").removeClass("hidden").text("Three or more disks is needed for RaidZ2."); - - validation.disks = false; - } else if (disks.id.length < 4 && $("#btnspan-storagepool-status-virtualdevice-add-virtualdevice-` + pool.status.config.items.index + `-` + pool.id + `").attr("data-field-value") == "raidz3") { - $("#helpblock-storagepool-status-virtualdevice-add-disks-` + pool.status.config.items.index + `-` + pool.id + `").removeClass("hidden").text("Four or more disks is needed for RaidZ3."); - - validation.disks = false; - } else if (disks.id.length < 1 && $("#btnspan-storagepool-status-virtualdevice-add-virtualdevice-` + pool.status.config.items.index + `-` + pool.id + `").attr("data-field-value") == "spare") { - $("#helpblock-storagepool-status-virtualdevice-add-disks-` + pool.status.config.items.index + `-` + pool.id + `").removeClass("hidden").text("One or more disks is needed for Spare."); - - validation.disks = false; - } else if (disks.id.length < 1 && $("#btnspan-storagepool-status-virtualdevice-add-virtualdevice-` + pool.status.config.items.index + `-` + pool.id + `").attr("data-field-value") == "special" && !$("#switch-storagepool-status-virtualdevice-add-special-mirror-` + pool.status.config.items.index + `-` + pool.id + ` input").prop("checked")) { - $("#helpblock-storagepool-status-virtualdevice-add-disks-` + pool.status.config.items.index + `-` + pool.id + `").removeClass("hidden").text("One or more disks is needed for Special."); - - validation.disks = false; - } else if (disks.id.length < 2 && $("#btnspan-storagepool-status-virtualdevice-add-virtualdevice-` + pool.status.config.items.index + `-` + pool.id + `").attr("data-field-value") == "special" && $("#switch-storagepool-status-virtualdevice-add-special-mirror-` + pool.status.config.items.index + `-` + pool.id + ` input").prop("checked")) { - $("#helpblock-storagepool-status-virtualdevice-add-disks-` + pool.status.config.items.index + `-` + pool.id + `").removeClass("hidden").text("Two or more disks is needed for Special (Mirror)."); - - validation.disks = false; - } else { - $("#validationwrapper-storagepool-status-virtualdevice-add-disks-` + pool.status.config.items.index + `-` + pool.id + `").removeClass("has-error"); - $("#helpblock-storagepool-status-virtualdevice-add-disks-` + pool.status.config.items.index + `-` + pool.id + `").removeClass("hidden").text(""); - - validation.disks = true; - } - - if (!validation.disks) { - $("#validationwrapper-storagepool-status-virtualdevice-add-disks-` + pool.status.config.items.index + `-` + pool.id + `").addClass("has-error"); - - $("#spinner-storagepool-status-virtualdevice-add-` + pool.status.config.items.index + `-` + pool.id + `").addClass("hidden"); - $(this).prop("disabled", false); - } - - if (validation.disks) { - modal.name = "storagepool-status-virtualdevice-add"; - modal.id = "` + pool.status.config.items.index + `-` + pool.id + `"; - - pool.force = $("#switch-storagepool-status-virtualdevice-add-force-` + pool.status.config.items.index + `-` + pool.id + ` input").prop("checked"); - pool.virtualdevice = ($("#btnspan-storagepool-status-virtualdevice-add-virtualdevice-` + pool.status.config.items.index + `-` + pool.id + `").attr("data-field-value") != "disk" ? $("#btnspan-storagepool-status-virtualdevice-add-virtualdevice-` + pool.status.config.items.index + `-` + pool.id + `").attr("data-field-value") : ""); - - if ($("#btnspan-storagepool-status-virtualdevice-add-virtualdevice-` + pool.status.config.items.index + `-` + pool.id + `").attr("data-field-value") == "dedup" && $("#switch-storagepool-status-virtualdevice-add-dedup-mirror-` + pool.status.config.items.index + `-` + pool.id + ` input").prop("checked")) { - pool.virtualdevice = "dedup mirror"; - } else if ($("#btnspan-storagepool-status-virtualdevice-add-virtualdevice-` + pool.status.config.items.index + `-` + pool.id + `").attr("data-field-value") == "log" && $("#switch-storagepool-status-virtualdevice-add-log-mirror-` + pool.status.config.items.index + `-` + pool.id + ` input").prop("checked")) { - pool.virtualdevice = "log mirror"; - } else if ($("#btnspan-storagepool-status-virtualdevice-add-virtualdevice-` + pool.status.config.items.index + `-` + pool.id + `").attr("data-field-value") == "special" && $("#switch-storagepool-status-virtualdevice-add-special-mirror-` + pool.status.config.items.index + `-` + pool.id + ` input").prop("checked")) { - pool.virtualdevice = "special mirror"; - } - - $("[id^=btn-storagepool-status-dropdown-][id$=` + pool.id + `]").addClass("disabled"); - $("#spinner-storagepool-status-` + pool.status.config.items.index + `-` + pool.id + `").removeClass("hidden"); - - FnStoragePoolVirtualDeviceAdd({ name: "` + pool.name + `", id: "` + pool.id + `", force: pool.force, virtualdevice: pool.virtualdevice }, { id: disks.id }, { name: modal.name, id: modal.id }); - } - }); - - $("#dropdown-storagepool-status-virtualdevice-add-disks-identifier-` + pool.status.config.items.index + `-` + pool.id + `").on("click", "li a", function () { - $("#btnspan-storagepool-status-virtualdevice-add-disks-identifier-` + pool.status.config.items.index + `-` + pool.id + `").text($(this).text()).attr("data-field-value", $(this).parent().attr("value")); - $(this).parent().siblings().removeClass("active"); - $(this).parent().addClass("active"); - - $("#helpblock-storagepool-status-virtualdevice-add-disks-identifierwarning-` + pool.status.config.items.index + `-` + pool.id + `").addClass("hidden").text(""); - ` + (zfsmanager.zfs.warnings.nvmevdev ? `$("#helpblock-storagepool-status-virtualdevice-add-disks-identifierwarningzfs-` + pool.status.config.items.index + `-` + pool.id + `").addClass("hidden");` : ``) + ` - - let disk = { - identifier: $(this).parent().attr("value"), - identifiertext: $(this).parent().text() - }; - - $("#listgroup-storagepool-status-virtualdevice-add-disks-` + pool.status.config.items.index + `-` + pool.id + ` input[name='checkbox-storagepool-status-virtualdevice-add-disks-` + pool.status.config.items.index + `-` + pool.id + `']").map(function () { - if ($(this).attr("data-disk-id-" + disk.identifier)) { - $(this).next().find(".select-ct-disk-row-id").text((disk.identifier == "blockdevice" ? "/dev/" : "") + $(this).attr("data-disk-id-" + disk.identifier)); - $(this).attr("data-disk-name", $(this).attr("data-disk-id-" + disk.identifier)); - } else { - $(this).next().find(".select-ct-disk-row-id").text("/dev/" + $(this).attr("data-disk-id-blockdevice")); - $(this).attr("data-disk-name", $(this).attr("data-disk-id-blockdevice")); - $("#helpblock-storagepool-status-virtualdevice-add-disks-identifierwarning-` + pool.status.config.items.index + `-` + pool.id + `").removeClass("hidden").text("One or more disks is missing a " + disk.identifiertext + " identifier."); - - - ` + (zfsmanager.zfs.warnings.nvmevdev ? ` - if (disk.identifier == "vdev" && /^nvme/gi.test($(this).attr("data-disk-id-blockdevice"))) { - $("#helpblock-storagepool-status-virtualdevice-add-disks-identifierwarningzfs-` + pool.status.config.items.index + `-` + pool.id + `").removeClass("hidden"); - } - ` : ``) + ` - } - }); - }); - - $("#dropdown-storagepool-status-virtualdevice-add-virtualdevice-` + pool.status.config.items.index + `-` + pool.id + `").on("click", "li a", function () { - $("#btnspan-storagepool-status-virtualdevice-add-virtualdevice-` + pool.status.config.items.index + `-` + pool.id + `").text($(this).text()).attr("data-field-value", $(this).parent().attr("value")); - $(this).parent().siblings().removeClass("active"); - $(this).parent().addClass("active"); - - if ($(this).text() == "Dedup") { - $("#controllabel-storagepool-status-virtualdevice-add-dedup-mirror-` + pool.status.config.items.index + `-` + pool.id + `").removeClass("hidden"); - $("#switch-storagepool-status-virtualdevice-add-dedup-mirror-` + pool.status.config.items.index + `-` + pool.id + `").parent().removeClass("hidden"); - } else { - $("#controllabel-storagepool-status-virtualdevice-add-dedup-mirror-` + pool.status.config.items.index + `-` + pool.id + `").addClass("hidden"); - $("#switch-storagepool-status-virtualdevice-add-dedup-mirror-` + pool.status.config.items.index + `-` + pool.id + `").parent().addClass("hidden"); - if ($("#switch-storagepool-status-virtualdevice-add-dedup-mirror-` + pool.status.config.items.index + `-` + pool.id + ` input").prop("checked")) { - $("#switch-storagepool-status-virtualdevice-add-dedup-mirror-` + pool.status.config.items.index + `-` + pool.id + ` input").click(); - } - } - - if ($(this).text() == "Log") { - $("#controllabel-storagepool-status-virtualdevice-add-log-mirror-` + pool.status.config.items.index + `-` + pool.id + `").removeClass("hidden"); - $("#switch-storagepool-status-virtualdevice-add-log-mirror-` + pool.status.config.items.index + `-` + pool.id + `").parent().removeClass("hidden"); - } else { - $("#controllabel-storagepool-status-virtualdevice-add-log-mirror-` + pool.status.config.items.index + `-` + pool.id + `").addClass("hidden"); - $("#switch-storagepool-status-virtualdevice-add-log-mirror-` + pool.status.config.items.index + `-` + pool.id + `").parent().addClass("hidden"); - if ($("#switch-storagepool-status-virtualdevice-add-log-mirror-` + pool.status.config.items.index + `-` + pool.id + ` input").prop("checked")) { - $("#switch-storagepool-status-virtualdevice-add-log-mirror-` + pool.status.config.items.index + `-` + pool.id + ` input").click(); - } - } - - if ($(this).text() == "Special") { - $("#controllabel-storagepool-status-virtualdevice-add-special-mirror-` + pool.status.config.items.index + `-` + pool.id + `").removeClass("hidden"); - $("#switch-storagepool-status-virtualdevice-add-special-mirror-` + pool.status.config.items.index + `-` + pool.id + `").parent().removeClass("hidden"); - } else { - $("#controllabel-storagepool-status-virtualdevice-add-special-mirror-` + pool.status.config.items.index + `-` + pool.id + `").addClass("hidden"); - $("#switch-storagepool-status-virtualdevice-add-special-mirror-` + pool.status.config.items.index + `-` + pool.id + `").parent().addClass("hidden"); - if ($("#switch-storagepool-status-virtualdevice-add-special-mirror-` + pool.status.config.items.index + `-` + pool.id + ` input").prop("checked")) { - $("#switch-storagepool-status-virtualdevice-add-special-mirror-` + pool.status.config.items.index + `-` + pool.id + ` input").click(); - } - } - }); - \x3C/script> - `; - - modal.id.empty().append(modal.content); -} - -function FnModalStatusVirtualDeviceClear(pool = { name, id, status: { config: { items: { index: 0 } } } }, virtualdevice = { id }) { - let modal = { - window: "" - }; - - modal.window = ` - - - \x3Cscript nonce="1t55lZ7tzuKTreHVNwE66Ox32Mc="> - $("#btn-storagepool-status-virtualdevice-clear-` + pool.status.config.items.index + `-` + pool.id + `").on("click", function () { - FnStoragePoolRefreshAutoDisable({ name: "` + pool.name + `", id: "` + pool.id + `" }); - FnModalStatusVirtualDeviceClearContent({ name: "` + pool.name + `", id: "` + pool.id + `", status: { config: { items: { index: ` + pool.status.config.items.index + ` } } } }, { id: "` + virtualdevice.id + `" }, { id: $("#modal-storagepool-status-virtualdevice-clear-` + pool.status.config.items.index + `-` + pool.id + `") }); - }); - \x3C/script> - `; - - $("#modals-storagepool-status-" + pool.id).append(modal.window); -} - -function FnModalStatusVirtualDeviceClearContent(pool = { name, id, status: { config: { items: { index: 0 } } } }, virtualdevice = { id }, modal = { id }) { - modal.content = ` - - - \x3Cscript nonce="1t55lZ7tzuKTreHVNwE66Ox32Mc="> - $("#btn-storagepool-status-virtualdevice-clear-apply-` + pool.status.config.items.index + `-` + pool.id + `").on("click", function () { - $("#spinner-storagepool-status-virtualdevice-clear-` + pool.status.config.items.index + `-` + pool.id + `").removeClass("hidden"); - $(this).prop("disabled", true); - - let modal = { - name: "storagepool-status-virtualdevice-clear", - id: "` + pool.status.config.items.index + `-` + pool.id + `" - }; - - $("[id^=btn-storagepool-status-dropdown-][id$=` + pool.id + `]").addClass("disabled"); - $("#spinner-storagepool-status-` + pool.status.config.items.index + `-` + pool.id + `").removeClass("hidden"); - - FnStoragePoolVirtualDeviceClear({ name: "` + pool.name + `", id: "` + pool.id + `" }, { id: "` + virtualdevice.id + `" }, { name: modal.name, id: modal.id }); - }); - \x3C/script> - `; - - modal.id.empty().append(modal.content); -} - -function FnModalStatusVirtualDeviceRemove(pool = { name, id, status: { config: { items: { index: 0 } } } }, virtualdevice = { id, disk: false }) { - let modal = { - window: "" - }; - - modal.window = ` - - - \x3Cscript nonce="1t55lZ7tzuKTreHVNwE66Ox32Mc="> - $("#btn-storagepool-status-virtualdevice-remove-` + pool.status.config.items.index + `-` + pool.id + `").on("click", function () { - FnStoragePoolRefreshAutoDisable({ name: "` + pool.name + `", id: "` + pool.id + `" }); - FnModalStatusVirtualDeviceRemoveContent({ name: "` + pool.name + `", id: "` + pool.id + `", status: { config: { items: { index: ` + pool.status.config.items.index + ` } } } }, { id: "` + virtualdevice.id + `", disk: ` + virtualdevice.disk + ` }, { id: $("#modal-storagepool-status-virtualdevice-remove-` + pool.status.config.items.index + `-` + pool.id + `") }); - }); - \x3C/script> - `; - - $("#modals-storagepool-status-" + pool.id).append(modal.window); -} - -function FnModalStatusVirtualDeviceRemoveContent(pool = { name, id, status: { config: { items: { index: 0 } } } }, virtualdevice = { id, disk: false }, modal = { id }) { - modal.content = ` - - - \x3Cscript nonce="1t55lZ7tzuKTreHVNwE66Ox32Mc="> - $("#btn-storagepool-status-virtualdevice-remove-apply-` + pool.status.config.items.index + `-` + pool.id + `").on("click", function () { - $("#spinner-storagepool-status-virtualdevice-remove-` + pool.status.config.items.index + `-` + pool.id + `").removeClass("hidden"); - $(this).prop("disabled", true); - - let virtualdevice = { - labelclear: ` + (virtualdevice.disk ? `$("#switch-storagepool-status-virtualdevice-remove-labelclear-` + pool.status.config.items.index + `-` + pool.id + ` input").prop("checked")` : false) + ` - }; - let modal = { - name: "storagepool-status-virtualdevice-remove", - id: "` + pool.status.config.items.index + `-` + pool.id + `" - }; - - $("[id^=btn-storagepool-status-dropdown-][id$=` + pool.id + `]").addClass("disabled"); - $("#spinner-storagepool-status-` + pool.status.config.items.index + `-` + pool.id + `").removeClass("hidden"); - - FnStoragePoolVirtualDeviceRemove({ name: "` + pool.name + `", id: "` + pool.id + `"} , { id: "` + virtualdevice.id + `", labelclear: virtualdevice.labelclear }, { name: modal.name, id: modal.id }); - }); - \x3C/script> - `; - - modal.id.empty().append(modal.content); -} - -//#endregion \ No newline at end of file