Skip to content

Commit bdccd5d

Browse files
committed
WIP - show more warnings when connecting to remote machines
1 parent 4bbac21 commit bdccd5d

File tree

6 files changed

+249
-84
lines changed

6 files changed

+249
-84
lines changed

pkg/shell/base_index.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,16 @@ function Frames(index, setupIdleResetTimers) {
147147

148148
/* Need to create a new frame */
149149
if (!frame) {
150+
/* Never create new frames for machines that are not
151+
connected yet. That would open a channel to them (for
152+
loading the URL), which woould trigger the bridge to
153+
attempt a log in. We want all logins to happen in a
154+
single place (in hosts.jsx) so that we can get the
155+
options right, and show a warning dialog.
156+
*/
157+
if (host != "localhost" && machine.state !== "connected")
158+
return null;
159+
150160
new_frame = true;
151161
frame = document.createElement("iframe");
152162
frame.setAttribute("class", "container-frame");

pkg/shell/hosts.jsx

Lines changed: 89 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import { Tooltip } from "@patternfly/react-core/dist/esm/components/Tooltip";
1515

1616
import 'polyfills';
1717
import { CockpitNav, CockpitNavItem } from "./nav.jsx";
18-
import { HostModal } from "./hosts_dialog.jsx";
18+
import { HostModal, try2Connect, codes } from "./hosts_dialog.jsx";
1919
import { useLoggedInUser } from "hooks";
2020

2121
const _ = cockpit.gettext;
@@ -75,20 +75,35 @@ export class CockpitHosts extends React.Component {
7575
current_key: props.machine.key,
7676
show_modal: false,
7777
edit_machine: null,
78+
switch_machine: null,
79+
error_options: null,
80+
problem: null,
81+
just_connect: false,
7882
};
7983

8084
this.toggleMenu = this.toggleMenu.bind(this);
8185
this.filterHosts = this.filterHosts.bind(this);
8286
this.onAddNewHost = this.onAddNewHost.bind(this);
8387
this.onEditHosts = this.onEditHosts.bind(this);
8488
this.onHostEdit = this.onHostEdit.bind(this);
89+
this.onHostSwitch = this.onHostSwitch.bind(this);
8590
this.onRemove = this.onRemove.bind(this);
8691
}
8792

8893
componentDidMount() {
8994
cockpit.user().then(user => {
9095
this.setState({ current_user: user.name || "" });
9196
}).catch(exc => console.log(exc));
97+
98+
window.trigger_connection_flow = machine => {
99+
if (!this.state.show_modal)
100+
this.onHostSwitch(machine, true);
101+
};
102+
this.props.index.navigate(null, true);
103+
}
104+
105+
componentWillUnmount() {
106+
window.trigger_connection_flow = null;
92107
}
93108

94109
static getDerivedStateFromProps(nextProps, prevState) {
@@ -124,6 +139,45 @@ export class CockpitHosts extends React.Component {
124139
this.setState({ show_modal: true, edit_machine: machine });
125140
}
126141

142+
onHostSwitch(machine, just_connect) {
143+
if (machine.state == "connected" || machine.address == "localhost") {
144+
if (!just_connect) {
145+
const addr = this.props.hostAddr({ host: machine.address }, true);
146+
this.props.jump(addr);
147+
}
148+
} else if (machine.state != "connecting") {
149+
if (machine.problem && codes[machine.problem]) {
150+
this.setState({
151+
show_modal: true,
152+
switch_machine: machine,
153+
problem: machine.problem,
154+
just_connect,
155+
});
156+
} else if (!window.sessionStorage.getItem("connection-warning-shown"))
157+
this.setState({ show_modal: true, switch_machine: machine, just_connect });
158+
else {
159+
try2Connect(this.props.machines, machine.connection_string)
160+
.then(() => {
161+
const parts = this.props.machines.split_connection_string(machine.connection_string);
162+
const addr = this.props.hostAddr({ host: parts.address }, true);
163+
this.props.loader.connect(parts.address);
164+
if (just_connect)
165+
this.props.index.navigate();
166+
else
167+
this.props.jump(addr);
168+
})
169+
.catch(err => {
170+
this.setState({ show_modal: true,
171+
switch_machine: machine,
172+
error_options: err,
173+
problem: err.problem,
174+
just_connect
175+
});
176+
});
177+
}
178+
}
179+
}
180+
127181
onEditHosts() {
128182
this.setState(s => { return { editing: !s.editing } });
129183
}
@@ -180,7 +234,7 @@ export class CockpitHosts extends React.Component {
180234
header={(m.user ? m.user : this.state.current_user) + " @"}
181235
status={m.state === "failed" ? { type: "error", title: _("Connection error") } : null}
182236
className={m.state}
183-
jump={this.props.jump}
237+
jump={() => this.onHostSwitch(m)}
184238
actions={<>
185239
<Tooltip content={_("Edit")} position="right">
186240
<Button isDisabled={m.address === "localhost"} className="nav-action" hidden={!editing} onClick={e => this.onHostEdit(e, m)} key={m.label + "edit"} variant="secondary"><EditIcon /></Button>
@@ -242,18 +296,40 @@ export class CockpitHosts extends React.Component {
242296
</div>
243297
{this.state.show_modal &&
244298
<HostModal machines_ins={this.props.machines}
245-
onClose={() => this.setState({ show_modal: false, edit_machine: null })}
246-
address={this.state.edit_machine ? this.state.edit_machine.address : null}
247-
caller_callback={this.state.edit_machine
248-
? (new_connection_string) => {
249-
const parts = this.props.machines.split_connection_string(new_connection_string);
250-
if (this.state.edit_machine == this.props.machine && parts.address != this.state.edit_machine.address) {
251-
const addr = this.props.hostAddr({ host: parts.address }, true);
299+
onClose={() => this.setState({
300+
show_modal: false,
301+
edit_machine: null,
302+
switch_machine: null,
303+
error_options: null,
304+
problem: null,
305+
})}
306+
address={this.state.edit_machine?.address || this.state.switch_machine?.address}
307+
template={this.state.switch_machine
308+
? (this.state.problem
309+
? codes[this.state.problem] || "change-port"
310+
: "connect")
311+
: null}
312+
error_options={this.state.error_options}
313+
caller_callback={(new_connection_string) => {
314+
const parts = this.props.machines.split_connection_string(new_connection_string);
315+
const addr = this.props.hostAddr({ host: parts.address }, true);
316+
if (this.state.edit_machine) {
317+
if (this.state.edit_machine == this.props.machine &&
318+
parts.address != this.state.edit_machine.address) {
319+
this.props.jump(addr);
320+
}
321+
} else if (this.state.switch_machine) {
322+
this.props.loader.connect(parts.address);
323+
this.props.index.frames.remove(this.state.switch_machine);
324+
if (this.state.just_connect) {
325+
this.props.index.navigate();
326+
} else {
252327
this.props.jump(addr);
253328
}
254-
return Promise.resolve();
255329
}
256-
: null } />
330+
return Promise.resolve();
331+
}}
332+
/>
257333
}
258334
</>
259335
);
@@ -263,6 +339,8 @@ export class CockpitHosts extends React.Component {
263339
CockpitHosts.propTypes = {
264340
machine: PropTypes.object.isRequired,
265341
machines: PropTypes.object.isRequired,
342+
index: PropTypes.object.isRequired,
343+
loader: PropTypes.object.isRequired,
266344
selector: PropTypes.string.isRequired,
267345
hostAddr: PropTypes.func.isRequired,
268346
jump: PropTypes.func.isRequired,

0 commit comments

Comments
 (0)