Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug 1838658: Use new proxy to connect to cloudshell in terminal #5428

Merged

Conversation

abhinandan13jan
Copy link
Contributor

@abhinandan13jan abhinandan13jan commented May 13, 2020

CloudShell Terminal using exec and autoresizer Xterm

  • Added new init call utility to make call to non k8s terminal API (requires backend changes)
    as per [WIP] fix(cloudshell-rework): make changes to podexec,xterm and switch to u… #5359
  • existing CloudShellTerminal modified to makes init and derive required props from response
  • New Exec component created which connects an Xterm component using the above props
    props include [podname, container,command, namespace]
  • New autoresizing XTerm terminal to work with CloudShellDrawer.
  • Add typings
  • Make CSS changes
  • Testing - Alter tests for this PR

Linked issue

https://issues.redhat.com/browse/ODC-3793

Screenshot

terminal1 (1)
terminal2

Browser conformation

chrome 73

@openshift-ci-robot openshift-ci-robot added do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. component/core Related to console core functionality labels May 13, 2020
@abhinandan13jan abhinandan13jan changed the title [WIP] fix(cloud-shell): Use CloudShell exec and resizable terminal fix(cloud-shell): Use CloudShell exec and resizable terminal May 14, 2020
@openshift-ci-robot openshift-ci-robot removed the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label May 14, 2020
@@ -86,3 +87,13 @@ export const newCloudShellWorkSpace = (
},
},
});

export const makeTerminalInitCalls = (username, wname, wnamespace) => {
const consumeUrl = `api/terminal/${wnamespace}/${wname}/exec/init`;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
const consumeUrl = `api/terminal/${wnamespace}/${wname}/exec/init`;
const consumeUrl = `/api/terminal/${wnamespace}/${wname}/exec/init`;

@@ -35,7 +35,7 @@ describe('CloudShellTerminal', () => {
true,
]);
const wrapper = shallow(<InternalCloudShellTerminal username="user" />);
const frame = wrapper.find(CloudShellTerminalFrame);
const exec = wrapper.find(CloudShellTerminalFrame);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change breaks the test.

But didn't you delete the file related these tests?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am yet to update the tests

Comment on lines 7 to 8
XTerminal.applyAddon(fit);
XTerminal.applyAddon(full);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is not supported in the current xterm dependency(3.12, requires ^3.14) and after upgrading the dependency, I am observing problems in PodExec (not sure if it is related to the version)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok fair enough, i thought it was in 3.x.

style={{
width: '100%',
height: '100%',
padding: this.padding / 2,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Assign padding using the terminal element, otherwise the scrollbars are indented.
https://github.com/xtermjs/xterm.js/pull/1208/files

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've removed padding and added to the xterm options, but it doesn't appear to add

Comment on lines 127 to 132
<div ref={this.outerRef} className={this.props.className}>
<div
ref={this.innerRef}
style={{ width: this.state.width, height: this.state.height }}
className="console"
/>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should only need the one div and not 3.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just one div now

Comment on lines 132 to 136
const containers = _.get(nextProps.obj, 'spec.containers', []).map((n) => n.name);
if (_.isEqual(containers, prevState.containers)) {
return null;
}
return { containers };
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nextProps.obj isn't even defined in CloudShellExecProps.
This function does nothing.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will remove this

current && current.onConnectionClosed(`connecting to ${container}`);
}

const impersonate = store.getState().UI.get('impersonate', {});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't reach for global redux store. Use connect.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

passed this on to connect

Comment on lines 69 to 76
if (this.ws) {
this.ws.destroy();
const { current } = this.terminal;
current && current.onConnectionClosed(`connecting to ${container}`);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unreachable code. connect is only ever called once on mount.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed


connect = () => {
const { container, podname, namespace, shcommand } = this.props;
const usedClient = this.props.flags[FLAGS.OPENSHIFT] ? 'oc' : 'kubectl';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Inconsistent access of this.props. Line above deconstructs all props.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

@@ -86,3 +87,13 @@ export const newCloudShellWorkSpace = (
},
},
});

export const makeTerminalInitCalls = (username, wname, wnamespace) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
export const makeTerminalInitCalls = (username, wname, wnamespace) => {
export const initializeTerminal = (username: string, workspaceName: string, namespace: string): Promise<...> => {

Promise should be properly typed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added type


onResize() {
try {
this.terminal && this.terminal.fit();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You don't need this if you are using resizeObserver to call terminal.fit().

Comment on lines 64 to 66
this.resizeObserver = new ResizeObserver(() => {
this.terminal.fit();
});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

or you can just call onResize here.

Suggested change
this.resizeObserver = new ResizeObserver(() => {
this.terminal.fit();
});
this.resizeObserver = new ResizeObserver(this.onResize);

}

componentWillUnmount() {
this.terminal && this.terminal.destroy();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You also need to disconnect the resizeobserver when component unmounts.

Suggested change
this.terminal && this.terminal.destroy();
this.terminal && this.terminal.destroy();
this.resizeObserver && this.resizeObserver.disconnect();

@rohitkrai03
Copy link
Contributor

/assign

@openshift-ci-robot openshift-ci-robot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label May 19, 2020

type TerminalProps = {
onData: (data: string) => void;
className?: string;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove. className is not used.

type TerminalProps = {
onData: (data: string) => void;
className?: string;
shouldResize?: boolean;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shouldResize is unnecessary as we need resize support for all use cases. Even a stand alone tab supports browser resizing.


constructor(props) {
super(props);
this.terminalRef = React.createRef();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move to declaration.
Missing type.

Comment on lines 45 to 47
if (!terminal) {
return;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

terminal can never be undefined here.

Comment on lines 110 to 115
if (
workSpacePod?.pod &&
workSpacePod?.container &&
workSpacePod?.namespace &&
workSpacePod?.command
) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If workspacePod is set, isn't it a guarantee that all the props are set?

Suggested change
if (
workSpacePod?.pod &&
workSpacePod?.container &&
workSpacePod?.namespace &&
workSpacePod?.command
) {
if (workspacePod) {

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this will take the user to the Terminal with error as soon as workSpacePod.namespace is set up.
And this occurs before workSpacePod.pod is set. However, we can alter it after moving namespace out.

Comment on lines 2 to 6
position: fixed;
top: 0px;
left: 0px;
right: 0px;
bottom: 0px;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is any of this necessary?
What's wrong with using the flex layout?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It keeps expanding beyond the screen as user puts some command

overflow: hidden;
padding-bottom: var(--pf-global--spacer--xl);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We shouldn't be creating extra white space at the bottom.

@@ -0,0 +1,8 @@
.odc-cloudshell-terminal {
&__container {
background-color: var(--pf-global--palette--black-1000);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this even exist black-1000 ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same is used in log component -- var(--pf-global--palette--black-1000);

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems like it does exist. But I wonder if we should just use --pf-global--BackgroundColor--dark-100 instead.

cursorBlink: false,
cols: 80,
rows: 25,
padding: 30,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think 4px max is sufficient padding. It looks to align with UX as well. Furthermore we don't want to add more than this amount to the top and bottom.

rows: 25,
padding: 30,
};
this.terminal = new XTerminal(Object.assign({}, options));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
this.terminal = new XTerminal(Object.assign({}, options));
this.terminal = new XTerminal(options);

@abhinandan13jan abhinandan13jan force-pushed the cloud-shell-terminal branch 2 times, most recently from 4550bb6 to 0bfa35f Compare May 19, 2020 16:57
@openshift-ci-robot openshift-ci-robot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label May 19, 2020
@rohitkrai03
Copy link
Contributor

@abhinandan13jan Raised a PR on your branch with some fixes and cleanups - abhinandan13jan#2

Comment on lines 44 to 46
private terminal;

private ws;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
private terminal;
private ws;
private terminal = React.createRef<Terminal>();
private ws: WSFactory;

this.ws && this.ws.send(`0${Base64.encode(data)}`);
};

connect() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
connect() {
private connect() {

// error channel
if (raw[0] === '3') {
if (previous.includes(NO_SH)) {
currentTerminal.reset();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Inconsistent. Missing null check as per rest of usage of this.terminal.current.


onConnectionClosed = (reason) => {
this.terminal.write(`\x1b[31m${reason || 'disconnected'}\x1b[m\r\n`);
this.terminal.cursorHidden = true;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cursorHidden doesn't exist in the type def of Terminal.
There is isCursorHidden on core service but unsure how to reach it...

this.terminal.write(`\x1b[31m${reason || 'disconnected'}\x1b[m\r\n`);
this.terminal.cursorHidden = true;
this.terminal.setOption('disableStdin', true);
this.terminal.refresh(this.terminal.y, this.terminal.y);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

y don't exist in the type def of Terminal

}

focus() {
this.terminal && this.terminal.focus();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this.terminal is always defined.

Suggested change
this.terminal && this.terminal.focus();
this.terminal.focus();

componentDidMount() {
this.terminal.open(this.terminalRef.current);
this.resizeObserver = new ResizeObserver(() => {
window.requestAnimationFrame(() => this.terminal.fit());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To work with typescript.
Import fit like this:
import { fit } from 'xterm/lib/addons/fit/fit';

Remove XTerminal.applyAddon(fit);

Suggested change
window.requestAnimationFrame(() => this.terminal.fit());
window.requestAnimationFrame(() => fit(this.terminal));

@@ -14,7 +12,7 @@ jest.mock('@console/internal/components/utils/k8s-watch-hook', () => ({
describe('CloudShellTerminal', () => {
it('should display loading box', () => {
(useK8sWatchResource as jest.Mock).mockReturnValueOnce([null, false]);
const wrapper = shallow(<InternalCloudShellTerminal username="user" />);
const wrapper = mount(<InternalCloudShellTerminal username="user" />);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We want to use shallow rendering. Checking for LoadingBox is no longer correct. This test needs updating.

@@ -23,21 +21,4 @@ describe('CloudShellTerminal', () => {
const wrapper = shallow(<InternalCloudShellTerminal username="user" />);
expect(wrapper.find(CloudShellSetup)).toHaveLength(1);
});

it('should display terminal if loaded with matching workspace', () => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's try to add more tests / fix up existing tests instead of removing them.

@@ -0,0 +1,8 @@
.odc-cloudshell-terminal {
&__container {
background-color: var(--pf-global--BackgroundColor--dark-100);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This background color is incorrect. We need pure black.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So back to black-10000?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The default terminal theme background color is pure black. So whatever gets us to pure black.
Unless we choose to override. But at this point being consistent with the other terminal is probably best.

@rohitkrai03
Copy link
Contributor

rohitkrai03 commented May 20, 2020

@abhinandan13jan Another PR with updates and fixes - abhinandan13jan#3

@rohitkrai03
Copy link
Contributor

/retitle Bug 1838658: Use new proxy to connect to cloudshell in terminal

@openshift-ci-robot openshift-ci-robot changed the title fix(cloud-shell): Use CloudShell exec and resizable terminal Bug 1838658: Use new proxy to connect to cloudshell in terminal May 21, 2020
@openshift-ci-robot openshift-ci-robot added bugzilla/severity-unspecified Referenced Bugzilla bug's severity is unspecified for the PR. bugzilla/valid-bug Indicates that a referenced Bugzilla bug is valid for the branch this PR is targeting. labels May 21, 2020
@openshift-ci-robot
Copy link
Contributor

@abhinandan13jan: This pull request references Bugzilla bug 1838658, which is valid. The bug has been moved to the POST state. The bug has been updated to refer to the pull request using the external bug tracker.

3 validation(s) were run on this bug
  • bug is open, matching expected state (open)
  • bug target release (4.5.0) matches configured target release for branch (4.5.0)
  • bug is in the state NEW, which is one of the valid states (NEW, ASSIGNED, ON_DEV, POST, POST)

In response to this:

Bug 1838658: Use new proxy to connect to cloudshell in terminal

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.

@rohitkrai03
Copy link
Contributor

/bugzilla refresh

@openshift-ci-robot openshift-ci-robot added bugzilla/severity-high Referenced Bugzilla bug's severity is high for the branch this PR is targeting. and removed bugzilla/severity-unspecified Referenced Bugzilla bug's severity is unspecified for the PR. labels May 21, 2020
@openshift-ci-robot
Copy link
Contributor

@rohitkrai03: This pull request references Bugzilla bug 1838658, which is valid.

3 validation(s) were run on this bug
  • bug is open, matching expected state (open)
  • bug target release (4.5.0) matches configured target release for branch (4.5.0)
  • bug is in the state POST, which is one of the valid states (NEW, ASSIGNED, ON_DEV, POST, POST)

In response to this:

/bugzilla refresh

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.

'Connecting to your OpenShift command line terminal ...',
);
});
it('should render cloudshellterminal', () => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Test names need to be descriptive of the actual test. Looks to be a copy and paste error.

@@ -14,30 +13,19 @@ jest.mock('@console/internal/components/utils/k8s-watch-hook', () => ({
describe('CloudShellTerminal', () => {
it('should display loading box', () => {
(useK8sWatchResource as jest.Mock).mockReturnValueOnce([null, false]);
const wrapper = shallow(<InternalCloudShellTerminal username="user" />);
expect(wrapper.find(LoadingBox)).toHaveLength(1);
const wrapper: ShallowWrapper = shallow(<InternalCloudShellTerminal username="user" />);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: no need to assign a type when it can be inferred from the assignment at declaration time.

Suggested change
const wrapper: ShallowWrapper = shallow(<InternalCloudShellTerminal username="user" />);
const wrapper = shallow(<InternalCloudShellTerminal username="user" />);

Comment on lines 50 to 71
React.useEffect(() => {
const term: XTerminal = new XTerminal(terminalOptions);
term.on('data', onData);
term.open(terminalRef.current);
term.focus();

const resizeObserver: ResizeObserver = new ResizeObserver(() => {
window.requestAnimationFrame(() => fit(term));
});

resizeObserver.observe(terminalRef.current);

if (terminal.current !== term) {
terminal.current && terminal.current.destroy();
terminal.current = term;
}

return () => {
term.destroy();
resizeObserver.disconnect();
};
}, [onData]);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems harsh to re-initialize the entire terminal when onData callback changes.

Probably want to split up into multiple effects where one does something simple like:

React.useEffect(() => {
  const term = terminal.current;
  term.on('data', onData);
  return () => term.off('data', onData);
}, [onData]);

Comment on lines 29 to 31
const focus = () => {
terminal.current && terminal.current.focus();
};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All the imperative handle functions should be defined inside the imperative handle hook callback so that they aren't needlessly declared on each render.

@@ -0,0 +1,8 @@
.odc-cloudshell-terminal {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
.odc-cloudshell-terminal {
.co-cloudshell-terminal {

onConnectionClosed,
}));

return <div ref={terminalRef} style={{ width: '100%', height: '100%' }} />;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Width isn't needed here on the block element div.
I think we need a class that can set the height of the terminal:

.something > .terminal {
  height: 100%;
}

Otherwise we see this gap appear at the bottom:
image

&__container {
background-color: #000;
color: var(--pf-global--Color--light-100);
width: 100%;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: width shouldn't be needed on a block element div

return <CloudShellSetup onCancel={onCancel} />;
if (loaded && !workspace) return <CloudShellSetup onCancel={onCancel} />;

return null;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we should ever return null. We have enough information to know if we should be showing loading, error, terminal or form at any point. The problem is with initDataLoading which I don't think is necessary. We can assume loading still if we do not have initData.

const [data, loaded, loadError] = useK8sWatchResource<CloudShellResource>(resource);
const [data, loaded, loadError] = useK8sWatchResource<CloudShellResource[]>(resource);
const [initData, setInitData] = React.useState<TerminalInitData>();
const [initDataLoading, setInitDataLoading] = React.useState<boolean>(false);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this is needed if you use initData null checks instead.

<StatusBox loaded={loaded} loadError={loadError} label="OpenShift command line terminal" />
<StatusBox
loaded={loaded}
loadError={loadError || initError}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

loadError cannot be a string as is the case for initError.

@rohitkrai03
Copy link
Contributor

/retest

@christianvogt
Copy link
Contributor

/approve

@openshift-ci-robot openshift-ci-robot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label May 22, 2020
Copy link
Contributor

@rohitkrai03 rohitkrai03 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/lgtm

@openshift-ci-robot openshift-ci-robot added the lgtm Indicates that a PR is ready to be merged. label May 22, 2020
@openshift-ci-robot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: abhinandan13jan, christianvogt, rohitkrai03

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@openshift-merge-robot openshift-merge-robot merged commit 60638f6 into openshift:master May 22, 2020
@openshift-ci-robot
Copy link
Contributor

@abhinandan13jan: All pull requests linked via external trackers have merged: openshift/console#5428. Bugzilla bug 1838658 has been moved to the MODIFIED state.

In response to this:

Bug 1838658: Use new proxy to connect to cloudshell in terminal

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.

@spadgett spadgett added this to the v4.5 milestone Jun 1, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved Indicates a PR has been approved by an approver from all required OWNERS files. bugzilla/severity-high Referenced Bugzilla bug's severity is high for the branch this PR is targeting. bugzilla/valid-bug Indicates that a referenced Bugzilla bug is valid for the branch this PR is targeting. component/core Related to console core functionality lgtm Indicates that a PR is ready to be merged.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants