* Copyright (C) 2021 Red Hat, Inc.
* SPDX-License-Identifier: LGPL-2.1-or-later
*/
import cockpit from "cockpit";
import React from "react";
import { Button } from "@patternfly/react-core/dist/esm/components/Button/index.js";
import { ClipboardCopy } from "@patternfly/react-core/dist/esm/components/ClipboardCopy/index.js";
import { Page, PageSection } from "@patternfly/react-core/dist/esm/components/Page/index.js";
import { Stack } from "@patternfly/react-core/dist/esm/layouts/Stack/index.js";
import { ExclamationCircleIcon } from "@patternfly/react-icons";
import { EmptyStatePanel } from "cockpit-components-empty-state";
import { codes } from "./hosts_dialog.jsx";
import { Machine } from "./machines/machines";
const _ = cockpit.gettext;
export const EarlyFailure = () => {
let ca_cert_url = null;
if (window.navigator.userAgent.indexOf("Safari") >= 0)
ca_cert_url = window.sessionStorage.getItem("CACertUrl");
return (
<div id="early-failure" className="early-failure">
<Page className="pf-m-no-sidebar">
<PageSection hasBodyWrapper={false}>
<EmptyStatePanel icon={ExclamationCircleIcon}
title={ _("Connection failed") }
paragraph={
<Stack hasGutter>
<div>{_("There was an unexpected error while connecting to the machine.")}</div>
<div>{_("Messages related to the failure might be found in the journal:")}</div>
<ClipboardCopy isReadOnly hoverTip={_("Copy")} clickTip={_("Copied")}>journalctl -u cockpit</ClipboardCopy>
{ca_cert_url && <div id="safari-cert-help">
<div>{_("Safari users need to import and trust the certificate of the self-signing CA:")}</div>
<Button variant="link" component="a" id="safari-cert" href={ca_cert_url} download>ca.cer</Button>
</div>}
</Stack>
} />
</PageSection>
</Page>
</div>
);
};
const EarlyFailureReady = ({
loading = false,
title,
paragraph,
reconnect = false,
troubleshoot = false,
onTroubleshoot = () => {},
onReconnect = () => {},
} : {
loading?: boolean,
title: string,
paragraph: string,
reconnect?: boolean,
troubleshoot?: boolean,
onTroubleshoot?: () => void,
onReconnect?: () => void,
}) => {
return (
<div id="early-failure-ready" className="curtains-ct">
<Page className="pf-m-no-sidebar">
<PageSection hasBodyWrapper={false}>
<EmptyStatePanel {... !loading ? { icon: ExclamationCircleIcon } : {} }
loading={loading}
title={title}
action={<>
{reconnect &&
<Button id="machine-reconnect" onClick={onReconnect}>
{_("Reconnect")}
</Button>}
{troubleshoot &&
<Button id="machine-troubleshoot" onClick={onTroubleshoot}>
{_("Log in")}
</Button>}
</>}
paragraph={paragraph} />
</PageSection>
</Page>
</div>
);
};
export const Disconnected = ({
problem
} : {
problem: string
}) => {
return (
<EarlyFailureReady title={_("Disconnected")}
reconnect
onReconnect={() => {
cockpit.sessionStorage.clear();
window.location.reload();
}}
paragraph={cockpit.message(problem)} />
);
};
export const MachineTroubleshoot = ({
machine,
onClick
} : {
machine: Machine,
onClick: () => void
}) => {
const connecting = (machine.state === "connecting");
let title;
let message;
if (machine.restarting) {
title = _("The machine is rebooting");
message = "";
} else if (connecting) {
title = _("Connecting to the machine");
message = "";
} else {
title = _("Not connected to host");
if (machine.problem === "not-found") {
message = _("Cannot connect to an unknown host");
} else {
const error = machine.problem || machine.state;
if (error)
message = cockpit.message(error);
else
message = "";
}
}
let troubleshooting = false;
if (!machine.restarting && (machine.problem === "no-host" || (machine.problem && machine.problem in codes))) {
troubleshooting = true;
}
const restarting = !!machine.restarting;
const reconnect = !connecting && machine.problem !== "not-found" && !troubleshooting;
return (
<EarlyFailureReady loading={connecting || restarting}
title={title}
reconnect={reconnect}
troubleshoot={troubleshooting}
onTroubleshoot={onClick}
onReconnect={onClick}
paragraph={message} />
);
};