Skip to content

Commit

Permalink
Merge pull request #540 from joseivanlopez/storage-issues
Browse files Browse the repository at this point in the history
Add storage issues
  • Loading branch information
joseivanlopez committed May 4, 2023
2 parents a1cf46e + 05ea541 commit 541bc83
Show file tree
Hide file tree
Showing 32 changed files with 1,111 additions and 113 deletions.
3 changes: 1 addition & 2 deletions service/lib/agama/storage/manager.rb
Original file line number Diff line number Diff line change
Expand Up @@ -228,9 +228,8 @@ def probing_issues
y2storage_issues = Y2Storage::StorageManager.instance.raw_probed.probing_issues

y2storage_issues.map do |y2storage_issue|
details = [y2storage_issue.description, y2storage_issue.details].compact.join("\n")
Issue.new(y2storage_issue.message,
details: details,
details: y2storage_issue.details,
source: Issue::Source::SYSTEM,
severity: Issue::Severity::WARN)
end
Expand Down
7 changes: 7 additions & 0 deletions web/package/cockpit-agama.changes
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
-------------------------------------------------------------------
Fri Apr 28 15:16:04 UTC 2023 - José Iván López González <jlopez@suse.com>

- Add issues for storage client.
- Add issues page.
- gh#openSUSE/agama#540

-------------------------------------------------------------------
Mon Apr 24 15:53:35 UTC 2023 - David Diaz <dgonzalez@suse.com>

Expand Down
45 changes: 38 additions & 7 deletions web/src/assets/styles/blocks.scss
Original file line number Diff line number Diff line change
Expand Up @@ -220,14 +220,45 @@ section > .content {
}

span.notification-mark {
--border-width: 2px;
--size: calc(var(--fs-base) + var(--border-width));
--nm-border-width: 0;
--nm-border-color: transparent;
--nm-border: var(--nm-border-width) solid var(--nm-border-color);
--nm-size: 8px;
--nm-margin-inline: var(--nm-size, 5px);
--nm-display: inline-block;
--nm-color: #00BFFF; //deepskyblue

margin-inline: var(--nm-margin-inline);
display: var(--nm-display);
background: var(--nm-color);
border: var(--nm-border);
width: var(--nm-size);
height: var(--nm-size);
border-radius: 999px;
}

span.notification-mark[data-variant="sidebar"] {
--nm-size: calc(var(--fs-base) + var(--nm-border-width));
--nm-display: initial;
--nm-border-width: 2px;
--nm-border-color: var(--color-primary);
--nm-margin-inline: 0;

position: absolute;
right: 0;
background: var(--color-primary-lighter);
border: var(--border-width) solid var(--color-primary);
width: var(--size);
height: var(--size);
border-radius: 999px;
}

.issue {
--icon-size: 1rem;

div:first-child {
svg {
width: var(--icon-size);
height: var(--icon-size);
}
}

div:nth-child(2) {
padding-left: calc(var(--icon-size) + var(--pf-c-helper-text__item-icon--MarginRight));
}
}
6 changes: 3 additions & 3 deletions web/src/client/dbus.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ import cockpit from "../lib/cockpit";

/**
* @typedef {object} DBusValue
* @property {string} s - type signature
* @property {DBusValue | DBusValue[] | number | string | boolean | number[] | string[] | boolean[]} v - value
* @property {string} t - type signature
* @property { * } v - value
*/

/**
Expand Down Expand Up @@ -149,7 +149,7 @@ class DBusClient {

try {
const result = await this.client.call(
path, "org.freedesktop.DBus.Properties", "Get", [iface, "Errors"]
path, "org.freedesktop.DBus.Properties", "Get", [iface, name]
);
property = result[0];
} catch (error) {
Expand Down
31 changes: 22 additions & 9 deletions web/src/client/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) [2021] SUSE LLC
* Copyright (c) [2021-2023] SUSE LLC
*
* All Rights Reserved.
*
Expand Down Expand Up @@ -30,6 +30,7 @@ import { UsersClient } from "./users";
import phase from "./phase";
import { QuestionsClient } from "./questions";
import { NetworkClient } from "./network";
import { IssuesClient } from "./issues";

const SERVICE_NAME = "org.opensuse.Agama";

Expand All @@ -43,6 +44,7 @@ const SERVICE_NAME = "org.opensuse.Agama";
* @property {StorageClient} storage - storage client
* @property {UsersClient} users - users client
* @property {QuestionsClient} questions - questions client
* @property {IssuesClient} issues - issues client
*/

/**
Expand All @@ -51,15 +53,26 @@ const SERVICE_NAME = "org.opensuse.Agama";
* @return {InstallerClient}
*/
const createClient = (address = "unix:path=/run/agama/bus") => {
const language = new LanguageClient(address);
const manager = new ManagerClient(address);
const monitor = new Monitor(address, SERVICE_NAME);
const network = new NetworkClient();
const software = new SoftwareClient(address);
const storage = new StorageClient(address);
const users = new UsersClient(address);
const questions = new QuestionsClient(address);
const issues = new IssuesClient({ storage });

return {
language: new LanguageClient(address),
manager: new ManagerClient(address),
monitor: new Monitor(address, SERVICE_NAME),
network: new NetworkClient(),
software: new SoftwareClient(address),
storage: new StorageClient(address),
users: new UsersClient(address),
questions: new QuestionsClient(address)
language,
manager,
monitor,
network,
software,
storage,
users,
questions,
issues
};
};

Expand Down
78 changes: 78 additions & 0 deletions web/src/client/issues.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/*
* Copyright (c) [2023] SUSE LLC
*
* All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as published
* by the Free Software Foundation.
*
* This program 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 General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, contact SUSE LLC.
*
* To contact SUSE LLC about this file by physical or electronic mail, you may
* find current contact information at www.suse.com.
*/

// @ts-check

/**
* @typedef {object} ClientsIssues
* @property {import ("~/client/mixins").Issue[]} storage - Issues from storage client
*/

/**
* Client for managing all issues, independently on the service owning the issues
*/
class IssuesClient {
/**
* @param {object} clients - Clients managing issues
* @param {import ("~/client/storage").StorageClient} clients.storage
*/
constructor(clients) {
this.clients = clients;
}

/**
* Get issues from all clients managing issues
*
* @returns {Promise<ClientsIssues>}
*/
async getAll() {
const storage = await this.clients.storage.getIssues();

return { storage };
}

/**
* Checks whether there is some error
*
* @returns {Promise<boolean>}
*/
async any() {
const clientsIssues = await this.getAll();
const issues = Object.values(clientsIssues).flat();

return issues.length > 0;
}

/**
* Registers a callback for each service to be executed when its issues change
*
* @param {import ("~/client/mixins").IssuesHandler} handler - callback function
* @return {import ("./dbus").RemoveFn} function to disable the callback
*/
onIssuesChange(handler) {
const unsubscribeCallbacks = [];
unsubscribeCallbacks.push(this.clients.storage.onIssuesChange(handler));

return () => { unsubscribeCallbacks.forEach(cb => cb()) };
}
}

export { IssuesClient };
94 changes: 94 additions & 0 deletions web/src/client/issues.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
/*
* Copyright (c) [2023] SUSE LLC
*
* All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as published
* by the Free Software Foundation.
*
* This program 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 General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, contact SUSE LLC.
*
* To contact SUSE LLC about this file by physical or electronic mail, you may
* find current contact information at www.suse.com.
*/

// @ts-check

import { IssuesClient } from "./issues";
import { StorageClient } from "./storage";

const storageIssues = [
{ description: "Storage issue 1", severity: "error", details: "", source: "" },
{ description: "Storage issue 2", severity: "warn", details: "", source: "" },
{ description: "Storage issue 3", severity: "error", details: "", source: "" }
];

const issues = {
storage: []
};

jest.spyOn(StorageClient.prototype, 'getIssues').mockImplementation(async () => issues.storage);
jest.spyOn(StorageClient.prototype, 'onIssuesChange');

const clientsWithIssues = {
storage: new StorageClient()
};

describe("#getAll", () => {
beforeEach(() => {
issues.storage = storageIssues;
});

it("returns all the storage issues", async () => {
const client = new IssuesClient(clientsWithIssues);

const { storage } = await client.getAll();
expect(storage).toEqual(expect.arrayContaining(storageIssues));
});
});

describe("#any", () => {
describe("if there are storage issues", () => {
beforeEach(() => {
issues.storage = storageIssues;
});

it("returns true", async () => {
const client = new IssuesClient(clientsWithIssues);

const result = await client.any();
expect(result).toEqual(true);
});
});

describe("if there are no issues", () => {
beforeEach(() => {
issues.storage = [];
});

it("returns false", async () => {
const client = new IssuesClient(clientsWithIssues);

const result = await client.any();
expect(result).toEqual(false);
});
});
});

describe("#onIssuesChange", () => {
it("subscribes to changes in storage issues", () => {
const client = new IssuesClient(clientsWithIssues);

const handler = jest.fn();
client.onIssuesChange(handler);

expect(clientsWithIssues.storage.onIssuesChange).toHaveBeenCalledWith(handler);
});
});
Loading

0 comments on commit 541bc83

Please sign in to comment.