Skip to content

Commit

Permalink
WIP - show more warnings when connecting to remote machines
Browse files Browse the repository at this point in the history
  • Loading branch information
mvollmer committed Sep 4, 2024
1 parent 4bbac21 commit 5f761c2
Show file tree
Hide file tree
Showing 6 changed files with 271 additions and 84 deletions.
10 changes: 10 additions & 0 deletions pkg/shell/base_index.js
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,16 @@ function Frames(index, setupIdleResetTimers) {

/* Need to create a new frame */
if (!frame) {
/* Never create new frames for machines that are not
connected yet. That would open a channel to them (for
loading the URL), which woould trigger the bridge to
attempt a log in. We want all logins to happen in a
single place (in hosts.jsx) so that we can get the
options right, and show a warning dialog.
*/
if (host != "localhost" && machine.state !== "connected")
return null;

new_frame = true;
frame = document.createElement("iframe");
frame.setAttribute("class", "container-frame");
Expand Down
101 changes: 90 additions & 11 deletions pkg/shell/hosts.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import { Tooltip } from "@patternfly/react-core/dist/esm/components/Tooltip";

import 'polyfills';
import { CockpitNav, CockpitNavItem } from "./nav.jsx";
import { HostModal } from "./hosts_dialog.jsx";
import { HostModal, try2Connect, codes } from "./hosts_dialog.jsx";
import { useLoggedInUser } from "hooks";

const _ = cockpit.gettext;
Expand Down Expand Up @@ -75,20 +75,35 @@ export class CockpitHosts extends React.Component {
current_key: props.machine.key,
show_modal: false,
edit_machine: null,
switch_machine: null,
error_options: null,
problem: null,
just_connect: false,
};

this.toggleMenu = this.toggleMenu.bind(this);
this.filterHosts = this.filterHosts.bind(this);
this.onAddNewHost = this.onAddNewHost.bind(this);
this.onEditHosts = this.onEditHosts.bind(this);
this.onHostEdit = this.onHostEdit.bind(this);
this.onHostSwitch = this.onHostSwitch.bind(this);
this.onRemove = this.onRemove.bind(this);
}

componentDidMount() {
cockpit.user().then(user => {
this.setState({ current_user: user.name || "" });
}).catch(exc => console.log(exc));

window.trigger_connection_flow = machine => {
if (!this.state.show_modal)
this.onHostSwitch(machine, true);
};
this.props.index.navigate(null, true);
}

componentWillUnmount() {
window.trigger_connection_flow = null;
}

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

onHostSwitch(machine, just_connect) {
if (machine.state == "connected" || machine.address == "localhost") {
if (!just_connect) {
const addr = this.props.hostAddr({ host: machine.address }, true);
this.props.jump(addr);
}
} else if (machine.state != "connecting") {
if (machine.problem && codes[machine.problem]) {
this.setState({
show_modal: true,
switch_machine: machine,
problem: machine.problem,
just_connect,
});
} else if (this.props.warn_before_connecting)
this.setState({ show_modal: true, switch_machine: machine, just_connect });
else {
try2Connect(this.props.machines, machine.connection_string)
.then(() => {
const parts = this.props.machines.split_connection_string(machine.connection_string);
const addr = this.props.hostAddr({ host: parts.address }, true);
this.props.loader.connect(parts.address);
if (just_connect)
this.props.index.navigate();
else
this.props.jump(addr);
})
.catch(err => {
this.setState({ show_modal: true,
switch_machine: machine,
error_options: err,
problem: err.problem,
just_connect
});
});
}
}
}

onEditHosts() {
this.setState(s => { return { editing: !s.editing } });
}
Expand Down Expand Up @@ -180,7 +234,7 @@ export class CockpitHosts extends React.Component {
header={(m.user ? m.user : this.state.current_user) + " @"}
status={m.state === "failed" ? { type: "error", title: _("Connection error") } : null}
className={m.state}
jump={this.props.jump}
jump={() => this.onHostSwitch(m)}
actions={<>
<Tooltip content={_("Edit")} position="right">
<Button isDisabled={m.address === "localhost"} className="nav-action" hidden={!editing} onClick={e => this.onHostEdit(e, m)} key={m.label + "edit"} variant="secondary"><EditIcon /></Button>
Expand Down Expand Up @@ -242,18 +296,41 @@ export class CockpitHosts extends React.Component {
</div>
{this.state.show_modal &&
<HostModal machines_ins={this.props.machines}
onClose={() => this.setState({ show_modal: false, edit_machine: null })}
address={this.state.edit_machine ? this.state.edit_machine.address : null}
caller_callback={this.state.edit_machine
? (new_connection_string) => {
const parts = this.props.machines.split_connection_string(new_connection_string);
if (this.state.edit_machine == this.props.machine && parts.address != this.state.edit_machine.address) {
const addr = this.props.hostAddr({ host: parts.address }, true);
onClose={() => this.setState({
show_modal: false,
edit_machine: null,
switch_machine: null,
error_options: null,
problem: null,
})}
address={this.state.edit_machine?.address || this.state.switch_machine?.address}
template={this.state.switch_machine
? (this.state.problem
? codes[this.state.problem] || "change-port"
: "connect")
: null}
error_options={this.state.error_options}
warn_before_connecting={this.props.warn_before_connecting}
caller_callback={(new_connection_string) => {
const parts = this.props.machines.split_connection_string(new_connection_string);
const addr = this.props.hostAddr({ host: parts.address }, true);
if (this.state.edit_machine) {
if (this.state.edit_machine == this.props.machine &&
parts.address != this.state.edit_machine.address) {
this.props.jump(addr);
}
} else if (this.state.switch_machine) {
this.props.loader.connect(parts.address);
this.props.index.frames.remove(this.state.switch_machine);
if (this.state.just_connect) {
this.props.index.navigate();
} else {
this.props.jump(addr);
}
return Promise.resolve();
}
: null } />
return Promise.resolve();
}}
/>
}
</>
);
Expand All @@ -263,6 +340,8 @@ export class CockpitHosts extends React.Component {
CockpitHosts.propTypes = {
machine: PropTypes.object.isRequired,
machines: PropTypes.object.isRequired,
index: PropTypes.object.isRequired,
loader: PropTypes.object.isRequired,
selector: PropTypes.string.isRequired,
hostAddr: PropTypes.func.isRequired,
jump: PropTypes.func.isRequired,
Expand Down
Loading

0 comments on commit 5f761c2

Please sign in to comment.