diff --git a/changes/31671-gigs-all-disk-space b/changes/31671-gigs-all-disk-space
new file mode 100644
index 000000000000..cff6cdddacbc
--- /dev/null
+++ b/changes/31671-gigs-all-disk-space
@@ -0,0 +1 @@
+- Add `gigs_all_disk_space` vital collection, storage, service, and UI rendering for Linux hosts
diff --git a/cmd/fleetctl/fleetctl/testdata/expectedHostDetailResponseJson.json b/cmd/fleetctl/fleetctl/testdata/expectedHostDetailResponseJson.json
index 23ca190697d8..34fbce3e17fb 100644
--- a/cmd/fleetctl/fleetctl/testdata/expectedHostDetailResponseJson.json
+++ b/cmd/fleetctl/fleetctl/testdata/expectedHostDetailResponseJson.json
@@ -63,6 +63,7 @@
"gigs_disk_space_available": 0,
"percent_disk_space_available": 0,
"gigs_total_disk_space": 0,
+ "gigs_all_disk_space": null,
"issues": {
"total_issues_count": 0,
"failing_policies_count": 0
diff --git a/cmd/fleetctl/fleetctl/testdata/expectedHostDetailResponseYaml.yml b/cmd/fleetctl/fleetctl/testdata/expectedHostDetailResponseYaml.yml
index b9b0da2c5536..8a4403ceab5a 100644
--- a/cmd/fleetctl/fleetctl/testdata/expectedHostDetailResponseYaml.yml
+++ b/cmd/fleetctl/fleetctl/testdata/expectedHostDetailResponseYaml.yml
@@ -18,6 +18,7 @@ spec:
fleet_desktop_version: null
gigs_disk_space_available: 0
gigs_total_disk_space: 0
+ gigs_all_disk_space: null
hardware_model: ""
hardware_serial: ""
hardware_vendor: ""
diff --git a/cmd/fleetctl/fleetctl/testdata/expectedListHostsJson.json b/cmd/fleetctl/fleetctl/testdata/expectedListHostsJson.json
index bd5e3a46195c..ecf7f79e4d3b 100644
--- a/cmd/fleetctl/fleetctl/testdata/expectedListHostsJson.json
+++ b/cmd/fleetctl/fleetctl/testdata/expectedListHostsJson.json
@@ -67,6 +67,7 @@
"gigs_disk_space_available": 0,
"percent_disk_space_available": 0,
"gigs_total_disk_space": 0,
+ "gigs_all_disk_space": null,
"issues": {
"total_issues_count": 0,
"failing_policies_count": 0
@@ -136,6 +137,7 @@
"gigs_disk_space_available": 0,
"percent_disk_space_available": 0,
"gigs_total_disk_space": 0,
+ "gigs_all_disk_space": null,
"issues": {
"total_issues_count": 0,
"failing_policies_count": 0
diff --git a/cmd/fleetctl/fleetctl/testdata/expectedListHostsMDM.json b/cmd/fleetctl/fleetctl/testdata/expectedListHostsMDM.json
index c0174324b60c..bf35fd976841 100644
--- a/cmd/fleetctl/fleetctl/testdata/expectedListHostsMDM.json
+++ b/cmd/fleetctl/fleetctl/testdata/expectedListHostsMDM.json
@@ -68,6 +68,7 @@
"gigs_disk_space_available": 0,
"percent_disk_space_available": 0,
"gigs_total_disk_space": 0,
+ "gigs_all_disk_space": null,
"issues": {
"total_issues_count": 0,
"failing_policies_count": 0
@@ -137,6 +138,7 @@
"gigs_disk_space_available": 0,
"percent_disk_space_available": 0,
"gigs_total_disk_space": 0,
+ "gigs_all_disk_space": null,
"issues": {
"total_issues_count": 0,
"failing_policies_count": 0
diff --git a/cmd/fleetctl/fleetctl/testdata/expectedListHostsYaml.yml b/cmd/fleetctl/fleetctl/testdata/expectedListHostsYaml.yml
index d511c5f4fadd..c0acff8dc402 100644
--- a/cmd/fleetctl/fleetctl/testdata/expectedListHostsYaml.yml
+++ b/cmd/fleetctl/fleetctl/testdata/expectedListHostsYaml.yml
@@ -23,6 +23,7 @@ spec:
fleet_desktop_version: null
gigs_disk_space_available: 0
gigs_total_disk_space: 0
+ gigs_all_disk_space: null
hardware_model: ""
hardware_serial: ""
hardware_vendor: ""
diff --git a/docs/Contributing/product-groups/orchestration/understanding-host-vitals.md b/docs/Contributing/product-groups/orchestration/understanding-host-vitals.md
index 9b1ac9717210..ed207090443b 100644
--- a/docs/Contributing/product-groups/orchestration/understanding-host-vitals.md
+++ b/docs/Contributing/product-groups/orchestration/understanding-host-vitals.md
@@ -116,9 +116,58 @@ WITH encrypted(enabled) AS (
- Query:
```sql
SELECT (blocks_available * 100 / blocks) AS percent_disk_space_available,
- round((blocks_available * blocks_size * 10e-10),2) AS gigs_disk_space_available,
- round((blocks * blocks_size * 10e-10),2) AS gigs_total_disk_space
-FROM mounts WHERE path = '/' LIMIT 1;
+ round((blocks_available * blocks_size * 10e-10),2) AS gigs_disk_space_available,
+ round((blocks * blocks_size * 10e-10),2) AS gigs_total_disk_space,
+ (SELECT round(SUM(blocks * blocks_size) * 10e-10, 2) FROM mounts WHERE
+-- exclude mounts with no space
+blocks > 0
+AND blocks_size > 0
+
+-- exclude external storage
+AND path NOT LIKE '/media%' AND path NOT LIKE '/mnt%'
+
+-- exclude device drivers
+AND path NOT LIKE '/dev%'
+
+-- exclude kernel-related mounts
+AND path NOT LIKE '/proc%'
+AND path NOT LIKE '/sys%'
+
+-- exclude process files
+AND path NOT LIKE '/run%'
+AND path NOT LIKE '/var/run%'
+
+-- exclude boot files
+AND path NOT LIKE '/boot%'
+
+-- exclude snap packages
+AND path NOT LIKE '/snap%' AND path NOT LIKE '/var/snap%'
+
+-- exclude virtualized mounts, would double-count bare metal storage
+AND path NOT LIKE '/var/lib/docker%'
+AND path NOT LIKE '/var/lib/containers%'
+
+AND type IN (
+'ext4',
+'ext3',
+'ext2',
+'xfs',
+'btrfs',
+'ntfs',
+'vfat',
+'fuseblk', --seen on NTFS and exFAT volumes mounted via FUSE
+'zfs' --also valid storage
+)
+AND (
+device LIKE '/dev/sd%'
+OR device LIKE '/dev/hd%'
+OR device LIKE '/dev/vd%'
+OR device LIKE '/dev/nvme%'
+OR device LIKE '/dev/mapper%'
+OR device LIKE '/dev/md%'
+OR device LIKE '/dev/dm-%'
+)) AS gigs_all_disk_space
+ FROM mounts WHERE path = '/' LIMIT 1;
```
## disk_space_windows
diff --git a/frontend/interfaces/host.ts b/frontend/interfaces/host.ts
index 8ba59655ce65..54fe48556125 100644
--- a/frontend/interfaces/host.ts
+++ b/frontend/interfaces/host.ts
@@ -65,6 +65,10 @@ export default PropTypes.shape({
additional: PropTypes.object, // eslint-disable-line react/forbid-prop-types
percent_disk_space_available: PropTypes.number,
gigs_disk_space_available: PropTypes.number,
+ // On Linux hosts, `gigs_total_disk_space` only includes disk space from the "/" partition
+ gigs_total_disk_space: PropTypes.number,
+ // `gigs_all_disk_space` includes disk space from all partitions
+ gigs_all_disk_space: PropTypes.number,
labels: PropTypes.arrayOf(labelInterface),
packs: PropTypes.arrayOf(packInterface),
software: PropTypes.arrayOf(softwareInterface),
@@ -280,6 +284,10 @@ export interface IHost {
additional?: object; // eslint-disable-line @typescript-eslint/ban-types
percent_disk_space_available: number;
gigs_disk_space_available: number;
+ // On Linux hosts, `gigs_total_disk_space` only includes disk space from the "/" partition
+ gigs_total_disk_space?: number;
+ // `gigs_all_disk_space` includes disk space from all partitions
+ gigs_all_disk_space?: number;
labels: ILabel[];
packs: IPack[];
software?: ISoftware[];
diff --git a/frontend/pages/hosts/ManageHostsPage/HostTableConfig.tsx b/frontend/pages/hosts/ManageHostsPage/HostTableConfig.tsx
index 2e8bb1c531ea..5eab71f85025 100644
--- a/frontend/pages/hosts/ManageHostsPage/HostTableConfig.tsx
+++ b/frontend/pages/hosts/ManageHostsPage/HostTableConfig.tsx
@@ -284,18 +284,25 @@ const allHostTableHeaders: IHostTableColumnConfig[] = [
isSortedDesc={cellProps.column.isSortedDesc}
/>
),
- accessor: "gigs_disk_space_available",
id: "gigs_disk_space_available",
Cell: (cellProps: IHostTableNumberCellProps) => {
- const { platform, percent_disk_space_available } = cellProps.row.original;
+ const {
+ platform,
+ percent_disk_space_available,
+ gigs_disk_space_available,
+ gigs_total_disk_space,
+ gigs_all_disk_space,
+ } = cellProps.row.original;
if (platform === "chrome") {
return NotSupported;
}
return (
);
diff --git a/frontend/pages/hosts/components/DiskSpaceIndicator/DiskSpaceIndicator.tests.tsx b/frontend/pages/hosts/components/DiskSpaceIndicator/DiskSpaceIndicator.tests.tsx
index 2998f800e053..538ca0b58022 100644
--- a/frontend/pages/hosts/components/DiskSpaceIndicator/DiskSpaceIndicator.tests.tsx
+++ b/frontend/pages/hosts/components/DiskSpaceIndicator/DiskSpaceIndicator.tests.tsx
@@ -148,4 +148,25 @@ describe("Disk space Indicator", () => {
expect(tooltip).toBeInTheDocument();
});
});
+ it("renders tooltip over anchor for Linux hosts with gigs all disk space and gigs total disk space", async () => {
+ const { user } = renderWithSetup(
+
+ );
+
+ await user.hover(screen.getByText(/GB/));
+
+ await waitFor(() => {
+ const totalTip = screen.getByText(/System disk space/);
+ expect(totalTip).toBeInTheDocument();
+ });
+
+ const allTip = screen.getByText(/All partitions/);
+ expect(allTip).toBeInTheDocument();
+ });
});
diff --git a/frontend/pages/hosts/components/DiskSpaceIndicator/DiskSpaceIndicator.tsx b/frontend/pages/hosts/components/DiskSpaceIndicator/DiskSpaceIndicator.tsx
index 793c516ec681..54e57ca5ee2f 100644
--- a/frontend/pages/hosts/components/DiskSpaceIndicator/DiskSpaceIndicator.tsx
+++ b/frontend/pages/hosts/components/DiskSpaceIndicator/DiskSpaceIndicator.tsx
@@ -1,6 +1,5 @@
import React from "react";
-import ReactTooltip from "react-tooltip";
import { PlacesType } from "react-tooltip-5";
import NotSupported from "components/NotSupported";
@@ -8,11 +7,14 @@ import { COLORS } from "styles/var/colors";
import ProgressBar from "components/ProgressBar";
import TooltipWrapper from "components/TooltipWrapper";
+import { isLinuxLike } from "interfaces/platform";
const baseClass = "disk-space-indicator";
interface IDiskSpaceIndicatorProps {
gigsDiskSpaceAvailable: number | "---";
percentDiskSpaceAvailable: number;
+ gigsTotalDiskSpace?: number;
+ gigsAllDiskSpace?: number;
platform: string;
inTableCell?: boolean;
tooltipPosition?: PlacesType;
@@ -21,6 +23,8 @@ interface IDiskSpaceIndicatorProps {
const DiskSpaceIndicator = ({
gigsDiskSpaceAvailable,
percentDiskSpaceAvailable,
+ gigsTotalDiskSpace,
+ gigsAllDiskSpace,
platform,
inTableCell = false,
tooltipPosition = "top",
@@ -73,6 +77,31 @@ const DiskSpaceIndicator = ({
/>
);
+ // get disk space tooltip content for Linux hosts
+ const totalDiskSpaceContent = gigsTotalDiskSpace ? (
+ <>
+ System disk space: {gigsTotalDiskSpace} GB
+
+ >
+ ) : null;
+ const allPartitionsContent = gigsAllDiskSpace ? (
+ <>All partitions: {gigsAllDiskSpace} GB>
+ ) : null;
+
+ const copyTootltipContent =
+ totalDiskSpaceContent || allPartitionsContent ? (
+ <>
+ {totalDiskSpaceContent}
+ {allPartitionsContent}
+ >
+ ) : null;
+
+ const renderCopy = () => (
+ <>
+ {gigsDiskSpaceAvailable} GB{!inTableCell && " available"}
+ >
+ );
+
return (
{diskSpaceTooltipText ? (
@@ -88,7 +117,16 @@ const DiskSpaceIndicator = ({
) : (
renderBar()
)}
- {gigsDiskSpaceAvailable} GB{!inTableCell && " available"}
+ {copyTootltipContent && isLinuxLike(platform) ? (
+
+ {renderCopy()}
+
+ ) : (
+ renderCopy()
+ )}
);
};
diff --git a/frontend/pages/hosts/components/DiskSpaceIndicator/_styles.scss b/frontend/pages/hosts/components/DiskSpaceIndicator/_styles.scss
index a4cba9ea22a2..fd5e5446253d 100644
--- a/frontend/pages/hosts/components/DiskSpaceIndicator/_styles.scss
+++ b/frontend/pages/hosts/components/DiskSpaceIndicator/_styles.scss
@@ -4,7 +4,7 @@
gap: $pad-small;
white-space: nowrap;
- .react-tooltip {
+ .react-tooltip :not(.copy-tooltip-content) {
max-width: px-to-rem(160);
text-align: center;
font-size: px-to-rem(13);
diff --git a/frontend/pages/hosts/details/cards/HostSummary/HostSummary.tsx b/frontend/pages/hosts/details/cards/HostSummary/HostSummary.tsx
index 2f6ce9f8fbcf..120abf9f42e0 100644
--- a/frontend/pages/hosts/details/cards/HostSummary/HostSummary.tsx
+++ b/frontend/pages/hosts/details/cards/HostSummary/HostSummary.tsx
@@ -199,6 +199,8 @@ const HostSummary = ({
diff --git a/frontend/utilities/constants.tsx b/frontend/utilities/constants.tsx
index 7bdb6896511f..cc5f1edb51ae 100644
--- a/frontend/utilities/constants.tsx
+++ b/frontend/utilities/constants.tsx
@@ -5,6 +5,7 @@ import React from "react";
import { IDropdownOption } from "interfaces/dropdownOption";
import { ICampaign } from "interfaces/campaign";
import { MdmEnrollmentStatus } from "interfaces/mdm";
+import { IHost } from "interfaces/host";
const { origin } = global.window.location;
export const BASE_URL = `${origin}${URL_PREFIX}/api`;
@@ -405,7 +406,7 @@ export const DEFAULT_EMPTY_CELL_VALUE = "---";
export const DOCUMENT_TITLE_SUFFIX = "Fleet";
-export const HOST_SUMMARY_DATA = [
+export const HOST_SUMMARY_DATA: (keyof IHost)[] = [
"id",
"status",
"issues",
@@ -416,10 +417,11 @@ export const HOST_SUMMARY_DATA = [
"osquery_version",
"orbit_version",
"fleet_desktop_version",
- "enroll_secret_name",
"detail_updated_at",
"percent_disk_space_available",
"gigs_disk_space_available",
+ "gigs_total_disk_space",
+ "gigs_all_disk_space",
"team_name",
"disk_encryption_enabled",
"display_name", // Not rendered on my device page
diff --git a/server/datastore/mysql/android.go b/server/datastore/mysql/android.go
index 649443e2a5e4..6eb8eb465694 100644
--- a/server/datastore/mysql/android.go
+++ b/server/datastore/mysql/android.go
@@ -139,7 +139,8 @@ func (ds *Datastore) NewAndroidHost(ctx context.Context, host *fleet.AndroidHost
err = ds.SetOrUpdateHostDisksSpace(ctx, host.Host.ID,
host.Host.GigsDiskSpaceAvailable,
host.Host.PercentDiskSpaceAvailable,
- host.Host.GigsTotalDiskSpace)
+ host.Host.GigsTotalDiskSpace,
+ nil)
if err != nil {
return ctxerr.Wrap(ctx, err, "setting Android host disk space")
}
@@ -232,7 +233,8 @@ func (ds *Datastore) UpdateAndroidHost(ctx context.Context, host *fleet.AndroidH
err = ds.SetOrUpdateHostDisksSpace(ctx, host.Host.ID,
host.Host.GigsDiskSpaceAvailable,
host.Host.PercentDiskSpaceAvailable,
- host.Host.GigsTotalDiskSpace)
+ host.Host.GigsTotalDiskSpace,
+ nil)
if err != nil {
return ctxerr.Wrap(ctx, err, "updating Android host disk space")
}
diff --git a/server/datastore/mysql/hosts.go b/server/datastore/mysql/hosts.go
index 17e5d37e2095..88df85f33a35 100644
--- a/server/datastore/mysql/hosts.go
+++ b/server/datastore/mysql/hosts.go
@@ -728,6 +728,7 @@ SELECT
COALESCE(hd.gigs_disk_space_available, 0) as gigs_disk_space_available,
COALESCE(hd.percent_disk_space_available, 0) as percent_disk_space_available,
COALESCE(hd.gigs_total_disk_space, 0) as gigs_total_disk_space,
+ hd.gigs_all_disk_space,
hd.encrypted as disk_encryption_enabled,
COALESCE(hst.seen_time, h.created_at) AS seen_time,
t.name AS team_name,
@@ -1019,6 +1020,7 @@ func (ds *Datastore) ListHosts(ctx context.Context, filter fleet.TeamFilter, opt
COALESCE(hd.gigs_disk_space_available, 0) as gigs_disk_space_available,
COALESCE(hd.percent_disk_space_available, 0) as percent_disk_space_available,
COALESCE(hd.gigs_total_disk_space, 0) as gigs_total_disk_space,
+ hd.gigs_all_disk_space,
COALESCE(hst.seen_time, h.created_at) AS seen_time,
t.name AS team_name,
COALESCE(hu.software_updated_at, h.created_at) AS software_updated_at,
@@ -2981,6 +2983,7 @@ func (ds *Datastore) SearchHosts(ctx context.Context, filter fleet.TeamFilter, m
COALESCE(hd.gigs_disk_space_available, 0) as gigs_disk_space_available,
COALESCE(hd.percent_disk_space_available, 0) as percent_disk_space_available,
COALESCE(hd.gigs_total_disk_space, 0) as gigs_total_disk_space,
+ hd.gigs_all_disk_space as gigs_all_disk_space,
COALESCE(hst.seen_time, h.created_at) AS seen_time,
COALESCE(hu.software_updated_at, h.created_at) AS software_updated_at
` + hostMDMSelect + `
@@ -4332,12 +4335,12 @@ func (ds *Datastore) GetHostEmails(ctx context.Context, hostUUID string, source
// SetOrUpdateHostDisksSpace sets the available gigs and percentage of the
// disks for the specified host.
-func (ds *Datastore) SetOrUpdateHostDisksSpace(ctx context.Context, hostID uint, gigsAvailable, percentAvailable, gigsTotal float64) error {
+func (ds *Datastore) SetOrUpdateHostDisksSpace(ctx context.Context, hostID uint, gigsAvailable, percentAvailable, gigsTotal float64, gigsAll *float64) error {
return ds.updateOrInsert(
ctx,
- `UPDATE host_disks SET gigs_disk_space_available = ?, percent_disk_space_available = ?, gigs_total_disk_space = ? WHERE host_id = ?`,
- `INSERT INTO host_disks (gigs_disk_space_available, percent_disk_space_available, gigs_total_disk_space, host_id) VALUES (?, ?, ?, ?)`,
- gigsAvailable, percentAvailable, gigsTotal, hostID,
+ `UPDATE host_disks SET gigs_disk_space_available = ?, percent_disk_space_available = ?, gigs_total_disk_space = ?, gigs_all_disk_space = ? WHERE host_id = ?`,
+ `INSERT INTO host_disks (gigs_disk_space_available, percent_disk_space_available, gigs_total_disk_space, gigs_all_disk_space, host_id) VALUES (?, ?, ?, ?, ?)`,
+ gigsAvailable, percentAvailable, gigsTotal, gigsAll, hostID,
)
}
diff --git a/server/datastore/mysql/hosts_test.go b/server/datastore/mysql/hosts_test.go
index e9803807d900..31d0194aa79e 100644
--- a/server/datastore/mysql/hosts_test.go
+++ b/server/datastore/mysql/hosts_test.go
@@ -1154,9 +1154,9 @@ func testHostsListQuery(t *testing.T, ds *Datastore) {
}, "src1"))
// add some disks space info for some hosts
- require.NoError(t, ds.SetOrUpdateHostDisksSpace(context.Background(), hosts[0].ID, 1.0, 2.0, 30.0))
- require.NoError(t, ds.SetOrUpdateHostDisksSpace(context.Background(), hosts[1].ID, 3.0, 4.0, 50.0))
- require.NoError(t, ds.SetOrUpdateHostDisksSpace(context.Background(), hosts[2].ID, 5.0, 6.0, 70.0))
+ require.NoError(t, ds.SetOrUpdateHostDisksSpace(context.Background(), hosts[0].ID, 1.0, 2.0, 30.0, nil))
+ require.NoError(t, ds.SetOrUpdateHostDisksSpace(context.Background(), hosts[1].ID, 3.0, 4.0, 50.0, nil))
+ require.NoError(t, ds.SetOrUpdateHostDisksSpace(context.Background(), hosts[2].ID, 5.0, 6.0, 70.0, nil))
filter := fleet.TeamFilter{User: test.UserAdmin}
@@ -2307,7 +2307,7 @@ func testHostsGenerateStatusStatistics(t *testing.T, ds *Datastore) {
h.ConfigTLSRefresh = 30
err = ds.UpdateHost(context.Background(), h)
require.NoError(t, err)
- require.NoError(t, ds.SetOrUpdateHostDisksSpace(context.Background(), h.ID, 5, 5, 100.0))
+ require.NoError(t, ds.SetOrUpdateHostDisksSpace(context.Background(), h.ID, 5, 5, 100.0, ptr.Float64(120.0)))
// Online
h, err = ds.NewHost(context.Background(), &fleet.Host{
@@ -2325,7 +2325,7 @@ func testHostsGenerateStatusStatistics(t *testing.T, ds *Datastore) {
h.ConfigTLSRefresh = 3600
err = ds.UpdateHost(context.Background(), h)
require.NoError(t, err)
- require.NoError(t, ds.SetOrUpdateHostDisksSpace(context.Background(), h.ID, 50, 50, 100.0))
+ require.NoError(t, ds.SetOrUpdateHostDisksSpace(context.Background(), h.ID, 50, 50, 100.0, ptr.Float64(120.0)))
// Offline
h, err = ds.NewHost(context.Background(), &fleet.Host{
@@ -2370,7 +2370,7 @@ func testHostsGenerateStatusStatistics(t *testing.T, ds *Datastore) {
})
require.NoError(t, err)
// Set -1 sentinel values to indicate storage measurement not supported
- require.NoError(t, ds.SetOrUpdateHostDisksSpace(context.Background(), h.ID, -1, -1, 128.0))
+ require.NoError(t, ds.SetOrUpdateHostDisksSpace(context.Background(), h.ID, -1, -1, 128.0, nil))
team1, err := ds.NewTeam(context.Background(), &fleet.Team{Name: "team1"})
require.NoError(t, err)
@@ -2468,7 +2468,7 @@ func testHostsLowDiskSpaceFilterExcludesSentinel(t *testing.T, ds *Datastore) {
Hostname: "android-unmeasurable",
})
require.NoError(t, err)
- require.NoError(t, ds.SetOrUpdateHostDisksSpace(ctx, h1.ID, -1, -1, 128.0))
+ require.NoError(t, ds.SetOrUpdateHostDisksSpace(ctx, h1.ID, -1, -1, 128.0, nil))
// Host 2: Regular host with 0 GB (should be counted - legitimate disk full)
h2, err := ds.NewHost(ctx, &fleet.Host{
@@ -2483,7 +2483,7 @@ func testHostsLowDiskSpaceFilterExcludesSentinel(t *testing.T, ds *Datastore) {
Hostname: "mac-disk-full",
})
require.NoError(t, err)
- require.NoError(t, ds.SetOrUpdateHostDisksSpace(ctx, h2.ID, 0, 0, 100.0))
+ require.NoError(t, ds.SetOrUpdateHostDisksSpace(ctx, h2.ID, 0, 0, 100.0, nil))
// Host 3: Regular host with 5 GB (should be counted)
h3, err := ds.NewHost(ctx, &fleet.Host{
@@ -2498,7 +2498,7 @@ func testHostsLowDiskSpaceFilterExcludesSentinel(t *testing.T, ds *Datastore) {
Hostname: "windows-low-space",
})
require.NoError(t, err)
- require.NoError(t, ds.SetOrUpdateHostDisksSpace(ctx, h3.ID, 5, 5, 100.0))
+ require.NoError(t, ds.SetOrUpdateHostDisksSpace(ctx, h3.ID, 5, 5, 100.0, nil))
// Host 4: Regular host with 50 GB (should NOT be counted - above threshold)
h4, err := ds.NewHost(ctx, &fleet.Host{
@@ -2513,7 +2513,7 @@ func testHostsLowDiskSpaceFilterExcludesSentinel(t *testing.T, ds *Datastore) {
Hostname: "linux-good-space",
})
require.NoError(t, err)
- require.NoError(t, ds.SetOrUpdateHostDisksSpace(ctx, h4.ID, 50, 50, 100.0))
+ require.NoError(t, ds.SetOrUpdateHostDisksSpace(ctx, h4.ID, 50, 50, 100.0, ptr.Float64(120.0)))
// Test with low disk space filter set to 32 GB (typical threshold)
opts := fleet.HostListOptions{
@@ -3036,12 +3036,13 @@ func testLoadHostByNodeKeyLoadsDisk(t *testing.T, ds *Datastore) {
NodeKey: ptr.String("nodekey"),
UUID: "uuid",
Hostname: "foobar.local",
+ Platform: "darwin",
})
require.NoError(t, err)
err = ds.UpdateHost(context.Background(), h)
require.NoError(t, err)
- err = ds.SetOrUpdateHostDisksSpace(context.Background(), h.ID, 1.24, 42.0, 3.0)
+ err = ds.SetOrUpdateHostDisksSpace(context.Background(), h.ID, 1.24, 42.0, 3.0, ptr.Float64(4.0))
require.NoError(t, err)
h, err = ds.LoadHostByNodeKey(context.Background(), "nodekey")
@@ -7997,7 +7998,7 @@ func testHostsDeleteHosts(t *testing.T, ds *Datastore) {
_, err = ds.writer(context.Background()).Exec(stmt, host.ID, 1, 123)
require.NoError(t, err)
// set host' disk space
- err = ds.SetOrUpdateHostDisksSpace(context.Background(), host.ID, 12, 25, 40.0)
+ err = ds.SetOrUpdateHostDisksSpace(context.Background(), host.ID, 12, 25, 40.0, nil)
require.NoError(t, err)
// set host orbit info
err = ds.SetOrUpdateHostOrbitInfo(
@@ -8736,10 +8737,10 @@ func testHostsSetOrUpdateHostDisksSpace(t *testing.T, ds *Datastore) {
err = ds.SetOrUpdateDeviceAuthToken(context.Background(), host.ID, token1)
require.NoError(t, err)
- err = ds.SetOrUpdateHostDisksSpace(context.Background(), host.ID, 1, 2, 50.0)
+ err = ds.SetOrUpdateHostDisksSpace(context.Background(), host.ID, 1, 2, 50.0, nil)
require.NoError(t, err)
- err = ds.SetOrUpdateHostDisksSpace(context.Background(), host2.ID, 3, 4, 90.0)
+ err = ds.SetOrUpdateHostDisksSpace(context.Background(), host2.ID, 3, 4, 90.0, nil)
require.NoError(t, err)
h, err := ds.Host(context.Background(), host.ID)
@@ -8752,7 +8753,7 @@ func testHostsSetOrUpdateHostDisksSpace(t *testing.T, ds *Datastore) {
require.Equal(t, 3.0, h.GigsDiskSpaceAvailable)
require.Equal(t, 4.0, h.PercentDiskSpaceAvailable)
- err = ds.SetOrUpdateHostDisksSpace(context.Background(), host.ID, 5, 6, 80.0)
+ err = ds.SetOrUpdateHostDisksSpace(context.Background(), host.ID, 5, 6, 80.0, nil)
require.NoError(t, err)
h, err = ds.LoadHostByDeviceAuthToken(context.Background(), token1, time.Hour)
diff --git a/server/datastore/mysql/labels_test.go b/server/datastore/mysql/labels_test.go
index eff62c62893c..504592832ec5 100644
--- a/server/datastore/mysql/labels_test.go
+++ b/server/datastore/mysql/labels_test.go
@@ -321,9 +321,9 @@ func testLabelsListHostsInLabel(t *testing.T, db *Datastore) {
Platform: "darwin",
})
require.Nil(t, err)
- require.NoError(t, db.SetOrUpdateHostDisksSpace(context.Background(), h1.ID, 10, 5, 200.0))
- require.NoError(t, db.SetOrUpdateHostDisksSpace(context.Background(), h2.ID, 20, 10, 200.1))
- require.NoError(t, db.SetOrUpdateHostDisksSpace(context.Background(), h3.ID, 30, 15, 200.2))
+ require.NoError(t, db.SetOrUpdateHostDisksSpace(context.Background(), h1.ID, 10, 5, 200.0, nil))
+ require.NoError(t, db.SetOrUpdateHostDisksSpace(context.Background(), h2.ID, 20, 10, 200.1, nil))
+ require.NoError(t, db.SetOrUpdateHostDisksSpace(context.Background(), h3.ID, 30, 15, 200.2, nil))
ctx := context.Background()
const simpleMDM, kandji = "https://simplemdm.com", "https://kandji.io"
diff --git a/server/datastore/mysql/migrations/tables/20251013172310_AddGigsAllDiskSpaceToHostDisks.go b/server/datastore/mysql/migrations/tables/20251013172310_AddGigsAllDiskSpaceToHostDisks.go
new file mode 100644
index 000000000000..b1938a09c487
--- /dev/null
+++ b/server/datastore/mysql/migrations/tables/20251013172310_AddGigsAllDiskSpaceToHostDisks.go
@@ -0,0 +1,26 @@
+package tables
+
+import (
+ "database/sql"
+ "fmt"
+)
+
+func init() {
+ MigrationClient.AddMigration(Up_20251013172310, Down_20251013172310)
+}
+
+func Up_20251013172310(tx *sql.Tx) error {
+ // NULLable since only relevant for Linux hosts
+ stmt := `
+ ALTER TABLE host_disks
+ ADD COLUMN gigs_all_disk_space decimal(10,2)
+ `
+ if _, err := tx.Exec(stmt); err != nil {
+ return fmt.Errorf("add gigs_all_disk_space to host_disks: %w", err)
+ }
+ return nil
+}
+
+func Down_20251013172310(tx *sql.Tx) error {
+ return nil
+}
diff --git a/server/datastore/mysql/migrations/tables/20251013172310_AddGigsAllDiskSpaceToHostDisks_test.go b/server/datastore/mysql/migrations/tables/20251013172310_AddGigsAllDiskSpaceToHostDisks_test.go
new file mode 100644
index 000000000000..a725e88f2472
--- /dev/null
+++ b/server/datastore/mysql/migrations/tables/20251013172310_AddGigsAllDiskSpaceToHostDisks_test.go
@@ -0,0 +1,36 @@
+package tables
+
+import (
+ "testing"
+
+ "github.com/fleetdm/fleet/v4/server/ptr"
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+)
+
+func TestUp_20251013172310(t *testing.T) {
+ db := applyUpToPrev(t)
+
+ insertStmt := `INSERT INTO host_disks (host_id) VALUES (1)`
+ _, err := db.Exec(insertStmt)
+ require.NoError(t, err)
+
+ // Apply current migration.
+ applyNext(t, db)
+
+ type diskSpace struct {
+ HostID uint `db:"host_id"`
+ GigsAllDiskSpace *float64 `db:"gigs_all_disk_space"`
+ }
+
+ var ds diskSpace
+ err = db.Get(&ds, `SELECT host_id, gigs_all_disk_space from host_disks where host_id = 1`)
+ require.NoError(t, err)
+ assert.Nil(t, ds.GigsAllDiskSpace)
+
+ _, err = db.Exec(`INSERT INTO host_disks (host_id, gigs_all_disk_space) VALUES (2, 1.5)`)
+ require.NoError(t, err)
+ err = db.Get(&ds, `SELECT host_id, gigs_all_disk_space from host_disks where host_id = 2`)
+ require.NoError(t, err)
+ assert.Equal(t, ptr.Float64(1.5), ds.GigsAllDiskSpace)
+}
diff --git a/server/datastore/mysql/schema.sql b/server/datastore/mysql/schema.sql
index 619bdbd5431e..89f61f5f433d 100644
--- a/server/datastore/mysql/schema.sql
+++ b/server/datastore/mysql/schema.sql
@@ -543,6 +543,7 @@ CREATE TABLE `host_disks` (
`encrypted` tinyint(1) DEFAULT NULL,
`gigs_total_disk_space` decimal(10,2) NOT NULL DEFAULT '0.00',
`tpm_pin_set` tinyint(1) DEFAULT '0',
+ `gigs_all_disk_space` decimal(10,2) DEFAULT NULL,
PRIMARY KEY (`host_id`),
KEY `idx_host_disks_gigs_disk_space_available` (`gigs_disk_space_available`)
) /*!50100 TABLESPACE `innodb_system` */ ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
@@ -1560,9 +1561,9 @@ CREATE TABLE `migration_status_tables` (
`is_applied` tinyint(1) NOT NULL,
`tstamp` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
-) /*!50100 TABLESPACE `innodb_system` */ ENGINE=InnoDB AUTO_INCREMENT=429 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
+) /*!50100 TABLESPACE `innodb_system` */ ENGINE=InnoDB AUTO_INCREMENT=430 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
-INSERT INTO `migration_status_tables` VALUES (1,0,1,'2020-01-01 01:01:01'),(2,20161118193812,1,'2020-01-01 01:01:01'),(3,20161118211713,1,'2020-01-01 01:01:01'),(4,20161118212436,1,'2020-01-01 01:01:01'),(5,20161118212515,1,'2020-01-01 01:01:01'),(6,20161118212528,1,'2020-01-01 01:01:01'),(7,20161118212538,1,'2020-01-01 01:01:01'),(8,20161118212549,1,'2020-01-01 01:01:01'),(9,20161118212557,1,'2020-01-01 01:01:01'),(10,20161118212604,1,'2020-01-01 01:01:01'),(11,20161118212613,1,'2020-01-01 01:01:01'),(12,20161118212621,1,'2020-01-01 01:01:01'),(13,20161118212630,1,'2020-01-01 01:01:01'),(14,20161118212641,1,'2020-01-01 01:01:01'),(15,20161118212649,1,'2020-01-01 01:01:01'),(16,20161118212656,1,'2020-01-01 01:01:01'),(17,20161118212758,1,'2020-01-01 01:01:01'),(18,20161128234849,1,'2020-01-01 01:01:01'),(19,20161230162221,1,'2020-01-01 01:01:01'),(20,20170104113816,1,'2020-01-01 01:01:01'),(21,20170105151732,1,'2020-01-01 01:01:01'),(22,20170108191242,1,'2020-01-01 01:01:01'),(23,20170109094020,1,'2020-01-01 01:01:01'),(24,20170109130438,1,'2020-01-01 01:01:01'),(25,20170110202752,1,'2020-01-01 01:01:01'),(26,20170111133013,1,'2020-01-01 01:01:01'),(27,20170117025759,1,'2020-01-01 01:01:01'),(28,20170118191001,1,'2020-01-01 01:01:01'),(29,20170119234632,1,'2020-01-01 01:01:01'),(30,20170124230432,1,'2020-01-01 01:01:01'),(31,20170127014618,1,'2020-01-01 01:01:01'),(32,20170131232841,1,'2020-01-01 01:01:01'),(33,20170223094154,1,'2020-01-01 01:01:01'),(34,20170306075207,1,'2020-01-01 01:01:01'),(35,20170309100733,1,'2020-01-01 01:01:01'),(36,20170331111922,1,'2020-01-01 01:01:01'),(37,20170502143928,1,'2020-01-01 01:01:01'),(38,20170504130602,1,'2020-01-01 01:01:01'),(39,20170509132100,1,'2020-01-01 01:01:01'),(40,20170519105647,1,'2020-01-01 01:01:01'),(41,20170519105648,1,'2020-01-01 01:01:01'),(42,20170831234300,1,'2020-01-01 01:01:01'),(43,20170831234301,1,'2020-01-01 01:01:01'),(44,20170831234303,1,'2020-01-01 01:01:01'),(45,20171116163618,1,'2020-01-01 01:01:01'),(46,20171219164727,1,'2020-01-01 01:01:01'),(47,20180620164811,1,'2020-01-01 01:01:01'),(48,20180620175054,1,'2020-01-01 01:01:01'),(49,20180620175055,1,'2020-01-01 01:01:01'),(50,20191010101639,1,'2020-01-01 01:01:01'),(51,20191010155147,1,'2020-01-01 01:01:01'),(52,20191220130734,1,'2020-01-01 01:01:01'),(53,20200311140000,1,'2020-01-01 01:01:01'),(54,20200405120000,1,'2020-01-01 01:01:01'),(55,20200407120000,1,'2020-01-01 01:01:01'),(56,20200420120000,1,'2020-01-01 01:01:01'),(57,20200504120000,1,'2020-01-01 01:01:01'),(58,20200512120000,1,'2020-01-01 01:01:01'),(59,20200707120000,1,'2020-01-01 01:01:01'),(60,20201011162341,1,'2020-01-01 01:01:01'),(61,20201021104586,1,'2020-01-01 01:01:01'),(62,20201102112520,1,'2020-01-01 01:01:01'),(63,20201208121729,1,'2020-01-01 01:01:01'),(64,20201215091637,1,'2020-01-01 01:01:01'),(65,20210119174155,1,'2020-01-01 01:01:01'),(66,20210326182902,1,'2020-01-01 01:01:01'),(67,20210421112652,1,'2020-01-01 01:01:01'),(68,20210506095025,1,'2020-01-01 01:01:01'),(69,20210513115729,1,'2020-01-01 01:01:01'),(70,20210526113559,1,'2020-01-01 01:01:01'),(71,20210601000001,1,'2020-01-01 01:01:01'),(72,20210601000002,1,'2020-01-01 01:01:01'),(73,20210601000003,1,'2020-01-01 01:01:01'),(74,20210601000004,1,'2020-01-01 01:01:01'),(75,20210601000005,1,'2020-01-01 01:01:01'),(76,20210601000006,1,'2020-01-01 01:01:01'),(77,20210601000007,1,'2020-01-01 01:01:01'),(78,20210601000008,1,'2020-01-01 01:01:01'),(79,20210606151329,1,'2020-01-01 01:01:01'),(80,20210616163757,1,'2020-01-01 01:01:01'),(81,20210617174723,1,'2020-01-01 01:01:01'),(82,20210622160235,1,'2020-01-01 01:01:01'),(83,20210623100031,1,'2020-01-01 01:01:01'),(84,20210623133615,1,'2020-01-01 01:01:01'),(85,20210708143152,1,'2020-01-01 01:01:01'),(86,20210709124443,1,'2020-01-01 01:01:01'),(87,20210712155608,1,'2020-01-01 01:01:01'),(88,20210714102108,1,'2020-01-01 01:01:01'),(89,20210719153709,1,'2020-01-01 01:01:01'),(90,20210721171531,1,'2020-01-01 01:01:01'),(91,20210723135713,1,'2020-01-01 01:01:01'),(92,20210802135933,1,'2020-01-01 01:01:01'),(93,20210806112844,1,'2020-01-01 01:01:01'),(94,20210810095603,1,'2020-01-01 01:01:01'),(95,20210811150223,1,'2020-01-01 01:01:01'),(96,20210818151827,1,'2020-01-01 01:01:01'),(97,20210818151828,1,'2020-01-01 01:01:01'),(98,20210818182258,1,'2020-01-01 01:01:01'),(99,20210819131107,1,'2020-01-01 01:01:01'),(100,20210819143446,1,'2020-01-01 01:01:01'),(101,20210903132338,1,'2020-01-01 01:01:01'),(102,20210915144307,1,'2020-01-01 01:01:01'),(103,20210920155130,1,'2020-01-01 01:01:01'),(104,20210927143115,1,'2020-01-01 01:01:01'),(105,20210927143116,1,'2020-01-01 01:01:01'),(106,20211013133706,1,'2020-01-01 01:01:01'),(107,20211013133707,1,'2020-01-01 01:01:01'),(108,20211102135149,1,'2020-01-01 01:01:01'),(109,20211109121546,1,'2020-01-01 01:01:01'),(110,20211110163320,1,'2020-01-01 01:01:01'),(111,20211116184029,1,'2020-01-01 01:01:01'),(112,20211116184030,1,'2020-01-01 01:01:01'),(113,20211202092042,1,'2020-01-01 01:01:01'),(114,20211202181033,1,'2020-01-01 01:01:01'),(115,20211207161856,1,'2020-01-01 01:01:01'),(116,20211216131203,1,'2020-01-01 01:01:01'),(117,20211221110132,1,'2020-01-01 01:01:01'),(118,20220107155700,1,'2020-01-01 01:01:01'),(119,20220125105650,1,'2020-01-01 01:01:01'),(120,20220201084510,1,'2020-01-01 01:01:01'),(121,20220208144830,1,'2020-01-01 01:01:01'),(122,20220208144831,1,'2020-01-01 01:01:01'),(123,20220215152203,1,'2020-01-01 01:01:01'),(124,20220223113157,1,'2020-01-01 01:01:01'),(125,20220307104655,1,'2020-01-01 01:01:01'),(126,20220309133956,1,'2020-01-01 01:01:01'),(127,20220316155700,1,'2020-01-01 01:01:01'),(128,20220323152301,1,'2020-01-01 01:01:01'),(129,20220330100659,1,'2020-01-01 01:01:01'),(130,20220404091216,1,'2020-01-01 01:01:01'),(131,20220419140750,1,'2020-01-01 01:01:01'),(132,20220428140039,1,'2020-01-01 01:01:01'),(133,20220503134048,1,'2020-01-01 01:01:01'),(134,20220524102918,1,'2020-01-01 01:01:01'),(135,20220526123327,1,'2020-01-01 01:01:01'),(136,20220526123328,1,'2020-01-01 01:01:01'),(137,20220526123329,1,'2020-01-01 01:01:01'),(138,20220608113128,1,'2020-01-01 01:01:01'),(139,20220627104817,1,'2020-01-01 01:01:01'),(140,20220704101843,1,'2020-01-01 01:01:01'),(141,20220708095046,1,'2020-01-01 01:01:01'),(142,20220713091130,1,'2020-01-01 01:01:01'),(143,20220802135510,1,'2020-01-01 01:01:01'),(144,20220818101352,1,'2020-01-01 01:01:01'),(145,20220822161445,1,'2020-01-01 01:01:01'),(146,20220831100036,1,'2020-01-01 01:01:01'),(147,20220831100151,1,'2020-01-01 01:01:01'),(148,20220908181826,1,'2020-01-01 01:01:01'),(149,20220914154915,1,'2020-01-01 01:01:01'),(150,20220915165115,1,'2020-01-01 01:01:01'),(151,20220915165116,1,'2020-01-01 01:01:01'),(152,20220928100158,1,'2020-01-01 01:01:01'),(153,20221014084130,1,'2020-01-01 01:01:01'),(154,20221027085019,1,'2020-01-01 01:01:01'),(155,20221101103952,1,'2020-01-01 01:01:01'),(156,20221104144401,1,'2020-01-01 01:01:01'),(157,20221109100749,1,'2020-01-01 01:01:01'),(158,20221115104546,1,'2020-01-01 01:01:01'),(159,20221130114928,1,'2020-01-01 01:01:01'),(160,20221205112142,1,'2020-01-01 01:01:01'),(161,20221216115820,1,'2020-01-01 01:01:01'),(162,20221220195934,1,'2020-01-01 01:01:01'),(163,20221220195935,1,'2020-01-01 01:01:01'),(164,20221223174807,1,'2020-01-01 01:01:01'),(165,20221227163855,1,'2020-01-01 01:01:01'),(166,20221227163856,1,'2020-01-01 01:01:01'),(167,20230202224725,1,'2020-01-01 01:01:01'),(168,20230206163608,1,'2020-01-01 01:01:01'),(169,20230214131519,1,'2020-01-01 01:01:01'),(170,20230303135738,1,'2020-01-01 01:01:01'),(171,20230313135301,1,'2020-01-01 01:01:01'),(172,20230313141819,1,'2020-01-01 01:01:01'),(173,20230315104937,1,'2020-01-01 01:01:01'),(174,20230317173844,1,'2020-01-01 01:01:01'),(175,20230320133602,1,'2020-01-01 01:01:01'),(176,20230330100011,1,'2020-01-01 01:01:01'),(177,20230330134823,1,'2020-01-01 01:01:01'),(178,20230405232025,1,'2020-01-01 01:01:01'),(179,20230408084104,1,'2020-01-01 01:01:01'),(180,20230411102858,1,'2020-01-01 01:01:01'),(181,20230421155932,1,'2020-01-01 01:01:01'),(182,20230425082126,1,'2020-01-01 01:01:01'),(183,20230425105727,1,'2020-01-01 01:01:01'),(184,20230501154913,1,'2020-01-01 01:01:01'),(185,20230503101418,1,'2020-01-01 01:01:01'),(186,20230515144206,1,'2020-01-01 01:01:01'),(187,20230517140952,1,'2020-01-01 01:01:01'),(188,20230517152807,1,'2020-01-01 01:01:01'),(189,20230518114155,1,'2020-01-01 01:01:01'),(190,20230520153236,1,'2020-01-01 01:01:01'),(191,20230525151159,1,'2020-01-01 01:01:01'),(192,20230530122103,1,'2020-01-01 01:01:01'),(193,20230602111827,1,'2020-01-01 01:01:01'),(194,20230608103123,1,'2020-01-01 01:01:01'),(195,20230629140529,1,'2020-01-01 01:01:01'),(196,20230629140530,1,'2020-01-01 01:01:01'),(197,20230711144622,1,'2020-01-01 01:01:01'),(198,20230721135421,1,'2020-01-01 01:01:01'),(199,20230721161508,1,'2020-01-01 01:01:01'),(200,20230726115701,1,'2020-01-01 01:01:01'),(201,20230807100822,1,'2020-01-01 01:01:01'),(202,20230814150442,1,'2020-01-01 01:01:01'),(203,20230823122728,1,'2020-01-01 01:01:01'),(204,20230906152143,1,'2020-01-01 01:01:01'),(205,20230911163618,1,'2020-01-01 01:01:01'),(206,20230912101759,1,'2020-01-01 01:01:01'),(207,20230915101341,1,'2020-01-01 01:01:01'),(208,20230918132351,1,'2020-01-01 01:01:01'),(209,20231004144339,1,'2020-01-01 01:01:01'),(210,20231009094541,1,'2020-01-01 01:01:01'),(211,20231009094542,1,'2020-01-01 01:01:01'),(212,20231009094543,1,'2020-01-01 01:01:01'),(213,20231009094544,1,'2020-01-01 01:01:01'),(214,20231016091915,1,'2020-01-01 01:01:01'),(215,20231024174135,1,'2020-01-01 01:01:01'),(216,20231025120016,1,'2020-01-01 01:01:01'),(217,20231025160156,1,'2020-01-01 01:01:01'),(218,20231031165350,1,'2020-01-01 01:01:01'),(219,20231106144110,1,'2020-01-01 01:01:01'),(220,20231107130934,1,'2020-01-01 01:01:01'),(221,20231109115838,1,'2020-01-01 01:01:01'),(222,20231121054530,1,'2020-01-01 01:01:01'),(223,20231122101320,1,'2020-01-01 01:01:01'),(224,20231130132828,1,'2020-01-01 01:01:01'),(225,20231130132931,1,'2020-01-01 01:01:01'),(226,20231204155427,1,'2020-01-01 01:01:01'),(227,20231206142340,1,'2020-01-01 01:01:01'),(228,20231207102320,1,'2020-01-01 01:01:01'),(229,20231207102321,1,'2020-01-01 01:01:01'),(230,20231207133731,1,'2020-01-01 01:01:01'),(231,20231212094238,1,'2020-01-01 01:01:01'),(232,20231212095734,1,'2020-01-01 01:01:01'),(233,20231212161121,1,'2020-01-01 01:01:01'),(234,20231215122713,1,'2020-01-01 01:01:01'),(235,20231219143041,1,'2020-01-01 01:01:01'),(236,20231224070653,1,'2020-01-01 01:01:01'),(237,20240110134315,1,'2020-01-01 01:01:01'),(238,20240119091637,1,'2020-01-01 01:01:01'),(239,20240126020642,1,'2020-01-01 01:01:01'),(240,20240126020643,1,'2020-01-01 01:01:01'),(241,20240129162819,1,'2020-01-01 01:01:01'),(242,20240130115133,1,'2020-01-01 01:01:01'),(243,20240131083822,1,'2020-01-01 01:01:01'),(244,20240205095928,1,'2020-01-01 01:01:01'),(245,20240205121956,1,'2020-01-01 01:01:01'),(246,20240209110212,1,'2020-01-01 01:01:01'),(247,20240212111533,1,'2020-01-01 01:01:01'),(248,20240221112844,1,'2020-01-01 01:01:01'),(249,20240222073518,1,'2020-01-01 01:01:01'),(250,20240222135115,1,'2020-01-01 01:01:01'),(251,20240226082255,1,'2020-01-01 01:01:01'),(252,20240228082706,1,'2020-01-01 01:01:01'),(253,20240301173035,1,'2020-01-01 01:01:01'),(254,20240302111134,1,'2020-01-01 01:01:01'),(255,20240312103753,1,'2020-01-01 01:01:01'),(256,20240313143416,1,'2020-01-01 01:01:01'),(257,20240314085226,1,'2020-01-01 01:01:01'),(258,20240314151747,1,'2020-01-01 01:01:01'),(259,20240320145650,1,'2020-01-01 01:01:01'),(260,20240327115530,1,'2020-01-01 01:01:01'),(261,20240327115617,1,'2020-01-01 01:01:01'),(262,20240408085837,1,'2020-01-01 01:01:01'),(263,20240415104633,1,'2020-01-01 01:01:01'),(264,20240430111727,1,'2020-01-01 01:01:01'),(265,20240515200020,1,'2020-01-01 01:01:01'),(266,20240521143023,1,'2020-01-01 01:01:01'),(267,20240521143024,1,'2020-01-01 01:01:01'),(268,20240601174138,1,'2020-01-01 01:01:01'),(269,20240607133721,1,'2020-01-01 01:01:01'),(270,20240612150059,1,'2020-01-01 01:01:01'),(271,20240613162201,1,'2020-01-01 01:01:01'),(272,20240613172616,1,'2020-01-01 01:01:01'),(273,20240618142419,1,'2020-01-01 01:01:01'),(274,20240625093543,1,'2020-01-01 01:01:01'),(275,20240626195531,1,'2020-01-01 01:01:01'),(276,20240702123921,1,'2020-01-01 01:01:01'),(277,20240703154849,1,'2020-01-01 01:01:01'),(278,20240707134035,1,'2020-01-01 01:01:01'),(279,20240707134036,1,'2020-01-01 01:01:01'),(280,20240709124958,1,'2020-01-01 01:01:01'),(281,20240709132642,1,'2020-01-01 01:01:01'),(282,20240709183940,1,'2020-01-01 01:01:01'),(283,20240710155623,1,'2020-01-01 01:01:01'),(284,20240723102712,1,'2020-01-01 01:01:01'),(285,20240725152735,1,'2020-01-01 01:01:01'),(286,20240725182118,1,'2020-01-01 01:01:01'),(287,20240726100517,1,'2020-01-01 01:01:01'),(288,20240730171504,1,'2020-01-01 01:01:01'),(289,20240730174056,1,'2020-01-01 01:01:01'),(290,20240730215453,1,'2020-01-01 01:01:01'),(291,20240730374423,1,'2020-01-01 01:01:01'),(292,20240801115359,1,'2020-01-01 01:01:01'),(293,20240802101043,1,'2020-01-01 01:01:01'),(294,20240802113716,1,'2020-01-01 01:01:01'),(295,20240814135330,1,'2020-01-01 01:01:01'),(296,20240815000000,1,'2020-01-01 01:01:01'),(297,20240815000001,1,'2020-01-01 01:01:01'),(298,20240816103247,1,'2020-01-01 01:01:01'),(299,20240820091218,1,'2020-01-01 01:01:01'),(300,20240826111228,1,'2020-01-01 01:01:01'),(301,20240826160025,1,'2020-01-01 01:01:01'),(302,20240829165448,1,'2020-01-01 01:01:01'),(303,20240829165605,1,'2020-01-01 01:01:01'),(304,20240829165715,1,'2020-01-01 01:01:01'),(305,20240829165930,1,'2020-01-01 01:01:01'),(306,20240829170023,1,'2020-01-01 01:01:01'),(307,20240829170033,1,'2020-01-01 01:01:01'),(308,20240829170044,1,'2020-01-01 01:01:01'),(309,20240905105135,1,'2020-01-01 01:01:01'),(310,20240905140514,1,'2020-01-01 01:01:01'),(311,20240905200000,1,'2020-01-01 01:01:01'),(312,20240905200001,1,'2020-01-01 01:01:01'),(313,20241002104104,1,'2020-01-01 01:01:01'),(314,20241002104105,1,'2020-01-01 01:01:01'),(315,20241002104106,1,'2020-01-01 01:01:01'),(316,20241002210000,1,'2020-01-01 01:01:01'),(317,20241003145349,1,'2020-01-01 01:01:01'),(318,20241004005000,1,'2020-01-01 01:01:01'),(319,20241008083925,1,'2020-01-01 01:01:01'),(320,20241009090010,1,'2020-01-01 01:01:01'),(321,20241017163402,1,'2020-01-01 01:01:01'),(322,20241021224359,1,'2020-01-01 01:01:01'),(323,20241022140321,1,'2020-01-01 01:01:01'),(324,20241025111236,1,'2020-01-01 01:01:01'),(325,20241025112748,1,'2020-01-01 01:01:01'),(326,20241025141855,1,'2020-01-01 01:01:01'),(327,20241110152839,1,'2020-01-01 01:01:01'),(328,20241110152840,1,'2020-01-01 01:01:01'),(329,20241110152841,1,'2020-01-01 01:01:01'),(330,20241116233322,1,'2020-01-01 01:01:01'),(331,20241122171434,1,'2020-01-01 01:01:01'),(332,20241125150614,1,'2020-01-01 01:01:01'),(333,20241203125346,1,'2020-01-01 01:01:01'),(334,20241203130032,1,'2020-01-01 01:01:01'),(335,20241205122800,1,'2020-01-01 01:01:01'),(336,20241209164540,1,'2020-01-01 01:01:01'),(337,20241210140021,1,'2020-01-01 01:01:01'),(338,20241219180042,1,'2020-01-01 01:01:01'),(339,20241220100000,1,'2020-01-01 01:01:01'),(340,20241220114903,1,'2020-01-01 01:01:01'),(341,20241220114904,1,'2020-01-01 01:01:01'),(342,20241224000000,1,'2020-01-01 01:01:01'),(343,20241230000000,1,'2020-01-01 01:01:01'),(344,20241231112624,1,'2020-01-01 01:01:01'),(345,20250102121439,1,'2020-01-01 01:01:01'),(346,20250121094045,1,'2020-01-01 01:01:01'),(347,20250121094500,1,'2020-01-01 01:01:01'),(348,20250121094600,1,'2020-01-01 01:01:01'),(349,20250121094700,1,'2020-01-01 01:01:01'),(350,20250124194347,1,'2020-01-01 01:01:01'),(351,20250127162751,1,'2020-01-01 01:01:01'),(352,20250213104005,1,'2020-01-01 01:01:01'),(353,20250214205657,1,'2020-01-01 01:01:01'),(354,20250217093329,1,'2020-01-01 01:01:01'),(355,20250219090511,1,'2020-01-01 01:01:01'),(356,20250219100000,1,'2020-01-01 01:01:01'),(357,20250219142401,1,'2020-01-01 01:01:01'),(358,20250224184002,1,'2020-01-01 01:01:01'),(359,20250225085436,1,'2020-01-01 01:01:01'),(360,20250226000000,1,'2020-01-01 01:01:01'),(361,20250226153445,1,'2020-01-01 01:01:01'),(362,20250304162702,1,'2020-01-01 01:01:01'),(363,20250306144233,1,'2020-01-01 01:01:01'),(364,20250313163430,1,'2020-01-01 01:01:01'),(365,20250317130944,1,'2020-01-01 01:01:01'),(366,20250318165922,1,'2020-01-01 01:01:01'),(367,20250320132525,1,'2020-01-01 01:01:01'),(368,20250320200000,1,'2020-01-01 01:01:01'),(369,20250326161930,1,'2020-01-01 01:01:01'),(370,20250326161931,1,'2020-01-01 01:01:01'),(371,20250331042354,1,'2020-01-01 01:01:01'),(372,20250331154206,1,'2020-01-01 01:01:01'),(373,20250401155831,1,'2020-01-01 01:01:01'),(374,20250408133233,1,'2020-01-01 01:01:01'),(375,20250410104321,1,'2020-01-01 01:01:01'),(376,20250421085116,1,'2020-01-01 01:01:01'),(377,20250422095806,1,'2020-01-01 01:01:01'),(378,20250424153059,1,'2020-01-01 01:01:01'),(379,20250430103833,1,'2020-01-01 01:01:01'),(380,20250430112622,1,'2020-01-01 01:01:01'),(381,20250501162727,1,'2020-01-01 01:01:01'),(382,20250502154517,1,'2020-01-01 01:01:01'),(383,20250502222222,1,'2020-01-01 01:01:01'),(384,20250507170845,1,'2020-01-01 01:01:01'),(385,20250513162912,1,'2020-01-01 01:01:01'),(386,20250519161614,1,'2020-01-01 01:01:01'),(387,20250519170000,1,'2020-01-01 01:01:01'),(388,20250520153848,1,'2020-01-01 01:01:01'),(389,20250528115932,1,'2020-01-01 01:01:01'),(390,20250529102706,1,'2020-01-01 01:01:01'),(391,20250603105558,1,'2020-01-01 01:01:01'),(392,20250609102714,1,'2020-01-01 01:01:01'),(393,20250609112613,1,'2020-01-01 01:01:01'),(394,20250613103810,1,'2020-01-01 01:01:01'),(395,20250616193950,1,'2020-01-01 01:01:01'),(396,20250624140757,1,'2020-01-01 01:01:01'),(397,20250626130239,1,'2020-01-01 01:01:01'),(398,20250629131032,1,'2020-01-01 01:01:01'),(399,20250701155654,1,'2020-01-01 01:01:01'),(400,20250707095725,1,'2020-01-01 01:01:01'),(401,20250716152435,1,'2020-01-01 01:01:01'),(402,20250718091828,1,'2020-01-01 01:01:01'),(403,20250728122229,1,'2020-01-01 01:01:01'),(404,20250731122715,1,'2020-01-01 01:01:01'),(405,20250731151000,1,'2020-01-01 01:01:01'),(406,20250803000000,1,'2020-01-01 01:01:01'),(407,20250805083116,1,'2020-01-01 01:01:01'),(408,20250807140441,1,'2020-01-01 01:01:01'),(409,20250808000000,1,'2020-01-01 01:01:01'),(410,20250811155036,1,'2020-01-01 01:01:01'),(411,20250813205039,1,'2020-01-01 01:01:01'),(412,20250814123333,1,'2020-01-01 01:01:01'),(413,20250815130115,1,'2020-01-01 01:01:01'),(414,20250816115553,1,'2020-01-01 01:01:01'),(415,20250817154557,1,'2020-01-01 01:01:01'),(416,20250825113751,1,'2020-01-01 01:01:01'),(417,20250827113140,1,'2020-01-01 01:01:01'),(418,20250828120836,1,'2020-01-01 01:01:01'),(419,20250902112642,1,'2020-01-01 01:01:01'),(420,20250904091745,1,'2020-01-01 01:01:01'),(421,20250905090000,1,'2020-01-01 01:01:01'),(422,20250922083056,1,'2020-01-01 01:01:01'),(423,20250923120000,1,'2020-01-01 01:01:01'),(424,20250926123048,1,'2020-01-01 01:01:01'),(425,20250929103528,1,'2020-01-01 01:01:01'),(426,20251003094629,1,'2020-01-01 01:01:01'),(427,20251009091733,1,'2020-01-01 01:01:01'),(428,20251010153829,1,'2020-01-01 01:01:01');
+INSERT INTO `migration_status_tables` VALUES (1,0,1,'2020-01-01 01:01:01'),(2,20161118193812,1,'2020-01-01 01:01:01'),(3,20161118211713,1,'2020-01-01 01:01:01'),(4,20161118212436,1,'2020-01-01 01:01:01'),(5,20161118212515,1,'2020-01-01 01:01:01'),(6,20161118212528,1,'2020-01-01 01:01:01'),(7,20161118212538,1,'2020-01-01 01:01:01'),(8,20161118212549,1,'2020-01-01 01:01:01'),(9,20161118212557,1,'2020-01-01 01:01:01'),(10,20161118212604,1,'2020-01-01 01:01:01'),(11,20161118212613,1,'2020-01-01 01:01:01'),(12,20161118212621,1,'2020-01-01 01:01:01'),(13,20161118212630,1,'2020-01-01 01:01:01'),(14,20161118212641,1,'2020-01-01 01:01:01'),(15,20161118212649,1,'2020-01-01 01:01:01'),(16,20161118212656,1,'2020-01-01 01:01:01'),(17,20161118212758,1,'2020-01-01 01:01:01'),(18,20161128234849,1,'2020-01-01 01:01:01'),(19,20161230162221,1,'2020-01-01 01:01:01'),(20,20170104113816,1,'2020-01-01 01:01:01'),(21,20170105151732,1,'2020-01-01 01:01:01'),(22,20170108191242,1,'2020-01-01 01:01:01'),(23,20170109094020,1,'2020-01-01 01:01:01'),(24,20170109130438,1,'2020-01-01 01:01:01'),(25,20170110202752,1,'2020-01-01 01:01:01'),(26,20170111133013,1,'2020-01-01 01:01:01'),(27,20170117025759,1,'2020-01-01 01:01:01'),(28,20170118191001,1,'2020-01-01 01:01:01'),(29,20170119234632,1,'2020-01-01 01:01:01'),(30,20170124230432,1,'2020-01-01 01:01:01'),(31,20170127014618,1,'2020-01-01 01:01:01'),(32,20170131232841,1,'2020-01-01 01:01:01'),(33,20170223094154,1,'2020-01-01 01:01:01'),(34,20170306075207,1,'2020-01-01 01:01:01'),(35,20170309100733,1,'2020-01-01 01:01:01'),(36,20170331111922,1,'2020-01-01 01:01:01'),(37,20170502143928,1,'2020-01-01 01:01:01'),(38,20170504130602,1,'2020-01-01 01:01:01'),(39,20170509132100,1,'2020-01-01 01:01:01'),(40,20170519105647,1,'2020-01-01 01:01:01'),(41,20170519105648,1,'2020-01-01 01:01:01'),(42,20170831234300,1,'2020-01-01 01:01:01'),(43,20170831234301,1,'2020-01-01 01:01:01'),(44,20170831234303,1,'2020-01-01 01:01:01'),(45,20171116163618,1,'2020-01-01 01:01:01'),(46,20171219164727,1,'2020-01-01 01:01:01'),(47,20180620164811,1,'2020-01-01 01:01:01'),(48,20180620175054,1,'2020-01-01 01:01:01'),(49,20180620175055,1,'2020-01-01 01:01:01'),(50,20191010101639,1,'2020-01-01 01:01:01'),(51,20191010155147,1,'2020-01-01 01:01:01'),(52,20191220130734,1,'2020-01-01 01:01:01'),(53,20200311140000,1,'2020-01-01 01:01:01'),(54,20200405120000,1,'2020-01-01 01:01:01'),(55,20200407120000,1,'2020-01-01 01:01:01'),(56,20200420120000,1,'2020-01-01 01:01:01'),(57,20200504120000,1,'2020-01-01 01:01:01'),(58,20200512120000,1,'2020-01-01 01:01:01'),(59,20200707120000,1,'2020-01-01 01:01:01'),(60,20201011162341,1,'2020-01-01 01:01:01'),(61,20201021104586,1,'2020-01-01 01:01:01'),(62,20201102112520,1,'2020-01-01 01:01:01'),(63,20201208121729,1,'2020-01-01 01:01:01'),(64,20201215091637,1,'2020-01-01 01:01:01'),(65,20210119174155,1,'2020-01-01 01:01:01'),(66,20210326182902,1,'2020-01-01 01:01:01'),(67,20210421112652,1,'2020-01-01 01:01:01'),(68,20210506095025,1,'2020-01-01 01:01:01'),(69,20210513115729,1,'2020-01-01 01:01:01'),(70,20210526113559,1,'2020-01-01 01:01:01'),(71,20210601000001,1,'2020-01-01 01:01:01'),(72,20210601000002,1,'2020-01-01 01:01:01'),(73,20210601000003,1,'2020-01-01 01:01:01'),(74,20210601000004,1,'2020-01-01 01:01:01'),(75,20210601000005,1,'2020-01-01 01:01:01'),(76,20210601000006,1,'2020-01-01 01:01:01'),(77,20210601000007,1,'2020-01-01 01:01:01'),(78,20210601000008,1,'2020-01-01 01:01:01'),(79,20210606151329,1,'2020-01-01 01:01:01'),(80,20210616163757,1,'2020-01-01 01:01:01'),(81,20210617174723,1,'2020-01-01 01:01:01'),(82,20210622160235,1,'2020-01-01 01:01:01'),(83,20210623100031,1,'2020-01-01 01:01:01'),(84,20210623133615,1,'2020-01-01 01:01:01'),(85,20210708143152,1,'2020-01-01 01:01:01'),(86,20210709124443,1,'2020-01-01 01:01:01'),(87,20210712155608,1,'2020-01-01 01:01:01'),(88,20210714102108,1,'2020-01-01 01:01:01'),(89,20210719153709,1,'2020-01-01 01:01:01'),(90,20210721171531,1,'2020-01-01 01:01:01'),(91,20210723135713,1,'2020-01-01 01:01:01'),(92,20210802135933,1,'2020-01-01 01:01:01'),(93,20210806112844,1,'2020-01-01 01:01:01'),(94,20210810095603,1,'2020-01-01 01:01:01'),(95,20210811150223,1,'2020-01-01 01:01:01'),(96,20210818151827,1,'2020-01-01 01:01:01'),(97,20210818151828,1,'2020-01-01 01:01:01'),(98,20210818182258,1,'2020-01-01 01:01:01'),(99,20210819131107,1,'2020-01-01 01:01:01'),(100,20210819143446,1,'2020-01-01 01:01:01'),(101,20210903132338,1,'2020-01-01 01:01:01'),(102,20210915144307,1,'2020-01-01 01:01:01'),(103,20210920155130,1,'2020-01-01 01:01:01'),(104,20210927143115,1,'2020-01-01 01:01:01'),(105,20210927143116,1,'2020-01-01 01:01:01'),(106,20211013133706,1,'2020-01-01 01:01:01'),(107,20211013133707,1,'2020-01-01 01:01:01'),(108,20211102135149,1,'2020-01-01 01:01:01'),(109,20211109121546,1,'2020-01-01 01:01:01'),(110,20211110163320,1,'2020-01-01 01:01:01'),(111,20211116184029,1,'2020-01-01 01:01:01'),(112,20211116184030,1,'2020-01-01 01:01:01'),(113,20211202092042,1,'2020-01-01 01:01:01'),(114,20211202181033,1,'2020-01-01 01:01:01'),(115,20211207161856,1,'2020-01-01 01:01:01'),(116,20211216131203,1,'2020-01-01 01:01:01'),(117,20211221110132,1,'2020-01-01 01:01:01'),(118,20220107155700,1,'2020-01-01 01:01:01'),(119,20220125105650,1,'2020-01-01 01:01:01'),(120,20220201084510,1,'2020-01-01 01:01:01'),(121,20220208144830,1,'2020-01-01 01:01:01'),(122,20220208144831,1,'2020-01-01 01:01:01'),(123,20220215152203,1,'2020-01-01 01:01:01'),(124,20220223113157,1,'2020-01-01 01:01:01'),(125,20220307104655,1,'2020-01-01 01:01:01'),(126,20220309133956,1,'2020-01-01 01:01:01'),(127,20220316155700,1,'2020-01-01 01:01:01'),(128,20220323152301,1,'2020-01-01 01:01:01'),(129,20220330100659,1,'2020-01-01 01:01:01'),(130,20220404091216,1,'2020-01-01 01:01:01'),(131,20220419140750,1,'2020-01-01 01:01:01'),(132,20220428140039,1,'2020-01-01 01:01:01'),(133,20220503134048,1,'2020-01-01 01:01:01'),(134,20220524102918,1,'2020-01-01 01:01:01'),(135,20220526123327,1,'2020-01-01 01:01:01'),(136,20220526123328,1,'2020-01-01 01:01:01'),(137,20220526123329,1,'2020-01-01 01:01:01'),(138,20220608113128,1,'2020-01-01 01:01:01'),(139,20220627104817,1,'2020-01-01 01:01:01'),(140,20220704101843,1,'2020-01-01 01:01:01'),(141,20220708095046,1,'2020-01-01 01:01:01'),(142,20220713091130,1,'2020-01-01 01:01:01'),(143,20220802135510,1,'2020-01-01 01:01:01'),(144,20220818101352,1,'2020-01-01 01:01:01'),(145,20220822161445,1,'2020-01-01 01:01:01'),(146,20220831100036,1,'2020-01-01 01:01:01'),(147,20220831100151,1,'2020-01-01 01:01:01'),(148,20220908181826,1,'2020-01-01 01:01:01'),(149,20220914154915,1,'2020-01-01 01:01:01'),(150,20220915165115,1,'2020-01-01 01:01:01'),(151,20220915165116,1,'2020-01-01 01:01:01'),(152,20220928100158,1,'2020-01-01 01:01:01'),(153,20221014084130,1,'2020-01-01 01:01:01'),(154,20221027085019,1,'2020-01-01 01:01:01'),(155,20221101103952,1,'2020-01-01 01:01:01'),(156,20221104144401,1,'2020-01-01 01:01:01'),(157,20221109100749,1,'2020-01-01 01:01:01'),(158,20221115104546,1,'2020-01-01 01:01:01'),(159,20221130114928,1,'2020-01-01 01:01:01'),(160,20221205112142,1,'2020-01-01 01:01:01'),(161,20221216115820,1,'2020-01-01 01:01:01'),(162,20221220195934,1,'2020-01-01 01:01:01'),(163,20221220195935,1,'2020-01-01 01:01:01'),(164,20221223174807,1,'2020-01-01 01:01:01'),(165,20221227163855,1,'2020-01-01 01:01:01'),(166,20221227163856,1,'2020-01-01 01:01:01'),(167,20230202224725,1,'2020-01-01 01:01:01'),(168,20230206163608,1,'2020-01-01 01:01:01'),(169,20230214131519,1,'2020-01-01 01:01:01'),(170,20230303135738,1,'2020-01-01 01:01:01'),(171,20230313135301,1,'2020-01-01 01:01:01'),(172,20230313141819,1,'2020-01-01 01:01:01'),(173,20230315104937,1,'2020-01-01 01:01:01'),(174,20230317173844,1,'2020-01-01 01:01:01'),(175,20230320133602,1,'2020-01-01 01:01:01'),(176,20230330100011,1,'2020-01-01 01:01:01'),(177,20230330134823,1,'2020-01-01 01:01:01'),(178,20230405232025,1,'2020-01-01 01:01:01'),(179,20230408084104,1,'2020-01-01 01:01:01'),(180,20230411102858,1,'2020-01-01 01:01:01'),(181,20230421155932,1,'2020-01-01 01:01:01'),(182,20230425082126,1,'2020-01-01 01:01:01'),(183,20230425105727,1,'2020-01-01 01:01:01'),(184,20230501154913,1,'2020-01-01 01:01:01'),(185,20230503101418,1,'2020-01-01 01:01:01'),(186,20230515144206,1,'2020-01-01 01:01:01'),(187,20230517140952,1,'2020-01-01 01:01:01'),(188,20230517152807,1,'2020-01-01 01:01:01'),(189,20230518114155,1,'2020-01-01 01:01:01'),(190,20230520153236,1,'2020-01-01 01:01:01'),(191,20230525151159,1,'2020-01-01 01:01:01'),(192,20230530122103,1,'2020-01-01 01:01:01'),(193,20230602111827,1,'2020-01-01 01:01:01'),(194,20230608103123,1,'2020-01-01 01:01:01'),(195,20230629140529,1,'2020-01-01 01:01:01'),(196,20230629140530,1,'2020-01-01 01:01:01'),(197,20230711144622,1,'2020-01-01 01:01:01'),(198,20230721135421,1,'2020-01-01 01:01:01'),(199,20230721161508,1,'2020-01-01 01:01:01'),(200,20230726115701,1,'2020-01-01 01:01:01'),(201,20230807100822,1,'2020-01-01 01:01:01'),(202,20230814150442,1,'2020-01-01 01:01:01'),(203,20230823122728,1,'2020-01-01 01:01:01'),(204,20230906152143,1,'2020-01-01 01:01:01'),(205,20230911163618,1,'2020-01-01 01:01:01'),(206,20230912101759,1,'2020-01-01 01:01:01'),(207,20230915101341,1,'2020-01-01 01:01:01'),(208,20230918132351,1,'2020-01-01 01:01:01'),(209,20231004144339,1,'2020-01-01 01:01:01'),(210,20231009094541,1,'2020-01-01 01:01:01'),(211,20231009094542,1,'2020-01-01 01:01:01'),(212,20231009094543,1,'2020-01-01 01:01:01'),(213,20231009094544,1,'2020-01-01 01:01:01'),(214,20231016091915,1,'2020-01-01 01:01:01'),(215,20231024174135,1,'2020-01-01 01:01:01'),(216,20231025120016,1,'2020-01-01 01:01:01'),(217,20231025160156,1,'2020-01-01 01:01:01'),(218,20231031165350,1,'2020-01-01 01:01:01'),(219,20231106144110,1,'2020-01-01 01:01:01'),(220,20231107130934,1,'2020-01-01 01:01:01'),(221,20231109115838,1,'2020-01-01 01:01:01'),(222,20231121054530,1,'2020-01-01 01:01:01'),(223,20231122101320,1,'2020-01-01 01:01:01'),(224,20231130132828,1,'2020-01-01 01:01:01'),(225,20231130132931,1,'2020-01-01 01:01:01'),(226,20231204155427,1,'2020-01-01 01:01:01'),(227,20231206142340,1,'2020-01-01 01:01:01'),(228,20231207102320,1,'2020-01-01 01:01:01'),(229,20231207102321,1,'2020-01-01 01:01:01'),(230,20231207133731,1,'2020-01-01 01:01:01'),(231,20231212094238,1,'2020-01-01 01:01:01'),(232,20231212095734,1,'2020-01-01 01:01:01'),(233,20231212161121,1,'2020-01-01 01:01:01'),(234,20231215122713,1,'2020-01-01 01:01:01'),(235,20231219143041,1,'2020-01-01 01:01:01'),(236,20231224070653,1,'2020-01-01 01:01:01'),(237,20240110134315,1,'2020-01-01 01:01:01'),(238,20240119091637,1,'2020-01-01 01:01:01'),(239,20240126020642,1,'2020-01-01 01:01:01'),(240,20240126020643,1,'2020-01-01 01:01:01'),(241,20240129162819,1,'2020-01-01 01:01:01'),(242,20240130115133,1,'2020-01-01 01:01:01'),(243,20240131083822,1,'2020-01-01 01:01:01'),(244,20240205095928,1,'2020-01-01 01:01:01'),(245,20240205121956,1,'2020-01-01 01:01:01'),(246,20240209110212,1,'2020-01-01 01:01:01'),(247,20240212111533,1,'2020-01-01 01:01:01'),(248,20240221112844,1,'2020-01-01 01:01:01'),(249,20240222073518,1,'2020-01-01 01:01:01'),(250,20240222135115,1,'2020-01-01 01:01:01'),(251,20240226082255,1,'2020-01-01 01:01:01'),(252,20240228082706,1,'2020-01-01 01:01:01'),(253,20240301173035,1,'2020-01-01 01:01:01'),(254,20240302111134,1,'2020-01-01 01:01:01'),(255,20240312103753,1,'2020-01-01 01:01:01'),(256,20240313143416,1,'2020-01-01 01:01:01'),(257,20240314085226,1,'2020-01-01 01:01:01'),(258,20240314151747,1,'2020-01-01 01:01:01'),(259,20240320145650,1,'2020-01-01 01:01:01'),(260,20240327115530,1,'2020-01-01 01:01:01'),(261,20240327115617,1,'2020-01-01 01:01:01'),(262,20240408085837,1,'2020-01-01 01:01:01'),(263,20240415104633,1,'2020-01-01 01:01:01'),(264,20240430111727,1,'2020-01-01 01:01:01'),(265,20240515200020,1,'2020-01-01 01:01:01'),(266,20240521143023,1,'2020-01-01 01:01:01'),(267,20240521143024,1,'2020-01-01 01:01:01'),(268,20240601174138,1,'2020-01-01 01:01:01'),(269,20240607133721,1,'2020-01-01 01:01:01'),(270,20240612150059,1,'2020-01-01 01:01:01'),(271,20240613162201,1,'2020-01-01 01:01:01'),(272,20240613172616,1,'2020-01-01 01:01:01'),(273,20240618142419,1,'2020-01-01 01:01:01'),(274,20240625093543,1,'2020-01-01 01:01:01'),(275,20240626195531,1,'2020-01-01 01:01:01'),(276,20240702123921,1,'2020-01-01 01:01:01'),(277,20240703154849,1,'2020-01-01 01:01:01'),(278,20240707134035,1,'2020-01-01 01:01:01'),(279,20240707134036,1,'2020-01-01 01:01:01'),(280,20240709124958,1,'2020-01-01 01:01:01'),(281,20240709132642,1,'2020-01-01 01:01:01'),(282,20240709183940,1,'2020-01-01 01:01:01'),(283,20240710155623,1,'2020-01-01 01:01:01'),(284,20240723102712,1,'2020-01-01 01:01:01'),(285,20240725152735,1,'2020-01-01 01:01:01'),(286,20240725182118,1,'2020-01-01 01:01:01'),(287,20240726100517,1,'2020-01-01 01:01:01'),(288,20240730171504,1,'2020-01-01 01:01:01'),(289,20240730174056,1,'2020-01-01 01:01:01'),(290,20240730215453,1,'2020-01-01 01:01:01'),(291,20240730374423,1,'2020-01-01 01:01:01'),(292,20240801115359,1,'2020-01-01 01:01:01'),(293,20240802101043,1,'2020-01-01 01:01:01'),(294,20240802113716,1,'2020-01-01 01:01:01'),(295,20240814135330,1,'2020-01-01 01:01:01'),(296,20240815000000,1,'2020-01-01 01:01:01'),(297,20240815000001,1,'2020-01-01 01:01:01'),(298,20240816103247,1,'2020-01-01 01:01:01'),(299,20240820091218,1,'2020-01-01 01:01:01'),(300,20240826111228,1,'2020-01-01 01:01:01'),(301,20240826160025,1,'2020-01-01 01:01:01'),(302,20240829165448,1,'2020-01-01 01:01:01'),(303,20240829165605,1,'2020-01-01 01:01:01'),(304,20240829165715,1,'2020-01-01 01:01:01'),(305,20240829165930,1,'2020-01-01 01:01:01'),(306,20240829170023,1,'2020-01-01 01:01:01'),(307,20240829170033,1,'2020-01-01 01:01:01'),(308,20240829170044,1,'2020-01-01 01:01:01'),(309,20240905105135,1,'2020-01-01 01:01:01'),(310,20240905140514,1,'2020-01-01 01:01:01'),(311,20240905200000,1,'2020-01-01 01:01:01'),(312,20240905200001,1,'2020-01-01 01:01:01'),(313,20241002104104,1,'2020-01-01 01:01:01'),(314,20241002104105,1,'2020-01-01 01:01:01'),(315,20241002104106,1,'2020-01-01 01:01:01'),(316,20241002210000,1,'2020-01-01 01:01:01'),(317,20241003145349,1,'2020-01-01 01:01:01'),(318,20241004005000,1,'2020-01-01 01:01:01'),(319,20241008083925,1,'2020-01-01 01:01:01'),(320,20241009090010,1,'2020-01-01 01:01:01'),(321,20241017163402,1,'2020-01-01 01:01:01'),(322,20241021224359,1,'2020-01-01 01:01:01'),(323,20241022140321,1,'2020-01-01 01:01:01'),(324,20241025111236,1,'2020-01-01 01:01:01'),(325,20241025112748,1,'2020-01-01 01:01:01'),(326,20241025141855,1,'2020-01-01 01:01:01'),(327,20241110152839,1,'2020-01-01 01:01:01'),(328,20241110152840,1,'2020-01-01 01:01:01'),(329,20241110152841,1,'2020-01-01 01:01:01'),(330,20241116233322,1,'2020-01-01 01:01:01'),(331,20241122171434,1,'2020-01-01 01:01:01'),(332,20241125150614,1,'2020-01-01 01:01:01'),(333,20241203125346,1,'2020-01-01 01:01:01'),(334,20241203130032,1,'2020-01-01 01:01:01'),(335,20241205122800,1,'2020-01-01 01:01:01'),(336,20241209164540,1,'2020-01-01 01:01:01'),(337,20241210140021,1,'2020-01-01 01:01:01'),(338,20241219180042,1,'2020-01-01 01:01:01'),(339,20241220100000,1,'2020-01-01 01:01:01'),(340,20241220114903,1,'2020-01-01 01:01:01'),(341,20241220114904,1,'2020-01-01 01:01:01'),(342,20241224000000,1,'2020-01-01 01:01:01'),(343,20241230000000,1,'2020-01-01 01:01:01'),(344,20241231112624,1,'2020-01-01 01:01:01'),(345,20250102121439,1,'2020-01-01 01:01:01'),(346,20250121094045,1,'2020-01-01 01:01:01'),(347,20250121094500,1,'2020-01-01 01:01:01'),(348,20250121094600,1,'2020-01-01 01:01:01'),(349,20250121094700,1,'2020-01-01 01:01:01'),(350,20250124194347,1,'2020-01-01 01:01:01'),(351,20250127162751,1,'2020-01-01 01:01:01'),(352,20250213104005,1,'2020-01-01 01:01:01'),(353,20250214205657,1,'2020-01-01 01:01:01'),(354,20250217093329,1,'2020-01-01 01:01:01'),(355,20250219090511,1,'2020-01-01 01:01:01'),(356,20250219100000,1,'2020-01-01 01:01:01'),(357,20250219142401,1,'2020-01-01 01:01:01'),(358,20250224184002,1,'2020-01-01 01:01:01'),(359,20250225085436,1,'2020-01-01 01:01:01'),(360,20250226000000,1,'2020-01-01 01:01:01'),(361,20250226153445,1,'2020-01-01 01:01:01'),(362,20250304162702,1,'2020-01-01 01:01:01'),(363,20250306144233,1,'2020-01-01 01:01:01'),(364,20250313163430,1,'2020-01-01 01:01:01'),(365,20250317130944,1,'2020-01-01 01:01:01'),(366,20250318165922,1,'2020-01-01 01:01:01'),(367,20250320132525,1,'2020-01-01 01:01:01'),(368,20250320200000,1,'2020-01-01 01:01:01'),(369,20250326161930,1,'2020-01-01 01:01:01'),(370,20250326161931,1,'2020-01-01 01:01:01'),(371,20250331042354,1,'2020-01-01 01:01:01'),(372,20250331154206,1,'2020-01-01 01:01:01'),(373,20250401155831,1,'2020-01-01 01:01:01'),(374,20250408133233,1,'2020-01-01 01:01:01'),(375,20250410104321,1,'2020-01-01 01:01:01'),(376,20250421085116,1,'2020-01-01 01:01:01'),(377,20250422095806,1,'2020-01-01 01:01:01'),(378,20250424153059,1,'2020-01-01 01:01:01'),(379,20250430103833,1,'2020-01-01 01:01:01'),(380,20250430112622,1,'2020-01-01 01:01:01'),(381,20250501162727,1,'2020-01-01 01:01:01'),(382,20250502154517,1,'2020-01-01 01:01:01'),(383,20250502222222,1,'2020-01-01 01:01:01'),(384,20250507170845,1,'2020-01-01 01:01:01'),(385,20250513162912,1,'2020-01-01 01:01:01'),(386,20250519161614,1,'2020-01-01 01:01:01'),(387,20250519170000,1,'2020-01-01 01:01:01'),(388,20250520153848,1,'2020-01-01 01:01:01'),(389,20250528115932,1,'2020-01-01 01:01:01'),(390,20250529102706,1,'2020-01-01 01:01:01'),(391,20250603105558,1,'2020-01-01 01:01:01'),(392,20250609102714,1,'2020-01-01 01:01:01'),(393,20250609112613,1,'2020-01-01 01:01:01'),(394,20250613103810,1,'2020-01-01 01:01:01'),(395,20250616193950,1,'2020-01-01 01:01:01'),(396,20250624140757,1,'2020-01-01 01:01:01'),(397,20250626130239,1,'2020-01-01 01:01:01'),(398,20250629131032,1,'2020-01-01 01:01:01'),(399,20250701155654,1,'2020-01-01 01:01:01'),(400,20250707095725,1,'2020-01-01 01:01:01'),(401,20250716152435,1,'2020-01-01 01:01:01'),(402,20250718091828,1,'2020-01-01 01:01:01'),(403,20250728122229,1,'2020-01-01 01:01:01'),(404,20250731122715,1,'2020-01-01 01:01:01'),(405,20250731151000,1,'2020-01-01 01:01:01'),(406,20250803000000,1,'2020-01-01 01:01:01'),(407,20250805083116,1,'2020-01-01 01:01:01'),(408,20250807140441,1,'2020-01-01 01:01:01'),(409,20250808000000,1,'2020-01-01 01:01:01'),(410,20250811155036,1,'2020-01-01 01:01:01'),(411,20250813205039,1,'2020-01-01 01:01:01'),(412,20250814123333,1,'2020-01-01 01:01:01'),(413,20250815130115,1,'2020-01-01 01:01:01'),(414,20250816115553,1,'2020-01-01 01:01:01'),(415,20250817154557,1,'2020-01-01 01:01:01'),(416,20250825113751,1,'2020-01-01 01:01:01'),(417,20250827113140,1,'2020-01-01 01:01:01'),(418,20250828120836,1,'2020-01-01 01:01:01'),(419,20250902112642,1,'2020-01-01 01:01:01'),(420,20250904091745,1,'2020-01-01 01:01:01'),(421,20250905090000,1,'2020-01-01 01:01:01'),(422,20250922083056,1,'2020-01-01 01:01:01'),(423,20250923120000,1,'2020-01-01 01:01:01'),(424,20250926123048,1,'2020-01-01 01:01:01'),(425,20250929103528,1,'2020-01-01 01:01:01'),(426,20251003094629,1,'2020-01-01 01:01:01'),(427,20251009091733,1,'2020-01-01 01:01:01'),(428,20251010153829,1,'2020-01-01 01:01:01'),(429,20251013172310,1,'2020-01-01 01:01:01');
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `mobile_device_management_solutions` (
diff --git a/server/fleet/datastore.go b/server/fleet/datastore.go
index 2147241c2112..1fd8446e969a 100644
--- a/server/fleet/datastore.go
+++ b/server/fleet/datastore.go
@@ -987,7 +987,9 @@ type Datastore interface {
UpdateMDMData(ctx context.Context, hostID uint, enrolled bool) error
// GetHostEmails returns the emails associated with the provided host for a given source, such as "google_chrome_profiles"
GetHostEmails(ctx context.Context, hostUUID string, source string) ([]string, error)
- SetOrUpdateHostDisksSpace(ctx context.Context, hostID uint, gigsAvailable, percentAvailable, gigsTotal float64) error
+ // SetOrUpdateHostDisksSpace sets or updates the gigs_total_disk_space and gigs_all_disk_space
+ // fields for a host. gigs_all_disk_space should should only be non-nil for Linux hosts
+ SetOrUpdateHostDisksSpace(ctx context.Context, hostID uint, gigsAvailable, percentAvailable, gigsTotal float64, gigsAll *float64) error
GetConfigEnableDiskEncryption(ctx context.Context, teamID *uint) (DiskEncryptionConfig, error)
SetOrUpdateHostDiskTpmPIN(ctx context.Context, hostID uint, pinSet bool) error
diff --git a/server/fleet/hosts.go b/server/fleet/hosts.go
index 03d7978e7f76..b3142c460c29 100644
--- a/server/fleet/hosts.go
+++ b/server/fleet/hosts.go
@@ -339,7 +339,10 @@ type Host struct {
GigsDiskSpaceAvailable float64 `json:"gigs_disk_space_available" db:"gigs_disk_space_available" csv:"gigs_disk_space_available"`
PercentDiskSpaceAvailable float64 `json:"percent_disk_space_available" db:"percent_disk_space_available" csv:"percent_disk_space_available"`
- GigsTotalDiskSpace float64 `json:"gigs_total_disk_space" db:"gigs_total_disk_space" csv:"gigs_total_disk_space"`
+ // GigsTotalDiskSpace and GigsAllDiskSpace as defined by `server > service > osquery_utils >
+ // queries.go > hostDetailQueries.disk_space_unix`
+ GigsTotalDiskSpace float64 `json:"gigs_total_disk_space" db:"gigs_total_disk_space" csv:"gigs_total_disk_space"`
+ GigsAllDiskSpace *float64 `json:"gigs_all_disk_space" db:"gigs_all_disk_space" csv:"gigs_all_disk_space"`
// DiskEncryptionEnabled is only returned by GET /host/{id} and so is not
// exportable as CSV (which is the result of List Hosts endpoint). It is
diff --git a/server/mock/datastore_mock.go b/server/mock/datastore_mock.go
index 5b2c74c4e21d..3f74e8859e64 100644
--- a/server/mock/datastore_mock.go
+++ b/server/mock/datastore_mock.go
@@ -707,7 +707,7 @@ type UpdateMDMDataFunc func(ctx context.Context, hostID uint, enrolled bool) err
type GetHostEmailsFunc func(ctx context.Context, hostUUID string, source string) ([]string, error)
-type SetOrUpdateHostDisksSpaceFunc func(ctx context.Context, hostID uint, gigsAvailable float64, percentAvailable float64, gigsTotal float64) error
+type SetOrUpdateHostDisksSpaceFunc func(ctx context.Context, hostID uint, gigsAvailable float64, percentAvailable float64, gigsTotal float64, gigsAll *float64) error
type GetConfigEnableDiskEncryptionFunc func(ctx context.Context, teamID *uint) (fleet.DiskEncryptionConfig, error)
@@ -6246,11 +6246,11 @@ func (s *DataStore) GetHostEmails(ctx context.Context, hostUUID string, source s
return s.GetHostEmailsFunc(ctx, hostUUID, source)
}
-func (s *DataStore) SetOrUpdateHostDisksSpace(ctx context.Context, hostID uint, gigsAvailable float64, percentAvailable float64, gigsTotal float64) error {
+func (s *DataStore) SetOrUpdateHostDisksSpace(ctx context.Context, hostID uint, gigsAvailable float64, percentAvailable float64, gigsTotal float64, gigsAll *float64) error {
s.mu.Lock()
s.SetOrUpdateHostDisksSpaceFuncInvoked = true
s.mu.Unlock()
- return s.SetOrUpdateHostDisksSpaceFunc(ctx, hostID, gigsAvailable, percentAvailable, gigsTotal)
+ return s.SetOrUpdateHostDisksSpaceFunc(ctx, hostID, gigsAvailable, percentAvailable, gigsTotal, gigsAll)
}
func (s *DataStore) GetConfigEnableDiskEncryption(ctx context.Context, teamID *uint) (fleet.DiskEncryptionConfig, error) {
diff --git a/server/service/apple_mdm.go b/server/service/apple_mdm.go
index f75bca354d43..4c41bff42880 100644
--- a/server/service/apple_mdm.go
+++ b/server/service/apple_mdm.go
@@ -4105,7 +4105,7 @@ func (svc *MDMAppleCheckinAndCommandService) handleRefetchDeviceResults(ctx cont
return nil, ctxerr.Wrap(ctx, err, "failed to update host")
}
if err := svc.ds.SetOrUpdateHostDisksSpace(ctx, host.ID, availableDeviceCapacity, 100*availableDeviceCapacity/deviceCapacity,
- deviceCapacity); err != nil {
+ deviceCapacity, nil); err != nil {
return nil, ctxerr.Wrap(ctx, err, "failed to update host storage")
}
if err := svc.ds.UpdateHostOperatingSystem(ctx, host.ID, fleet.OperatingSystem{
diff --git a/server/service/apple_mdm_test.go b/server/service/apple_mdm_test.go
index 4caf6a264628..5eb0fd3cf779 100644
--- a/server/service/apple_mdm_test.go
+++ b/server/service/apple_mdm_test.go
@@ -4502,7 +4502,7 @@ func TestMDMCommandAndReportResultsIOSIPadOSRefetch(t *testing.T) {
require.WithinDuration(t, time.Now(), host.DetailUpdatedAt, 1*time.Minute)
return nil
}
- ds.SetOrUpdateHostDisksSpaceFunc = func(ctx context.Context, incomingHostID uint, gigsAvailable, percentAvailable, gigsTotal float64) error {
+ ds.SetOrUpdateHostDisksSpaceFunc = func(ctx context.Context, incomingHostID uint, gigsAvailable, percentAvailable, gigsTotal float64, gigsAll *float64) error {
require.Equal(t, hostID, incomingHostID)
require.NotZero(t, 51, int64(gigsAvailable))
require.NotZero(t, 79, int64(percentAvailable))
diff --git a/server/service/integration_core_test.go b/server/service/integration_core_test.go
index 1d77ae7ac211..0267ef18c36c 100644
--- a/server/service/integration_core_test.go
+++ b/server/service/integration_core_test.go
@@ -1295,8 +1295,8 @@ func (s *integrationTestSuite) TestHostsCount() {
hosts := s.createHosts(t, "darwin", "darwin", "darwin")
// set disk space information for some hosts
- require.NoError(t, s.ds.SetOrUpdateHostDisksSpace(context.Background(), hosts[0].ID, 10.0, 2.0, 500.0)) // low disk
- require.NoError(t, s.ds.SetOrUpdateHostDisksSpace(context.Background(), hosts[1].ID, 40.0, 4.0, 1000.0)) // not low disk
+ require.NoError(t, s.ds.SetOrUpdateHostDisksSpace(context.Background(), hosts[0].ID, 10.0, 2.0, 500.0, nil)) // low disk
+ require.NoError(t, s.ds.SetOrUpdateHostDisksSpace(context.Background(), hosts[1].ID, 40.0, 4.0, 1000.0, nil)) // not low disk
label := &fleet.Label{
Name: t.Name() + "foo",
@@ -1513,8 +1513,8 @@ func (s *integrationTestSuite) TestListHosts() {
hosts := s.createHosts(t, "darwin", "darwin", "darwin")
// set disk space information for some hosts
- require.NoError(t, s.ds.SetOrUpdateHostDisksSpace(context.Background(), hosts[0].ID, 10.0, 2.0, 500.0)) // low disk
- require.NoError(t, s.ds.SetOrUpdateHostDisksSpace(context.Background(), hosts[1].ID, 40.0, 4.0, 1000.0)) // not low disk
+ require.NoError(t, s.ds.SetOrUpdateHostDisksSpace(context.Background(), hosts[0].ID, 10.0, 2.0, 500.0, nil)) // low disk
+ require.NoError(t, s.ds.SetOrUpdateHostDisksSpace(context.Background(), hosts[1].ID, 40.0, 4.0, 1000.0, nil)) // not low disk
var resp listHostsResponse
s.DoJSON("GET", "/api/latest/fleet/hosts", nil, http.StatusOK, &resp)
@@ -2386,13 +2386,15 @@ func (s *integrationTestSuite) TestGetHostSummary() {
require.NoError(t, s.ds.AddHostsToTeam(ctx, fleet.NewAddHostsToTeamParams(&team1.ID, []uint{hosts[0].ID})))
// set disk space information for hosts [0] and [1]
- require.NoError(t, s.ds.SetOrUpdateHostDisksSpace(ctx, hosts[0].ID, 1.0, 2.0, 500.0))
- require.NoError(t, s.ds.SetOrUpdateHostDisksSpace(ctx, hosts[1].ID, 3.0, 4.0, 1000.0))
+ require.NoError(t, s.ds.SetOrUpdateHostDisksSpace(ctx, hosts[0].ID, 1.0, 2.0, 500.0, ptr.Float64(600.0)))
+ require.NoError(t, s.ds.SetOrUpdateHostDisksSpace(ctx, hosts[1].ID, 3.0, 4.0, 1000.0, ptr.Float64(1200.0)))
var getHostResp getHostResponse
s.DoJSON("GET", fmt.Sprintf("/api/latest/fleet/hosts/%d", hosts[0].ID), nil, http.StatusOK, &getHostResp)
assert.Equal(t, 1.0, getHostResp.Host.GigsDiskSpaceAvailable)
assert.Equal(t, 2.0, getHostResp.Host.PercentDiskSpaceAvailable)
+ assert.Equal(t, 500.0, getHostResp.Host.GigsTotalDiskSpace)
+ assert.Equal(t, ptr.Float64(600.0), getHostResp.Host.GigsAllDiskSpace)
var resp getHostSummaryResponse
@@ -4871,7 +4873,7 @@ func (s *integrationTestSuite) TestListHostsByLabel() {
)
// set disk space information
- require.NoError(t, s.ds.SetOrUpdateHostDisksSpace(context.Background(), host.ID, 10.0, 2.0, 500.0)) // low disk
+ require.NoError(t, s.ds.SetOrUpdateHostDisksSpace(context.Background(), host.ID, 10.0, 2.0, 500.0, nil)) // low disk
// Update host fields
host.Uptime = 30 * time.Second
@@ -8156,8 +8158,8 @@ func (s *integrationTestSuite) TestSearchHosts() {
hosts := s.createHosts(t)
// set disk space information for hosts [0] and [1]
- require.NoError(t, s.ds.SetOrUpdateHostDisksSpace(ctx, hosts[0].ID, 1.0, 2.0, 500.0))
- require.NoError(t, s.ds.SetOrUpdateHostDisksSpace(ctx, hosts[1].ID, 3.0, 4.0, 1000.0))
+ require.NoError(t, s.ds.SetOrUpdateHostDisksSpace(ctx, hosts[0].ID, 1.0, 2.0, 500.0, ptr.Float64(600.0)))
+ require.NoError(t, s.ds.SetOrUpdateHostDisksSpace(ctx, hosts[1].ID, 3.0, 4.0, 1000.0, ptr.Float64(1200.0)))
// no search criteria
var searchResp searchHostsResponse
@@ -8168,9 +8170,13 @@ func (s *integrationTestSuite) TestSearchHosts() {
case hosts[0].ID:
assert.Equal(t, 1.0, h.GigsDiskSpaceAvailable)
assert.Equal(t, 2.0, h.PercentDiskSpaceAvailable)
+ assert.Equal(t, 500.0, h.GigsTotalDiskSpace)
+ assert.Equal(t, ptr.Float64(600.0), h.GigsAllDiskSpace)
case hosts[1].ID:
assert.Equal(t, 3.0, h.GigsDiskSpaceAvailable)
assert.Equal(t, 4.0, h.PercentDiskSpaceAvailable)
+ assert.Equal(t, 1000.0, h.GigsTotalDiskSpace)
+ assert.Equal(t, ptr.Float64(1200.0), h.GigsAllDiskSpace)
}
assert.Equal(t, h.SoftwareUpdatedAt, h.CreatedAt)
}
@@ -9048,8 +9054,8 @@ func (s *integrationTestSuite) TestHostsReportDownload() {
require.NoError(t, err)
// set disk space information for hosts [0] and [1]
- require.NoError(t, s.ds.SetOrUpdateHostDisksSpace(ctx, hosts[0].ID, 1.0, 2.0, 500.0))
- require.NoError(t, s.ds.SetOrUpdateHostDisksSpace(ctx, hosts[1].ID, 3.0, 4.0, 1000.0))
+ require.NoError(t, s.ds.SetOrUpdateHostDisksSpace(ctx, hosts[0].ID, 1.0, 2.0, 500.0, ptr.Float64(600.0)))
+ require.NoError(t, s.ds.SetOrUpdateHostDisksSpace(ctx, hosts[1].ID, 3.0, 4.0, 1000.0, ptr.Float64(1200.0)))
// create software for host [0]
software := []fleet.Software{
@@ -9087,11 +9093,11 @@ func (s *integrationTestSuite) TestHostsReportDownload() {
res.Body.Close()
require.NoError(t, err)
require.Len(t, rows, len(hosts)+1) // all hosts + header row
- assert.Len(t, rows[0], 54) // total number of cols
+ assert.Len(t, rows[0], 55) // total number of cols
const (
idCol = 3
- issuesCol = 45
+ issuesCol = 46
gigsDiskCol = 42
pctDiskCol = 43
gigsTotalCol = 44
@@ -9463,7 +9469,7 @@ func (s *integrationTestSuite) TestGetHostDiskEncryption() {
// before any disk encryption is received, all hosts report NULL (even if
// some have disk space information, i.e. an entry exists in host_disks).
- require.NoError(t, s.ds.SetOrUpdateHostDisksSpace(context.Background(), hostWin.ID, 44.5, 55.6, 90.0))
+ require.NoError(t, s.ds.SetOrUpdateHostDisksSpace(context.Background(), hostWin.ID, 44.5, 55.6, 90.0, nil))
var getHostResp getHostResponse
s.DoJSON("GET", fmt.Sprintf("/api/latest/fleet/hosts/%d", hostWin.ID), nil, http.StatusOK, &getHostResp)
@@ -11420,7 +11426,7 @@ func (s *integrationTestSuite) TestHostsReportWithPolicyResults() {
res.Body.Close()
require.NoError(t, err)
require.Len(t, rows1, len(hosts)+1) // all hosts + header row
- assert.Len(t, rows1[0], 54) // total number of cols
+ assert.Len(t, rows1[0], 55) // total number of cols
var (
idIdx int
@@ -11450,7 +11456,7 @@ func (s *integrationTestSuite) TestHostsReportWithPolicyResults() {
res.Body.Close()
require.NoError(t, err)
require.Len(t, rows2, len(hosts)+1) // all hosts + header row
- assert.Len(t, rows2[0], 54) // total number of cols
+ assert.Len(t, rows2[0], 55) // total number of cols
// Check that all hosts have 0 issues and that they match the previous call to `/hosts/report`.
for i := 1; i < len(hosts)+1; i++ {
diff --git a/server/service/integration_enterprise_test.go b/server/service/integration_enterprise_test.go
index 45dc5819cb50..0f04c6da4c62 100644
--- a/server/service/integration_enterprise_test.go
+++ b/server/service/integration_enterprise_test.go
@@ -4373,8 +4373,8 @@ func (s *integrationEnterpriseTestSuite) TestListHosts() {
require.NotNil(t, host3)
// set disk space information for some hosts (none provided for host3)
- require.NoError(t, s.ds.SetOrUpdateHostDisksSpace(context.Background(), host1.ID, 10.0, 2.0, 500.0))
- require.NoError(t, s.ds.SetOrUpdateHostDisksSpace(context.Background(), host2.ID, 32.0, 4.0, 1000.0))
+ require.NoError(t, s.ds.SetOrUpdateHostDisksSpace(context.Background(), host1.ID, 10.0, 2.0, 500.0, nil))
+ require.NoError(t, s.ds.SetOrUpdateHostDisksSpace(context.Background(), host2.ID, 32.0, 4.0, 1000.0, ptr.Float64(1200.0)))
var resp listHostsResponse
s.DoJSON("GET", "/api/latest/fleet/hosts", nil, http.StatusOK, &resp)
diff --git a/server/service/osquery_test.go b/server/service/osquery_test.go
index 526b823d1b88..6f6fa0a9717f 100644
--- a/server/service/osquery_test.go
+++ b/server/service/osquery_test.go
@@ -1838,7 +1838,7 @@ func TestDetailQueries(t *testing.T) {
require.Equal(t, "foo", authToken)
return nil
}
- ds.SetOrUpdateHostDisksSpaceFunc = func(ctx context.Context, hostID uint, gigsAvailable, percentAvailable, gigsTotal float64) error {
+ ds.SetOrUpdateHostDisksSpaceFunc = func(ctx context.Context, hostID uint, gigsAvailable, percentAvailable, gigsTotal float64, gigsAll *float64) error {
require.Equal(t, 277.0, gigsAvailable)
require.Equal(t, 56.0, percentAvailable)
require.Equal(t, 500.1, gigsTotal)
diff --git a/server/service/osquery_utils/queries.go b/server/service/osquery_utils/queries.go
index f2b404be9974..76293ebebd5c 100644
--- a/server/service/osquery_utils/queries.go
+++ b/server/service/osquery_utils/queries.go
@@ -125,6 +125,56 @@ ORDER BY
inet_aton(ia.address) IS NOT NULL DESC
LIMIT 1;`
+const linuxGigsAllDiskSpaceSubQueryConditions = `WHERE
+-- exclude mounts with no space
+blocks > 0
+AND blocks_size > 0
+
+-- exclude external storage
+AND path NOT LIKE '/media%' AND path NOT LIKE '/mnt%'
+
+-- exclude device drivers
+AND path NOT LIKE '/dev%'
+
+-- exclude kernel-related mounts
+AND path NOT LIKE '/proc%'
+AND path NOT LIKE '/sys%'
+
+-- exclude process files
+AND path NOT LIKE '/run%'
+AND path NOT LIKE '/var/run%'
+
+-- exclude boot files
+AND path NOT LIKE '/boot%'
+
+-- exclude snap packages
+AND path NOT LIKE '/snap%' AND path NOT LIKE '/var/snap%'
+
+-- exclude virtualized mounts, would double-count bare metal storage
+AND path NOT LIKE '/var/lib/docker%'
+AND path NOT LIKE '/var/lib/containers%'
+
+AND type IN (
+'ext4',
+'ext3',
+'ext2',
+'xfs',
+'btrfs',
+'ntfs',
+'vfat',
+'fuseblk', --seen on NTFS and exFAT volumes mounted via FUSE
+'zfs' --also valid storage
+)
+AND (
+device LIKE '/dev/sd%'
+OR device LIKE '/dev/hd%'
+OR device LIKE '/dev/vd%'
+OR device LIKE '/dev/nvme%'
+OR device LIKE '/dev/mapper%'
+OR device LIKE '/dev/md%'
+OR device LIKE '/dev/dm-%'
+)`
+
// hostDetailQueries defines the detail queries that should be run on the host, as
// well as how the results of those queries should be ingested into the
// fleet.Host data model (via IngestFunc).
@@ -378,11 +428,12 @@ var hostDetailQueries = map[string]DetailQuery{
Platforms: append(fleet.HostLinuxOSs, "darwin", "windows"), // not chrome
},
"disk_space_unix": {
- Query: `
-SELECT (blocks_available * 100 / blocks) AS percent_disk_space_available,
- round((blocks_available * blocks_size * 10e-10),2) AS gigs_disk_space_available,
- round((blocks * blocks_size * 10e-10),2) AS gigs_total_disk_space
-FROM mounts WHERE path = '/' LIMIT 1;`,
+ Query: fmt.Sprintf(`
+ SELECT (blocks_available * 100 / blocks) AS percent_disk_space_available,
+ round((blocks_available * blocks_size * 10e-10),2) AS gigs_disk_space_available,
+ round((blocks * blocks_size * 10e-10),2) AS gigs_total_disk_space,
+ (SELECT round(SUM(blocks * blocks_size) * 10e-10, 2) FROM mounts %s) AS gigs_all_disk_space
+ FROM mounts WHERE path = '/' LIMIT 1;`, linuxGigsAllDiskSpaceSubQueryConditions),
Platforms: append(fleet.HostLinuxOSs, "darwin"),
DirectIngestFunc: directIngestDiskSpace,
},
@@ -463,7 +514,21 @@ func directIngestDiskSpace(ctx context.Context, logger log.Logger, host *fleet.H
return err
}
- return ds.SetOrUpdateHostDisksSpace(ctx, host.ID, gigsAvailable, percentAvailable, gigsTotal)
+ var gigsAllForFnCall *float64
+ if fleet.IsLinux(host.Platform) {
+ strippedRawRes := strings.TrimSpace(rows[0]["gigs_all_disk_space"])
+ // write `nil`, not 0, if osquery returns `""`, since a host cannot have 0 disk space and
+ // therefore this must represent a problematic query result
+ if strippedRawRes != "" {
+ gigsAll, err := strconv.ParseFloat(strippedRawRes, 64)
+ if err != nil {
+ return err
+ }
+ gigsAllForFnCall = &gigsAll
+ }
+ }
+
+ return ds.SetOrUpdateHostDisksSpace(ctx, host.ID, gigsAvailable, percentAvailable, gigsTotal, gigsAllForFnCall)
}
func ingestKubequeryInfo(ctx context.Context, logger log.Logger, host *fleet.Host, rows []map[string]string) error {