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

Support choosing tensorboard version from UI #2690

Merged
merged 37 commits into from
Dec 24, 2019

Conversation

dldaisy
Copy link
Contributor

@dldaisy dldaisy commented Dec 3, 2019

We allow choosing tensorboard version from UI. User now can select a tensorflow image version to start different versions of tensorboard among our provided list of images which can be opened correctly, including support for tensorboard 2.0.0+ by adding the argument "--bind-all". We also add a corresponding test to test version selection.

Changes include:
Frontend:
(1) Add html element in Tensorboard component to allow user to select the tensorboard version and start it.
(2) Modify functions about start/get a tensorboard in frontend server and apis. The functions now accept another arguments indicating tensorflow image version, encode it in url and request frontend server. The server will parse & decode the version and let k8s client to launch a required version of tensorboard. We don't encode version into viewer's name, so it just remains the same as before.

Backend:
We use the backend mentioned in PR #2544 with a field for tensorflow image. The backend viewer controller would use this field to launch a required version of tensorboard.

Note:
(1) Which versions to be allowed to choose: we tested all the main versions of tensorflow docker image, and kept all those can work correctly.
(2) Whether to change the viewer name with encoded information about version: Currently user can launch only one tensorboard viewer instance on one log directory, so we choose not to include the version information to identify a viewer's name. However, both solutions are correct and would be easy to modify later on.

Related bug: #2514


This change is Reviewable

@googlebot
Copy link
Collaborator

Thanks for your pull request. It looks like this may be your first contribution to a Google open source project (if not, look below for help). Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

📝 Please visit https://cla.developers.google.com/ to sign.

Once you've signed (or fixed any issues), please reply here with @googlebot I signed it! and we'll verify it.


What to do if you already signed the CLA

Individual signers
Corporate signers

ℹ️ Googlers: Go here for more info.

@k8s-ci-robot
Copy link
Contributor

Hi @dldaisy. Thanks for your PR.

I'm waiting for a kubeflow member to verify that this patch is reasonable to test. If it is, they should reply with /ok-to-test on its own line. Until that is done, I will not automatically test new commits in this PR, but the usual testing commands by org members will still work. Regular contributors should join the org to skip this step.

Once the patch is verified, the new status will be reflected by the ok-to-test label.

I understand the commands that are listed here.

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.

@Bobgy
Copy link
Contributor

Bobgy commented Dec 3, 2019

/ok-to-test

Copy link
Contributor

@Bobgy Bobgy left a comment

Choose a reason for hiding this comment

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

Thanks! this is great.

Can you help me format code by npm run format. That should reduce most diffs.

@@ -180,6 +181,12 @@ func setPodSpecForTensorboard(view *viewerV1beta1.Viewer, s *corev1.PodSpec) {
// when https://github.com/kubeflow/pipelines/issues/2514 is done
// "--bind_all",
}

matched, _ := regexp.MatchString(`tensorflow/tensorflow:2.`, view.Spec.TensorboardSpec.TensorflowImage)
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: you are not using any regex features, just using string.startsWith is simpler

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks for the review and suggestion! I will re-format the code today.

@@ -19,7 +19,8 @@ import TensorboardViewer from './Tensorboard';
import TestUtils from '../../TestUtils';
import { Apis } from '../../lib/Apis';
import { PlotType } from './Viewer';
import { shallow } from 'enzyme';
import { shallow, mount } from 'enzyme';
import { resolve } from 'dns';
Copy link
Contributor

Choose a reason for hiding this comment

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

is this a mistake?

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 will look into it. It might be me forgetting to delete something after writing test.

@@ -56,6 +64,10 @@ class TensorboardViewer extends Viewer<TensorboardViewerProps, TensorboardViewer
this._checkTensorboardApp();
}

public onChangeFunc(e: React.ChangeEvent<{ name?: string; value: unknown }>): void {
Copy link
Contributor

Choose a reason for hiding this comment

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

2 notes:

  1. recommend using arrow function as field like
public onChangeFunc = (e: ...) => {
...
}

Arrow functions are bound automatically, then you can omit the .bind.. part when using it.

  1. name the function by what it does makes this more readable. e.g. selectVersion or handleVersionSelect

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 will rename the function. As for the arrow function, I didn't use it because when writing tests, I failed to invoke onChange arrow function with enzyme's simulate('change') method, although it works fine in real environment. Maybe we can discuss it later.

frontend/src/components/viewers/Tensorboard.tsx Outdated Show resolved Hide resolved
@@ -56,6 +64,10 @@ class TensorboardViewer extends Viewer<TensorboardViewerProps, TensorboardViewer
this._checkTensorboardApp();
}

public onChangeFunc(e: React.ChangeEvent<{ name?: string; value: unknown }>): void {
Copy link
Contributor

Choose a reason for hiding this comment

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

Behavior issue: after a version is selected, BusyButton state is no longer up-to-date, because it checks if the selected version instance exists or not.

I think the behavior could be confusing.
My imagined ideal behavior:

  1. backend finds tensorboard instance by logdir and reports which version it is running
  2. frontend shows to user there is an existing tensorboard with version xxx
  3. user can choose to stop it and start a new one with different version

What do you think? Feel free to say your opinion. We discuss to make the product.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, I agree. Since stopping and restarting a tensorboard requires a delete button, we plan to add the delete feature in next commit and the behavior will be completed as you mentioned above at that time.

@@ -101,4 +108,35 @@ describe('Tensorboard', () => {
it('is aggregatable', () => {
expect(TensorboardViewer.prototype.isAggregatable()).toBeTruthy();
});

it('set state', async () => {
Copy link
Contributor

Choose a reason for hiding this comment

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

Recommend reading this: https://kentcdodds.com/blog/making-your-ui-tests-resilient-to-change
Main point: test UI behavior, not implementation details.
Although the article advertises react testing library, but you can do similar testing style with enzyme.

Steps for this test:

  1. mount the component (not shallow)
  2. simulate clicking the select input
  3. simulate clicking an item
  4. verify UI shows your chosen item
  5. click start tensorboard button, verify it called api with the correct values

In this way, no matter how you refactor this UI component, you test remains the same as long as user behavior is the same.

Copy link
Contributor

Choose a reason for hiding this comment

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

(please address behavior comments first, before you actually work on the test)

if (!k8sV1CustomObjectClient) {
throw new Error('Cannot access kubernetes Custom Object API');
}
const currentPod = await getTensorboardInstance(logdir);
const currentPod = await getTensorboardInstance(logdir, tfversion);
Copy link
Contributor

Choose a reason for hiding this comment

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

What if there's a current pod with a different version?
Your steps below would fail because you are creating another viewer with the same name.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

After some discussion with Jing, we find we are facing two choices:

  1. Allow user to run more than one version at the same time, so with need to distinguish pods name by version. To implement this way, there might be several tensorboard deployments running at background, and the frontend will display which one will be opened.
  2. Another choice is only allow one version of tensorboard running at the same time. Because users mainly hope to choose a version that can be used correctly, this implementation might be functionally enough while keep the page concise. To implement this way, the "logdir" would be an unique identifier of the tensorboard folder. It's not until the user delete the previous version that he can open a new version, within the same logdir.

Maybe we can discuss later to decide which one to choose!

Copy link
Contributor

Choose a reason for hiding this comment

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

2 sgtm
Do you have a preference?

@dldaisy
Copy link
Contributor Author

dldaisy commented Dec 24, 2019

/retest

@@ -1769,7 +1769,8 @@
},
"ansi-regex": {
"version": "2.1.1",
"bundled": true
"bundled": true,
Copy link
Contributor

Choose a reason for hiding this comment

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

Note, this still needs to be reverted.

frontend/src/components/viewers/Tensorboard.test.tsx Outdated Show resolved Hide resolved
frontend/src/components/viewers/Tensorboard.test.tsx Outdated Show resolved Hide resolved
frontend/server/k8s-helper.ts Show resolved Hide resolved
frontend/server/k8s-helper.ts Show resolved Hide resolved
frontend/src/components/viewers/Tensorboard.tsx Outdated Show resolved Hide resolved
frontend/src/components/viewers/Tensorboard.tsx Outdated Show resolved Hide resolved
frontend/src/components/viewers/Tensorboard.tsx Outdated Show resolved Hide resolved
Copy link
Contributor

@Bobgy Bobgy left a comment

Choose a reason for hiding this comment

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

Thanks for the contribution!
/lgtm
/approve

@k8s-ci-robot k8s-ci-robot removed the lgtm label Dec 24, 2019
@jingzhang36
Copy link
Contributor

/lgtm

@dldaisy
Copy link
Contributor Author

dldaisy commented Dec 24, 2019

/retest

@k8s-ci-robot k8s-ci-robot removed the lgtm label Dec 24, 2019
@dldaisy
Copy link
Contributor Author

dldaisy commented Dec 24, 2019

/test kubeflow-pipeline-sample-test

@jingzhang36
Copy link
Contributor

/lgtm

@jingzhang36
Copy link
Contributor

/approve

@k8s-ci-robot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: Bobgy, jingzhang36

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

@nielsmeima
Copy link

nielsmeima commented Jul 1, 2020

Currently, the versions to pick from are hard-coded, however newer tags are available (which might solves issues like #2509). Could these be loaded dynamically?

EDIT: can confirm that using the tag 2.1.1 issue #2509 gets resolved.

Jeffwan pushed a commit to Jeffwan/pipelines that referenced this pull request Dec 9, 2020
* Support select tensorflow image for tensorboard

* modify test for tensorflow version select

* delete not available image entry

* Support tensorflow image selection to run tensorboard

* format code with prettier

* use HasPrefix instead of regexp

* delete

* modified tensorboard test

* delete tensorboard

* modify typo

* test tensorboard

* tensorboard test

* fuck

* fuck2

* modify test

* modify typo in tensorboard hint

* npm run format

* modify tensorboard snapshot

* compatible with previous kfp version. Allow vacant tensorflowImage field.

* add 2 tests for dialog

* modify default tensorflow image to 1.13.2

* merge get version and get tensorboard; let --bind_all support tensorboard3.x

* modify reconciler.go

* reconciler rollback

* modify corresponding test for --bind_all

* modify requested chances 12/23

* formControl sorted alphabetically

* select sorted alphabetically

* modify details from PR request 12/24

* moidfy format

* modify details 12/23

* modify snapshot

* retest

* retest
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants