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

Fix to more accurately communicate build statuses #91

Merged
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Fix to more accurately communicate build statuses
jeff-phillips-18 committed Sep 9, 2021
commit 32fee12ab0213de759b7e289f6c76d31d6be3aab
1 change: 1 addition & 0 deletions backend/src/types.ts
Original file line number Diff line number Diff line change
@@ -40,6 +40,7 @@ export type K8sResourceCommon = {
};

export enum BUILD_PHASE {
none = 'Not started',
new = 'New',
running = 'Running',
pending = 'Pending',
23 changes: 2 additions & 21 deletions backend/src/utils/resourceUtils.ts
Original file line number Diff line number Diff line change
@@ -209,7 +209,7 @@ const getBuildConfigStatus = (
if (bcBuilds.length === 0) {
return {
name: notebookName,
status: BUILD_PHASE.pending,
status: BUILD_PHASE.none,
};
}
const mostRecent = bcBuilds.sort(compareBuilds).pop();
@@ -229,7 +229,7 @@ const getBuildConfigStatus = (
};

export const fetchBuilds = async (fastify: KubeFastifyInstance): Promise<BuildStatus[]> => {
const nbBuildConfigs: K8sResourceCommon[] = await fastify.kube.customObjectsApi
const buildConfigs: K8sResourceCommon[] = await fastify.kube.customObjectsApi
.listNamespacedCustomObject(
'build.openshift.io',
'v1',
@@ -246,25 +246,6 @@ export const fetchBuilds = async (fastify: KubeFastifyInstance): Promise<BuildSt
.catch(() => {
return [];
});
const baseBuildConfigs: K8sResourceCommon[] = await fastify.kube.customObjectsApi
.listNamespacedCustomObject(
'build.openshift.io',
'v1',
fastify.kube.namespace,
'buildconfigs',
undefined,
undefined,
undefined,
'opendatahub.io/build_type=base_image',
)
.then((res) => {
return (res?.body as { items: K8sResourceCommon[] })?.items;
})
.catch(() => {
return [];
});

const buildConfigs = [...nbBuildConfigs, ...baseBuildConfigs];

const getters = buildConfigs.map(async (buildConfig) => {
return getBuildConfigStatus(fastify, buildConfig);
11 changes: 10 additions & 1 deletion frontend/src/app/App.scss
Original file line number Diff line number Diff line change
@@ -42,8 +42,17 @@ html, body, #root {
padding-bottom: 0;
}
}
&__message {
.pf-c-notification-drawer__list & {
margin-left: var(--pf-global--spacer--lg);
}
}
&__list {
list-style: disc;
margin-left: 20px;
margin-bottom: var(--pf-global--spacer--sm);
}
}

&__favorite {
cursor: pointer;
position: relative;
3 changes: 1 addition & 2 deletions frontend/src/app/AppNotificationDrawer.tsx
Original file line number Diff line number Diff line change
@@ -26,7 +26,7 @@ interface AppNotificationDrawerProps {
const AppNotificationDrawer: React.FC<AppNotificationDrawerProps> = ({ onClose }) => {
const notifications: AppNotification[] = useSelector<State, AppNotification[]>(
(state) => state.appState.notifications,
);
).sort((a, b) => b.timestamp.getTime() - a.timestamp.getTime());
const dispatch = useDispatch();
const newNotifications = React.useMemo(() => {
return notifications.filter((notification) => !notification.read).length;
@@ -67,7 +67,6 @@ const AppNotificationDrawer: React.FC<AppNotificationDrawerProps> = ({ onClose }
<NotificationDrawerListItemHeader
variant={notification.status}
title={notification.title}
srTitle={notification.title}
>
<div>
<Button
3 changes: 2 additions & 1 deletion frontend/src/redux/types.ts
Original file line number Diff line number Diff line change
@@ -11,9 +11,10 @@ export enum Actions {
FORCE_COMPONENTS_UPDATE = 'FORCE_COMPONENTS_UPDATE',
}

export type AppNotificationStatus = 'success' | 'danger' | 'warning' | 'info' | 'default';
export interface AppNotification {
id?: number;
status: 'success' | 'danger' | 'warning' | 'info' | 'default';
status: AppNotificationStatus;
title: string;
message?: React.ReactNode;
hidden?: boolean;
1 change: 1 addition & 0 deletions frontend/src/types.ts
Original file line number Diff line number Diff line change
@@ -87,6 +87,7 @@ export type OdhGettingStarted = {
};

export enum BUILD_PHASE {
none = 'Not started',
new = 'New',
running = 'Running',
pending = 'Pending',
53 changes: 50 additions & 3 deletions frontend/src/utilities/useWatchBuildStatus.tsx
Original file line number Diff line number Diff line change
@@ -5,6 +5,7 @@ import { POLL_INTERVAL } from './const';
import { useDeepCompareMemoize } from './useDeepCompareMemoize';
import { fetchBuildStatuses } from '../services/buildsService';
import { addNotification } from '../redux/actions/actions';
import { AppNotificationStatus } from '../redux/types';

const runningStatuses = [
BUILD_PHASE.new,
@@ -53,10 +54,13 @@ export const useWatchBuildStatus = (): void => {
if (!buildStatuses) {
return;
}
const wasNotStarted = filterBuilds(prevBuildStatuses.current, [BUILD_PHASE.none]);
const wasBuilding = filterBuilds(prevBuildStatuses.current, runningStatuses);
const wasFailed = filterBuilds(prevBuildStatuses.current, failedStatuses);
const notStarted = filterBuilds(buildStatuses, [BUILD_PHASE.none]);
const building = filterBuilds(buildStatuses, runningStatuses);
const failed = filterBuilds(buildStatuses, failedStatuses);
const complete = filterBuilds(buildStatuses, [BUILD_PHASE.complete]);

// Add notifications for new failures
if (failed.length > 0) {
@@ -73,6 +77,27 @@ export const useWatchBuildStatus = (): void => {
});
}

// Add notifications for new not started
if (notStarted.length && !wasNotStarted.length) {
dispatch(
addNotification({
status: 'danger',
title: 'These notebook image builds have not started:',
message: (
<div className="odh-dashboard__notifications__message">
<ul className="odh-dashboard__notifications__list">
{notStarted.map((build) => (
<li key={build.name}>{build.name}</li>
))}
</ul>
Contact your administrator to start the builds.
</div>
),
timestamp: new Date(),
}),
);
}

// Add notification if builds are now running
if (building.length && !wasBuilding.length) {
dispatch(
@@ -85,11 +110,33 @@ export const useWatchBuildStatus = (): void => {
}

// Add notification if all builds are now complete
if (wasBuilding.length && !building.length && !failed.length) {
if (
complete.length &&
(wasBuilding.length || wasNotStarted.length) &&
!building.length &&
!notStarted.length
) {
let status: AppNotificationStatus = 'success';
let message;
if (failed.length) {
status = complete.length ? 'warning' : 'danger';
message = (
<div className="odh-dashboard__notifications__message">
{complete.length} of {failed.length + complete.length} builds completed successfully.
<ul className="odh-dashboard__notifications__list">
{failed.map((build) => (
<li key={build.name}>{build.name} build image failed.</li>
))}
</ul>
Contact your administrator to retry failed images.
</div>
);
}
dispatch(
addNotification({
status: 'success',
title: 'All notebook images installed.',
status,
title: 'All notebook image builds are complete.',
message,
timestamp: new Date(),
}),
);
36 changes: 36 additions & 0 deletions install/odh/base/cluster-role.yaml
Original file line number Diff line number Diff line change
@@ -3,6 +3,15 @@ apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: odh-dashboard
rules:
- verbs:
- get
- watch
- list
apiGroups:
- ''
- config.openshift.io
resources:
- clusterversions
- verbs:
- get
- list
@@ -19,6 +28,7 @@ rules:
- ''
resources:
- services
- configmaps
- verbs:
- get
- list
@@ -27,3 +37,29 @@ rules:
- route.openshift.io
resources:
- routes
- verbs:
- get
- list
- watch
apiGroups:
- console.openshift.io
resources:
- consolelinks
- verbs:
- get
- list
- watch
apiGroups:
- operator.openshift.io
resources:
- consoles
- verbs:
- get
- watch
- list
apiGroups:
- ''
- integreatly.org
resources:
- rhmis

12 changes: 7 additions & 5 deletions install/odh/base/deployment.yaml
Original file line number Diff line number Diff line change
@@ -15,17 +15,17 @@ spec:
serviceAccount: odh-dashboard
containers:
- name: odh-dashboard
image: quay.io/opendatahub/odh-dashboard:latest
image: quay.io/modh/odh-dashboard:v1.0.11
imagePullPolicy: Always
ports:
- containerPort: 8080
resources:
requests:
cpu: 250m
memory: 300Mi
cpu: 300m
memory: 500Mi
limits:
cpu: 500m
memory: 1000Mi
memory: 1Gi
livenessProbe:
httpGet:
path: /api/status
@@ -45,4 +45,6 @@ spec:
timeoutSeconds: 15
periodSeconds: 30
successThreshold: 1
failureThreshold: 3
failureThreshold: 3
imagePullSecrets:
- name: addon-managed-odh-pullsecret
13 changes: 13 additions & 0 deletions install/odh/base/role.yaml
Original file line number Diff line number Diff line change
@@ -25,6 +25,7 @@ rules:
- create
- delete
- get
- list
- patch
- update
- watch
@@ -37,17 +38,29 @@ rules:
- create
- delete
- get
- list
- patch
- update
- watch
resources:
- cronjobs
- jobs
- jobs/status
- apiGroups:
- image.openshift.io
verbs:
- create
- get
- list
- patch
resources:
- imagestreams
- apiGroups:
- build.openshift.io
verbs:
- get
- list
- watch
resources:
- builds
- buildconfigs