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

Re-enable Snapshots tab #6807

Merged

Conversation

glekner
Copy link
Contributor

@glekner glekner commented Oct 1, 2020

No description provided.

@openshift-ci-robot openshift-ci-robot added the component/kubevirt Related to kubevirt-plugin label Oct 1, 2020
@@ -41,6 +49,8 @@ export const breadcrumbsForVMPage = (match: any) => () => [

export const VirtualMachinesDetailsPage: React.FC<VirtualMachinesDetailsPageProps> = (props) => {
const { name, ns: namespace } = props.match.params;
const [snapData, snapLoaded, snapErr] = useK8sGet(VirtualMachineSnapshotModel);
const isSnapshotSupported = snapData && snapLoaded && !snapErr;
Copy link
Member

Choose a reason for hiding this comment

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

can you please look at the original description of this bug https://bugzilla.redhat.com/show_bug.cgi?id=1881125 ? And fix the loading when reintroducing the snapshots again?

@openshift-ci-robot openshift-ci-robot added the component/shared Related to console-shared label Oct 4, 2020
@glekner
Copy link
Contributor Author

glekner commented Oct 4, 2020

@suomiy we now look for snapshots only in the relevant namespace. Is this solution sufficient?

@atiratree
Copy link
Member

@glekner we should check if the CRD is present

import { VMEnvironmentFirehose } from './vm-environment/vm-environment-page';
import { VMNics } from '../vm-nics';
import { PendingChangesWarningFirehose } from './pending-changes-warning';
import { VMSnapshotsPage } from '../vm-snapshots/vm-snapshots';
import {
Copy link
Contributor

Choose a reason for hiding this comment

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

nitpick: This should be above the kubevirt package imports. Of course, we can catch it in a follow-up if you don't have any other changes to make.

@openshift-ci-robot openshift-ci-robot added the component/core Related to console core functionality label Oct 6, 2020
@glekner
Copy link
Contributor Author

glekner commented Oct 6, 2020

@@ -41,6 +49,7 @@ export const breadcrumbsForVMPage = (match: any) => () => [

export const VirtualMachinesDetailsPage: React.FC<VirtualMachinesDetailsPageProps> = (props) => {
const { name, ns: namespace } = props.match.params;
const isSnapshotsAvailable = useModelLoaded(VirtualMachineSnapshotModel.kind);
Copy link
Member

Choose a reason for hiding this comment

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

shouldn't referenceForModel be used here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

depends on the use case, some would use referenceForModel(model) but in our case the resource in store is called VMSnapshotModel so we need VMSnapshotModel.kind

Copy link
Member

Choose a reason for hiding this comment

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

it might get loaded only with the group+version to the store so we should use referenceForModel to be safe

@@ -95,6 +102,7 @@ export const VirtualMachinesDetailsPage: React.FC<VirtualMachinesDetailsPageProp
consolePage,
nicsPage,
disksPage,
...(isSnapshotsAvailable ? [snapshotsPage] : []),
Copy link
Member

Choose a reason for hiding this comment

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

are we expecting more pages? IMO simple if would be more readable.

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 is a one line and it is a convention.
check https://github.com/openshift/console/blob/master/frontend/webpack.config.ts#L192 for example

Copy link
Member

Choose a reason for hiding this comment

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

I wouldn't cite webpack.config.ts as a convention. I know there are both use cases in the code base.

This one is less elegant.
Do as you want - I can live with both.

@@ -61,6 +61,9 @@ const useModelsLoaded = (): boolean => {
return ref.current;
};

export const useModelLoaded = (model: string): boolean =>
!!useSelector<RootState, K8sKind>(({ k8s }) => k8s.getIn(['RESOURCES', 'models', model]));
Copy link
Member

Choose a reason for hiding this comment

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

we could check for empty model first

Copy link
Contributor Author

Choose a reason for hiding this comment

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

react hooks shouldn't be called conditionally. eslint will shout at you

Copy link
Member

Choose a reason for hiding this comment

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

yes, unless the condition is inside

@@ -61,6 +61,9 @@ const useModelsLoaded = (): boolean => {
return ref.current;
};

export const useModelLoaded = (model: string): boolean =>
Copy link
Member

Choose a reason for hiding this comment

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

+1 hook might be useful

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
Member

Choose a reason for hiding this comment

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

yeah that sound much better

@@ -91,7 +98,22 @@ export const VMSnapshotsPage: React.FC<VMLikeEntityTabProps> = ({ obj: vmLikeEnt
[namespace],
);

const [snapshots, snapshotsLoaded, snapshotsError] = useK8sWatchResource<VMSnapshot[]>(resource);
const restoreResource: WatchK8sResource = React.useMemo(
Copy link
Contributor

Choose a reason for hiding this comment

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

useK8sWatchResource doesnt require memoized resource anymore :)

@@ -66,12 +56,14 @@ const getActions = (
return [];
}

const actions = [menuActionRestore, menuActionDelete];
const actions = [menuActionDelete];
Copy link
Member

Choose a reason for hiding this comment

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

what about the snapshot detail later?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

snapshot detail?
the restore is now a dedicated button for each row, not a kebab option

Copy link
Member

Choose a reason for hiding this comment

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

are we planning to have also snapshot details?

@@ -4,6 +4,8 @@ import { Kebab } from '@console/internal/components/utils';
export const snapshotsTableColumnClasses = [

This comment was marked as resolved.

@glekner glekner force-pushed the enable-snapshots-feature branch 4 times, most recently from 4be4c72 to 94050a7 Compare October 12, 2020 10:19
@@ -64,6 +64,13 @@ export const VMSnapshotsTable: React.FC<VMSnapshotsTableProps> = ({
sortField: 'status.readyToUse',
transforms: [sortable],
},
{
title: 'Last restored',
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@suomiy
since the latest restore date is computed inside the row component (because one snapshot can have multiple restore objects) we can't sort the table by it. do you have any suggestions?

https://github.com/openshift/console/pull/6807/files#diff-d4bb250ed498bbf43eeee21385193b71R146

Copy link
Contributor

Choose a reason for hiding this comment

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

@glekner you can use sortFunc prop

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Copy link
Member

Choose a reason for hiding this comment

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

I am not a big fan of expecting that the core code should handle our CRDs. Wouldn't it be more straightforward to just resolve the time here and pass it as a data like we do in our other tables?

@glekner glekner force-pushed the enable-snapshots-feature branch 3 times, most recently from 3c6c405 to 53faa72 Compare October 12, 2020 12:19
@glekner
Copy link
Contributor Author

glekner commented Oct 12, 2020

Updated to match latest design

Restore failed popover:
Screen Shot 2020-10-12 at 13 03 24

Restore in progress popover:
Screen Shot 2020-10-12 at 15 18 12

can you review @suomiy @matthewcarleton @yfrimanm

@yfrimanm
Copy link

Thanks @glekner
Nit: For the restoring popover, maybe we can make it clearer with: ''Virtual-machine-name 2019-8-28 is being restored from this snapshot''.

@@ -66,12 +56,14 @@ const getActions = (
return [];
}

const actions = [menuActionRestore, menuActionDelete];
const actions = [menuActionDelete];
Copy link
Member

Choose a reason for hiding this comment

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

are we planning to have also snapshot details?

const snapshotReady = isVMSnapshotReady(snapshot);

if (snapshotError) {
return <ErrorStatus title={'Create Failed'}>{snapshotError?.message}</ErrorStatus>;
Copy link
Member

Choose a reason for hiding this comment

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

can we also visit a snapshot detail when error occurs? like we can do with restore detail?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

user can access the snapshot details by clicking on its name in the table

Copy link
Member

@atiratree atiratree Oct 13, 2020

Choose a reason for hiding this comment

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

In that case, we are missing the restore action in the detail

@@ -6,4 +7,6 @@ export type VMSnapshotRowCustomData = {
vmLikeEntity: VMLikeEntityKind;
columnClasses: string[];
isDisabled: boolean;
restores: VMRestore[];
withProgress: (promise: Promise<any>) => void;
Copy link
Member

Choose a reason for hiding this comment

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

why do we need withProgress in snapshots?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

why not? its a resource creation like any other modal?

Copy link
Member

Choose a reason for hiding this comment

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

because this feature is used only by the wizard

Copy link
Member

Choose a reason for hiding this comment

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

ah you are right, It is used by the detail pages as well

@@ -64,6 +64,13 @@ export const VMSnapshotsTable: React.FC<VMSnapshotsTableProps> = ({
sortField: 'status.readyToUse',
transforms: [sortable],
},
{
title: 'Last restored',
Copy link
Member

Choose a reason for hiding this comment

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

I am not a big fan of expecting that the core code should handle our CRDs. Wouldn't it be more straightforward to just resolve the time here and pass it as a data like we do in our other tables?

const [restores, restoresLoaded, restoresError] = useK8sWatchResource<VMRestore[]>(
restoreResource,
);
const sortedRestores = React.useMemo(
Copy link
Member

Choose a reason for hiding this comment

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

it might be easier to create a map with getVmRestoreSnapshotName key here for better consumption.
Then it wouldn't need to be even sorted as you could just save the relevant restore.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

which snapshotName? one vm can have multiple snapshots with different names? a row for each.

Copy link
Member

Choose a reason for hiding this comment

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

yes, but relevant restore shoul be only one , right?

@glekner glekner force-pushed the enable-snapshots-feature branch 2 times, most recently from 9d33c17 to 2e359cc Compare October 15, 2020 14:09
@glekner
Copy link
Contributor Author

glekner commented Oct 15, 2020

  • mapped restores by key
  • changed kebab options to:
  1. Last Restore details (if available)
  2. Delete Snapshot
    image

@suomiy can you review?
the common kebab options can be confusing here because of the "Dual" resource page of snapshots/kebab. if a user wants to play with them, they should visit a specific resource page


const mappedRelevantRestores = React.useMemo(
() =>
restores.reduce((restoreMap, currentRestore) => {
Copy link
Member

Choose a reason for hiding this comment

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

this would be simpler

      restores.reduce((restoreMap, currentRestore) => {
        const relevantRestore = restoreMap[getVmRestoreSnapshotName(currentRestore)];
        if (!relevantRestore || new Date(getVmRestoreTime(relevantRestore)).getTime() < new Date(getVmRestoreTime(currentRestore)).getTime()) {
            restoreMap[getVmRestoreSnapshotName(currentRestore)] = currentRestore
        }
        return restoreMap
      }, {}),

@atiratree
Copy link
Member

the common kebab options can be confusing here because of the "Dual" resource page of snapshots/kebab. if a user wants to play with them, they should visit a specific resource page

I was under an impression that it would make more sense to show snapshots as one logical resources (ie as an aggregation of resources like vm/vmi does).
Do you think it makes sense to introduce VMRestore resource to the users? And what advantages does it have?

@glekner glekner force-pushed the enable-snapshots-feature branch 4 times, most recently from 3cda155 to 67b9267 Compare October 20, 2020 18:05
@glekner
Copy link
Contributor Author

glekner commented Oct 20, 2020

  • Created custom Details Page for VM Snapshot with Description if available
  • Added Restore action, Status and Last Restore(same new component like the table)
  • Removed Last Restore Details kebab option in a Snapshot row
  • Added breadcrumbs for VM context
  • Added Description input to Snapshot modal

Screen Shot 2020-10-20 at 21 03 00

@suomiy @matthewcarleton @yfrimanm can you take a look

Copy link
Member

@atiratree atiratree left a comment

Choose a reason for hiding this comment

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

@glekner we probably should ask for delete confirmation of snapshots when we delete the VM. The same we do with disks. To prevent stale snapshots being stored in the system.
Thoughts?

Also not sure if we want an owner reference on them.

<div className="row">
<div className="col-sm-6">
<ResourceSummary resource={obj} showAnnotations={false}>
{obj?.metadata?.annotations?.description && (
Copy link
Member

Choose a reason for hiding this comment

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

I think the convention is to show NA when the data is not there

Copy link
Member

Choose a reason for hiding this comment

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

also it might be useful to make it editable

return [
{
name: 'Virtualization',
path: `/k8s/ns/${namespace || 'default'}/virtualization`,
Copy link
Member

Choose a reason for hiding this comment

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

let's make a variable vmNamespace for this

isDisabled: !isVMSnapshotReady(snapshot),
callback: () => snapshotRestoreModal({ snapshot }),
}),
...common,
Copy link
Member

Choose a reason for hiding this comment

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

there is a discrepancy in the names Snapshot vs Virtual Machine Snapshot

snapshot,
}).result,
),
});

const menuActionDelete = (
Copy link
Member

Choose a reason for hiding this comment

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

could we have all the actions in the same place? eg menu-actions file? And use a subset of them in places where we need them.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We don't need any of it actually, the only kebab option as of now is Delete.so now just using
const { Delete } = Kebab.factory

) : (
<Status status={readyToUse ? 'Ready' : 'Not Ready'} />
);
export const VMSnapshotStatus: React.FC<VMSnapshotStatusProps> = ({ snapshot, restore }) => {
Copy link
Member

Choose a reason for hiding this comment

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

can you please move the status to standalone file?


const [restores, restoresLoaded] = useK8sWatchResource<VMRestore[]>(restoreResource);

const mappedRelevantRestores = React.useMemo(
Copy link
Member

Choose a reason for hiding this comment

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

could we make a hook for this, since we are using ti twice?

Copy link
Contributor

Choose a reason for hiding this comment

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

you could include useK8sWatchResource into the new hook and it would return [mappedRestores, loaded, error]

@glekner glekner force-pushed the enable-snapshots-feature branch 2 times, most recently from cde5803 to 279df00 Compare October 21, 2020 11:34
@glekner
Copy link
Contributor Author

glekner commented Oct 21, 2020

@suomiy @rawagner

  • Implemented suggestions
  • Created useMappedVMRestores hook
  • Made DescriptionModal generic to reuse in the snapshot details.

[restores],
);

return [mappedRelevantRestores, restoresLoaded, restoresError];
Copy link
Contributor

Choose a reason for hiding this comment

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

you can return directly from React.useMemo so you wont create a new array every time

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

},
{
name: `${vmName} Snapshots`,
path: `/k8s/ns/${match.params.ns ||
Copy link
Member

Choose a reason for hiding this comment

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

can use the variable here as well

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


export const VMDescriptionModal = withHandlePromise((props: VMDescriptionModalProps) => {
const { vmLikeEntity, inProgress, errorMessage, handlePromise, close, cancel } = props;
const DescriptionModal = withHandlePromise((props: DescriptionModalProps) => {
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 DescriptionModal = withHandlePromise((props: DescriptionModalProps) => {
const DescriptionModal = withHandlePromise<DescriptionModalProps>((props) => {

@@ -0,0 +1 @@
export * from './description-modal';
Copy link
Contributor

Choose a reason for hiding this comment

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

lets avoid creating new index files, they cause cyclic deps and we will be removing them in the future

<FormRow title="Description" fieldId={asId('desc')}>
<TextArea
value={description}
onChange={(d) => setDescription(d)}
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
onChange={(d) => setDescription(d)}
onChange={setDescription}

resources={[resource]}
menuActions={menuActions}
pages={pages}
breadcrumbsFor={(obj) => breadcrumbsForSnapshots(obj)}
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
breadcrumbsFor={(obj) => breadcrumbsForSnapshots(obj)}
breadcrumbsFor={breadcrumbsForSnapshots}

@@ -26,7 +25,7 @@ export const getLabelValue = (entity: K8sResourceKind, label: string): string =>

// Annotations
export const getAnnotations = (
vm: VMGenericLikeEntityKind,
vm: K8sResourceKind,
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
vm: K8sResourceKind,
vm: K8sResourceCommon,

@rawagner
Copy link
Contributor

/lgtm

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

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: glekner, rawagner

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-ci-robot openshift-ci-robot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Oct 22, 2020
@openshift-merge-robot openshift-merge-robot merged commit 36c50a9 into openshift:master Oct 22, 2020
@spadgett spadgett added this to the v4.7 milestone Oct 26, 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. component/core Related to console core functionality component/kubevirt Related to kubevirt-plugin component/shared Related to console-shared 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

8 participants