Line data Source code
1 : /*
2 : * Copyright (C) 2021 Red Hat, Inc.
3 : * SPDX-License-Identifier: LGPL-2.1-or-later
4 : */
5 :
6 123 : import cockpit from "cockpit";
7 123 : import React from "react";
8 :
9 : import { Button } from "@patternfly/react-core/dist/esm/components/Button/index.js";
10 : import { ClipboardCopy } from "@patternfly/react-core/dist/esm/components/ClipboardCopy/index.js";
11 : import { Page, PageSection } from "@patternfly/react-core/dist/esm/components/Page/index.js";
12 : import { Stack } from "@patternfly/react-core/dist/esm/layouts/Stack/index.js";
13 : import { ExclamationCircleIcon } from "@patternfly/react-icons";
14 :
15 : import { EmptyStatePanel } from "cockpit-components-empty-state";
16 :
17 : import { codes } from "./hosts_dialog.jsx";
18 : import { Machine } from "./machines/machines";
19 :
20 123 : const _ = cockpit.gettext;
21 :
22 3 : export const EarlyFailure = () => {
23 3 : let ca_cert_url = null;
24 3 : if (window.navigator.userAgent.indexOf("Safari") >= 0)
25 3 : ca_cert_url = window.sessionStorage.getItem("CACertUrl");
26 :
27 3 : return (
28 3 : <div id="early-failure" className="early-failure">
29 3 : <Page className="pf-m-no-sidebar">
30 3 : <PageSection hasBodyWrapper={false}>
31 3 : <EmptyStatePanel icon={ExclamationCircleIcon}
32 3 : title={ _("Connection failed") }
33 3 : paragraph={
34 3 : <Stack hasGutter>
35 3 : <div>{_("There was an unexpected error while connecting to the machine.")}</div>
36 3 : <div>{_("Messages related to the failure might be found in the journal:")}</div>
37 3 : <ClipboardCopy isReadOnly hoverTip={_("Copy")} clickTip={_("Copied")}>journalctl -u cockpit</ClipboardCopy>
38 1 : {ca_cert_url && <div id="safari-cert-help">
39 1 : <div>{_("Safari users need to import and trust the certificate of the self-signing CA:")}</div>
40 1 : <Button variant="link" component="a" id="safari-cert" href={ca_cert_url} download>ca.cer</Button>
41 1 : </div>}
42 3 : </Stack>
43 3 : } />
44 3 : </PageSection>
45 3 : </Page>
46 3 : </div>
47 : );
48 3 : };
49 :
50 2 : const EarlyFailureReady = ({
51 2 : loading = false,
52 2 : title,
53 2 : paragraph,
54 2 : reconnect = false,
55 2 : troubleshoot = false,
56 0 : onTroubleshoot = () => {},
57 0 : onReconnect = () => {},
58 2 : } : {
59 : loading?: boolean,
60 : title: string,
61 : paragraph: string,
62 : reconnect?: boolean,
63 : troubleshoot?: boolean,
64 : onTroubleshoot?: () => void,
65 : onReconnect?: () => void,
66 2 : }) => {
67 2 : return (
68 2 : <div id="early-failure-ready" className="curtains-ct">
69 2 : <Page className="pf-m-no-sidebar">
70 2 : <PageSection hasBodyWrapper={false}>
71 0 : <EmptyStatePanel {... !loading ? { icon: ExclamationCircleIcon } : {} }
72 2 : loading={loading}
73 2 : title={title}
74 2 : action={<>
75 2 : {reconnect &&
76 2 : <Button id="machine-reconnect" onClick={onReconnect}>
77 2 : {_("Reconnect")}
78 2 : </Button>}
79 2 : {troubleshoot &&
80 0 : <Button id="machine-troubleshoot" onClick={onTroubleshoot}>
81 0 : {_("Log in")}
82 0 : </Button>}
83 2 : </>}
84 2 : paragraph={paragraph} />
85 2 : </PageSection>
86 2 : </Page>
87 2 : </div>
88 : );
89 2 : };
90 :
91 2 : export const Disconnected = ({
92 2 : problem
93 2 : } : {
94 : problem: string
95 2 : }) => {
96 2 : return (
97 2 : <EarlyFailureReady title={_("Disconnected")}
98 2 : reconnect
99 0 : onReconnect={() => {
100 0 : cockpit.sessionStorage.clear();
101 0 : window.location.reload();
102 0 : }}
103 2 : paragraph={cockpit.message(problem)} />
104 : );
105 2 : };
106 :
107 0 : export const MachineTroubleshoot = ({
108 0 : machine,
109 0 : onClick
110 0 : } : {
111 : machine: Machine,
112 : onClick: () => void
113 0 : }) => {
114 0 : const connecting = (machine.state == "connecting");
115 0 : let title;
116 0 : let message;
117 0 : if (machine.restarting) {
118 0 : title = _("The machine is rebooting");
119 0 : message = "";
120 0 : } else if (connecting) {
121 0 : title = _("Connecting to the machine");
122 0 : message = "";
123 0 : } else {
124 0 : title = _("Not connected to host");
125 0 : if (machine.problem == "not-found") {
126 0 : message = _("Cannot connect to an unknown host");
127 0 : } else {
128 0 : const error = machine.problem || machine.state;
129 0 : if (error)
130 0 : message = cockpit.message(error);
131 : else
132 0 : message = "";
133 0 : }
134 0 : }
135 :
136 0 : let troubleshooting = false;
137 :
138 0 : if (!machine.restarting && (machine.problem === "no-host" || (machine.problem && machine.problem in codes))) {
139 0 : troubleshooting = true;
140 0 : }
141 :
142 0 : const restarting = !!machine.restarting;
143 0 : const reconnect = !connecting && machine.problem != "not-found" && !troubleshooting;
144 :
145 0 : return (
146 0 : <EarlyFailureReady loading={connecting || restarting}
147 0 : title={title}
148 0 : reconnect={reconnect}
149 0 : troubleshoot={troubleshooting}
150 0 : onTroubleshoot={onClick}
151 0 : onReconnect={onClick}
152 0 : paragraph={message} />
153 : );
154 0 : };
|