diff --git a/dashboard/src/app/diagnostics/diagnostic-callback-state.ts b/dashboard/src/app/diagnostics/diagnostic-callback-state.ts deleted file mode 100644 index 2f2e784255b..00000000000 --- a/dashboard/src/app/diagnostics/diagnostic-callback-state.ts +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (c) 2015-2018 Red Hat, Inc. - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Red Hat, Inc. - initial API and implementation - */ -/** - * Defines the state of the diagnostic callback - * @author Florent Benoit - */ -export const enum DiagnosticCallbackState { - OK, - FAILURE, - ERROR, - RUNNING, - HINT -} diff --git a/dashboard/src/app/diagnostics/diagnostic-callback.ts b/dashboard/src/app/diagnostics/diagnostic-callback.ts deleted file mode 100644 index 483b879a90c..00000000000 --- a/dashboard/src/app/diagnostics/diagnostic-callback.ts +++ /dev/null @@ -1,240 +0,0 @@ -/* - * Copyright (c) 2015-2018 Red Hat, Inc. - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Red Hat, Inc. - initial API and implementation - */ -import {DiagnosticItem} from './diagnostic-item'; -import {DiagnosticCallbackState} from './diagnostic-callback-state'; -import {DiagnosticPart} from './diagnostic-part'; -import {DiagnosticsController} from './diagnostics.controller'; - -/** - * Defines a callback of diagnostic. Allow to notify/report states, messages, etc. - * @author Florent Benoit - */ -export class DiagnosticCallback { - - /** - * Parent item. - */ - private diagnosticPart: DiagnosticPart; - - /** - * Promise service handling. - */ - private $q: ng.IQService; - - /** - * Angular Timeout service - */ - private $timeout: ng.ITimeoutService; - - /** - * defered object instance from q service - */ - private defered: ng.IDeferred; - - /** - * All timeouts that we're starting as part of this callback. They need to be stopped at the end. - */ - private timeoutPromises: Array>; - - /** - * Map used to send data across different fonctions. - */ - private sharedMap: Map; - - /** - * Builder when a new sibling callback is required to be added/build. - */ - private builder: DiagnosticsController; - - /** - * Name of the callback. - */ - private name: string; - - /** - * Content associated to the callback. - */ - private content: string; - - /** - * All items attached to this category. - */ - private items: Array; - - - /** - * Constructor. - */ - constructor($q: ng.IQService, $timeout: ng.ITimeoutService, name: string, sharedMap: Map, builder: any, diagnosticPart: DiagnosticPart) { - this.$q = $q; - this.$timeout = $timeout; - this.defered = $q.defer(); - this.timeoutPromises = new Array>(); - this.name = name; - this.sharedMap = sharedMap; - this.builder = builder; - this.diagnosticPart = diagnosticPart; - this.items = new Array(); - } - - /** - * Add the given value under the given key name. - * @param {string} key the key for the storage (a string) - * @param {any} value the value object - */ - public shared(key: string, value: any): void { - this.sharedMap.set(key, value); - } - - /** - * Allow to retrieved an object based on its key (string) - * @param {string} key the string name - * @returns {undefined|any} - */ - public getShared(key: string): any { - return this.sharedMap.get(key); - } - - /** - * Adds a running state item [like a new service that is now running received by server side event] - * @param {string} message the message to display - * @param {string=}hint extra hint - */ - public stateRunning(message: string, hint?: string): void { - this.newItem(message, hint, DiagnosticCallbackState.RUNNING); - this.cleanup(); - this.defered.resolve(message); - } - - /** - * Adds a success item [like the result of a test] - * @param {string} message the message to display - * @param {string} hint extra hint - */ - public success(message: string, hint?: string): void { - this.newItem(message, hint, DiagnosticCallbackState.OK); - this.cleanup(); - this.defered.resolve(message); - } - - /** - * Notify a failure. note: it doesn't stop the execution flow. A success or an error will come after a failure. - * @param {string} message the message to display - * @param {string} hint extra hint - */ - notifyFailure(message: string, hint?: string): void { - this.newItem(message, hint, DiagnosticCallbackState.FAILURE); - } - - /** - * Only notify a hint. - * @param {string} hint the hint to display - */ - notifyHint(hint: string): void { - this.newItem('', hint, DiagnosticCallbackState.HINT); - } - - /** - * Adds an error item [like the result of a test]. Note: it will break the current flow and cancel all existing promises. - * @param {string} message the message to display - * @param {string} hint extra hint - */ - public error(message: string, hint?: string): void { - this.newItem(message, hint, DiagnosticCallbackState.ERROR); - this.cleanup(); - this.defered.reject(message); - } - - /** - * Add content to the callback - * @param {string} content the content to add - */ - public addContent(content: string): void { - if (!this.content) { - this.content = content; - } else { - this.content += '\n' + content; - } - } - - /** - * Promise associated to this callback - * @returns {ng.IPromise} - */ - public getPromise(): ng.IPromise { - return this.defered.promise; - } - - /** - * Delay an error after a timeout. Allow to stop a test if there is no answer after some time. - * @param {string} message - * @param {number} delay the number of seconds to wait - */ - delayError(message: string, delay: number) { - let promise = this.$timeout(() => { - this.error(message); - }, delay); - this.timeoutPromises.push(promise); - } - - /** - * Delay a function after a timeout. - * @param {any} funct the callback function - * @param {number} delay the number of seconds to wait - */ - delayFunction(funct: any, delay: number) { - let promise = this.$timeout(funct, delay); - this.timeoutPromises.push(promise); - } - - - /** - * Cleanup all resources (like current promises) - */ - protected cleanup(): void { - this.timeoutPromises.forEach((promise: ng.IPromise) => { - this.$timeout.cancel(promise); - }); - this.timeoutPromises.length = 0; - } - - /** - * Builder of a sibling callback - * @param {string} text - * @returns {DiagnosticCallback} - */ - newCallback(text: string): DiagnosticCallback { - return this.builder.newItem(text, this.diagnosticPart); - } - - /** - * Build a new item instance - * @param {any} message the message to store in the item - * @param {string} hint any hint to add to the item - * @param {DiagnosticCallbackState} state the state of this newly item - * @returns {DiagnosticItem} the newly created object - */ - private newItem(message: any, hint: string, state: DiagnosticCallbackState) { - let diagnosticItem = new DiagnosticItem(); - diagnosticItem.title = this.name; - diagnosticItem.message = message; - if (hint) { - diagnosticItem.hint = hint; - } - diagnosticItem.state = state; - diagnosticItem.content = this.content; - this.diagnosticPart.addItem(diagnosticItem); - this.items.push(diagnosticItem); - return diagnosticItem; - } - -} diff --git a/dashboard/src/app/diagnostics/diagnostic-item.ts b/dashboard/src/app/diagnostics/diagnostic-item.ts deleted file mode 100644 index 9e9caca3fef..00000000000 --- a/dashboard/src/app/diagnostics/diagnostic-item.ts +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (c) 2015-2018 Red Hat, Inc. - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Red Hat, Inc. - initial API and implementation - */ -import {DiagnosticCallbackState} from './diagnostic-callback-state'; - -/** - * Item is a result of a test or an event to be notified to end user - * @author Florent Benoit - */ -export class DiagnosticItem { - - /** - * Title of the item. Describe the global stuff. - */ - public title: string; - - /** - * Message used to be displayed after the title of the item. - */ - public message: string; - - /** - * State of the current item. - */ - public state: DiagnosticCallbackState; - - /** - * Content is extra verbose stuff that could be displayed as part of the logs of the item. - */ - public content: string; - - /** - * Hint to report to the end-user. Something that could be helpful regarding the item. - */ - public hint: string; - - /** - * Checks the state of the item - * @returns {boolean} true if state is OK - */ - public isOk(): boolean { - return DiagnosticCallbackState.OK === this.state; - } - - /** - * Checks the state of the item - * @returns {boolean} true if state is OK - */ - public isSuccess(): boolean { - return DiagnosticCallbackState.OK === this.state; - } - - /** - * Checks the state of the item - * @returns {boolean} true if state is ERROR - */ - public isError(): boolean { - return DiagnosticCallbackState.ERROR === this.state; - } - - /** - * Checks the state of the item - * @returns {boolean} true if state is FAILURE - */ - public isFailure(): boolean { - return DiagnosticCallbackState.FAILURE === this.state; - } - - /** - * Checks the state of the item - * @returns {boolean} true if state is RUNNING - */ - public isRunning(): boolean { - return DiagnosticCallbackState.RUNNING === this.state; - } - - /** - * Checks the state of the item - * @returns {boolean} true if state is HINT - */ - public isHint(): boolean { - return DiagnosticCallbackState.HINT === this.state; - } - - /** - * Convert state to friendly text. - * @returns {any} - */ - public stateToText(): string { - switch (this.state) { - case DiagnosticCallbackState.RUNNING : - return 'STATE_RUNNING'; - case DiagnosticCallbackState.HINT : - return 'HINT'; - case DiagnosticCallbackState.OK : - return 'SUCCESS'; - case DiagnosticCallbackState.FAILURE : - return 'FAILURE'; - case DiagnosticCallbackState.ERROR : - return 'ERROR'; - } - } - -} diff --git a/dashboard/src/app/diagnostics/diagnostic-part-state.ts b/dashboard/src/app/diagnostics/diagnostic-part-state.ts deleted file mode 100644 index 91cca402bf7..00000000000 --- a/dashboard/src/app/diagnostics/diagnostic-part-state.ts +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (c) 2015-2018 Red Hat, Inc. - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Red Hat, Inc. - initial API and implementation - */ -/** - * Defines the state of the diagnostic part - * @author Florent Benoit - */ -export const enum DiagnosticPartState { - READY, - IN_PROGRESS, - SUCCESS, - FAILURE, - ERROR -} diff --git a/dashboard/src/app/diagnostics/diagnostic-part.ts b/dashboard/src/app/diagnostics/diagnostic-part.ts deleted file mode 100644 index 53ee4764433..00000000000 --- a/dashboard/src/app/diagnostics/diagnostic-part.ts +++ /dev/null @@ -1,210 +0,0 @@ -/* - * Copyright (c) 2015-2018 Red Hat, Inc. - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Red Hat, Inc. - initial API and implementation - */ -import {DiagnosticItem} from './diagnostic-item'; -import {DiagnosticPartState} from './diagnostic-part-state'; -import {DiagnosticCallback} from './diagnostic-callback'; - -/** - * A part or category is a grouping capability of Diagnostics callbacks. It allows to group callback in some groups. - * @author Florent Benoit - */ -export class DiagnosticPart { - - /** - * The title of the part. - */ - title: string; - - /** - * An optional subtitle of this part. - */ - subtitle: string; - - /** - * The current state of this category - */ - state: DiagnosticPartState; - - /** - * Display icon of this part. - */ - icon: string; - - /** - * All items attached to this category. - */ - private items: Array; - - /** - * All callbacks attached to this category. - */ - private callbacks: Array; - - /** - * Current promises of all callbacks - */ - private callbackPromises: Array>; - - /** - * Number of callbacks (tests) that have finished. - */ - private nbEndedCallbacks: number; - - /** - * Number of callbacks (tests) that have been successful. - */ - private nbSuccessCallbacks: number; - - /** - * Number of callbacks that had errors - */ - private nbErrorCallbacks: number; - - /** - * Callbacks that have ended - */ - private callbacksEnded: Array; - - /** - * Constructor. - */ - constructor() { - this.items = new Array(); - this.callbacks = new Array(); - this.callbacksEnded = new Array(); - this.callbackPromises = new Array>(); - this.nbEndedCallbacks = 0; - this.nbSuccessCallbacks = 0; - this.nbErrorCallbacks = 0; - } - - /** - * Add an item to this part. - * @param {DiagnosticItem} item the item to add - */ - addItem(item: DiagnosticItem): void { - this.items.push(item); - } - - /** - * Test callback to add to this part - * @param {DiagnosticCallback} callback the test callback to add. - */ - addCallback(callback: DiagnosticCallback): void { - - callback.getPromise().then(() => { - this.nbSuccessCallbacks++; - }); - - callback.getPromise().catch(() => { - this.nbErrorCallbacks++; - }); - - callback.getPromise().finally(() => { - this.callbacksEnded.push(callback); - this.nbEndedCallbacks++; - }); - - this.callbackPromises.push(callback.getPromise()); - this.callbacks.push(callback); - } - - /** - * Checks the state of the part - * @returns {boolean} true if state is READY - */ - public isReady(): boolean { - return DiagnosticPartState.READY === this.state; - } - - /** - * Checks the state of the part - * @returns {boolean} true if state is IN_PROGRESS - */ - public isInProgress(): boolean { - return DiagnosticPartState.IN_PROGRESS === this.state; - } - - /** - * Checks the state of the part - * @returns {boolean} true if state is SUCCESS - */ - public isSuccess(): boolean { - return DiagnosticPartState.SUCCESS === this.state; - } - - /** - * Checks the state of the part - * @returns {boolean} true if state is FAILURE - */ - public isFailure(): boolean { - return DiagnosticPartState.FAILURE === this.state; - } - - /** - * Checks the state of the part - * @returns {boolean} true if state is ERROR - */ - public isError(): boolean { - return DiagnosticPartState.ERROR === this.state; - } - - /** - * Convert state to friendly text. - * @returns {string} - */ - public stateToText(): string { - switch (this.state) { - case DiagnosticPartState.READY : - return 'READY (planned)'; - case DiagnosticPartState.IN_PROGRESS : - return 'IN PROGRESS'; - case DiagnosticPartState.SUCCESS : - return 'SUCCESS'; - case DiagnosticPartState.FAILURE : - return 'FAILURE'; - case DiagnosticPartState.ERROR : - return 'ERROR'; - } - } - - /** - * Clear the values - */ - clear(): void { - this.nbEndedCallbacks = 0; - this.nbSuccessCallbacks = 0; - this.nbErrorCallbacks = 0; - this.items.length = 0; - this.callbacks.length = 0; - this.callbacksEnded.length = 0; - this.callbackPromises.length = 0; - } - - /** - * Gets the total number of callbacks - * @returns {number} - */ - public getNumberOfCallbacks(): number { - return this.callbacks.length; - } - - /** - * Gets the total number of ended callbacks - * @returns {number} - */ - public getNumberOfEndedCallbacks(): number { - return this.nbEndedCallbacks; - } - - -} diff --git a/dashboard/src/app/diagnostics/diagnostics-config.ts b/dashboard/src/app/diagnostics/diagnostics-config.ts deleted file mode 100644 index 36dc95f952e..00000000000 --- a/dashboard/src/app/diagnostics/diagnostics-config.ts +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2015-2018 Red Hat, Inc. - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Red Hat, Inc. - initial API and implementation - */ -'use strict'; - - -import {Diagnostics} from './diagnostics.directive'; -import {DiagnosticsController} from './diagnostics.controller'; -import {DiagnosticsWebsocketWsMaster} from './test/diagnostics-websocket-wsmaster.factory'; -import {DiagnosticsWorkspaceStartCheck} from './test/diagnostics-workspace-start-check.factory'; -import {DiagnosticsRunningWorkspaceCheck} from './test/diagnostics-workspace-check-workspace.factory'; - -/** - * Diagnostics configuration - * @author Florent Benoit - */ -export class DiagnosticsConfig { - - constructor(register: che.IRegisterService) { - - register.factory('diagnosticsWebsocketWsMaster', DiagnosticsWebsocketWsMaster); - register.factory('diagnosticsWorkspaceStartCheck', DiagnosticsWorkspaceStartCheck); - register.factory('diagnosticsRunningWorkspaceCheck', DiagnosticsRunningWorkspaceCheck); - - register.directive('diagnostics', Diagnostics); - register.controller('DiagnosticsController', DiagnosticsController); - - // config routes - register.app.config(['$routeProvider', ($routeProvider: che.route.IRouteProvider) => { - $routeProvider.accessWhen('/diagnostic', { - title: 'Diagnostic', - templateUrl: 'app/diagnostics/diagnostics.html' - }); - }]); - - } -} diff --git a/dashboard/src/app/diagnostics/diagnostics-widget.html b/dashboard/src/app/diagnostics/diagnostics-widget.html deleted file mode 100644 index 9ed55c37133..00000000000 --- a/dashboard/src/app/diagnostics/diagnostics-widget.html +++ /dev/null @@ -1,172 +0,0 @@ - - -
- - -
-
-
- - - - - - - - -
-
-
{{diagnosticsController.globalStatusText}}
-
No Errors Found
-
All Tests Passed
-
Error!
- -
-
-
- -
- -
 
-
-
- -
-
-
- -
-
-
-
-
-
-
-
{{part.title}} -
-
- {{part.subtitle}}
-
-
{{(part.getNumberOfEndedCallbacks() / part.getNumberOfCallbacks()) * 100 | number:0}}%
-
-
- - - - - - - - -
-
- Initializing... -
-
- TestingTested {{part.getNumberOfEndedCallbacks()}} of {{part.getNumberOfCallbacks()}} -
-
- -
-
-
-
-
- -
Testing {{diagnosticsController.currentPart.title}}. Wait for results. -
- - -
-
-
- -
-
-
-
-
-
-
- - - - - - -
-
-
- {{item.title}} -
-
{{item.message}}
-
Hint: {{item.hint}}
-
-
-
-
-
-
-
-
-
-
-
- -
-
Logs
-
-
{{part.title}} {{part.subtitle}} : {{part.stateToText()}}
-
-
{{callback.name}}
-
{{callback.content}}
-
-
-
{{item.message}}
-
 --- {{item.stateToText()}}
-
-
{{item.hint}}
-
-
-
-
- - -
-
diff --git a/dashboard/src/app/diagnostics/diagnostics.controller.ts b/dashboard/src/app/diagnostics/diagnostics.controller.ts deleted file mode 100644 index b10e48bd467..00000000000 --- a/dashboard/src/app/diagnostics/diagnostics.controller.ts +++ /dev/null @@ -1,337 +0,0 @@ -/* - * Copyright (c) 2015-2018 Red Hat, Inc. - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Red Hat, Inc. - initial API and implementation - */ -'use strict'; -import {DiagnosticsWebsocketWsMaster} from './test/diagnostics-websocket-wsmaster.factory'; -import {DiagnosticCallback} from './diagnostic-callback'; -import {DiagnosticsWorkspaceStartCheck} from './test/diagnostics-workspace-start-check.factory'; -import {DiagnosticsRunningWorkspaceCheck} from './test/diagnostics-workspace-check-workspace.factory'; -import {DiagnosticPart} from './diagnostic-part'; -import {DiagnosticPartState} from './diagnostic-part-state'; -import {CheBranding} from '../../components/branding/che-branding.factory'; - -/** - * @ngdoc controller - * @name diagnostics.controller:DiagnosticsController - * @description This class is handling the controller for the diagnostics page - * @author Florent Benoit - */ -export class DiagnosticsController { - - static $inject = ['$log', '$q', 'lodash', '$timeout', 'diagnosticsWebsocketWsMaster', 'cheBranding', 'diagnosticsRunningWorkspaceCheck', 'diagnosticsWorkspaceStartCheck']; - - /** - * Promise service handling. - */ - private $q: ng.IQService; - - /** - * Log service. - */ - private $log: ng.ILogService; - - /** - * Lodash utility. - */ - private lodash: any; - - /** - * Instance of checker for websockets - */ - private diagnosticsWebsocketWsMaster: DiagnosticsWebsocketWsMaster; - - /** - * Instance of checker for workspace - */ - private diagnosticsWorkspaceStartCheck: DiagnosticsWorkspaceStartCheck; - - /** - * Angular timeout service. - */ - private $timeout: ng.ITimeoutService; - - /** - * Shared Map across all parts. - */ - private sharedMap: Map; - - /** - * Reference to the diagnostic workspace checker. - */ - private diagnosticsRunningWorkspaceCheck: DiagnosticsRunningWorkspaceCheck; - - /** - * List of all parts. - */ - private parts: Array; - - /** - * Link to the workspace master part - */ - private wsMasterPart: DiagnosticPart; - - /** - * Link to the workspace agent part - */ - private wsAgentPart: DiagnosticPart; - - /** - * Alias for the current part being tested - */ - private currentPart: DiagnosticPart; - - /** - * Allow to turn on/off details - */ - private showDetails: boolean = false; - - /** - * Global state - */ - private state: DiagnosticPartState; - - /** - * Text to be displayed as global status - */ - private globalStatusText: string; - - /** - * Branding info. - */ - private cheBranding: CheBranding; - - /** - * Show/hide logs - */ - private isLogDisplayed: boolean; - - /** - * Default constructor that is using resource - */ - constructor($log: ng.ILogService, $q: ng.IQService, lodash: any, - $timeout: ng.ITimeoutService, - diagnosticsWebsocketWsMaster: DiagnosticsWebsocketWsMaster, - cheBranding: CheBranding, - diagnosticsRunningWorkspaceCheck: DiagnosticsRunningWorkspaceCheck, - diagnosticsWorkspaceStartCheck: DiagnosticsWorkspaceStartCheck) { - this.$q = $q; - this.$log = $log; - this.lodash = lodash; - this.$timeout = $timeout; - this.diagnosticsWebsocketWsMaster = diagnosticsWebsocketWsMaster; - this.diagnosticsWorkspaceStartCheck = diagnosticsWorkspaceStartCheck; - this.diagnosticsRunningWorkspaceCheck = diagnosticsRunningWorkspaceCheck; - this.parts = new Array(); - this.sharedMap = new Map(); - this.cheBranding = cheBranding; - this.isLogDisplayed = false; - this.state = DiagnosticPartState.READY; - this.globalStatusText = 'Ready To Start'; - - this.wsMasterPart = new DiagnosticPart(); - this.wsMasterPart.icon = 'fa fa-cube'; - this.wsMasterPart.title = 'Server Tests'; - this.wsMasterPart.state = DiagnosticPartState.READY; - this.wsMasterPart.subtitle = 'Connectivity checks to the ' + this.cheBranding.getName() + ' server'; - - this.wsAgentPart = new DiagnosticPart(); - this.wsAgentPart.icon = 'fa fa-cubes'; - this.wsAgentPart.title = 'Workspace Tests'; - this.wsAgentPart.state = DiagnosticPartState.READY; - this.wsAgentPart.subtitle = 'Connectivity checks to Dockerized workspaces'; - } - - /** - * Start the tests. - */ - public start(): void { - this.sharedMap.clear(); - this.globalStatusText = 'Running Tests'; - this.state = DiagnosticPartState.IN_PROGRESS; - - this.parts.length = 0; - this.parts.push(this.wsMasterPart); - this.parts.push(this.wsAgentPart); - this.parts.forEach((part: DiagnosticPart) => { - part.clear(); - }); - - this.currentPart = this.wsMasterPart; - - // first check websocket on workspace master - this.checkWorkspaceMaster().then(() => { - return this.checkWorkspaceAgent(); - }).then(() => { - return this.waitAllCompleted([this.checkWorkspaceCheck(), this.checkWebSocketWsAgent()]); - }).then(() => { - this.globalStatusText = 'Completed Diagnostics'; - this.state = DiagnosticPartState.SUCCESS; - }).catch((error: any) => { - this.globalStatusText = 'Diagnostics Finished With Error'; - this.state = DiagnosticPartState.ERROR; - }); - } - - /** - * Wait for all promises to be terminate and not stop at the first error - * @param promises an array of promises - * @returns {ng.IPromise} - */ - waitAllCompleted(promises: Array>): ng.IPromise { - const allCompletedDefered = this.$q.defer(); - let finished: number = 0; - let toFinish: number = promises.length; - let error: boolean = false; - promises.forEach((promise: ng.IPromise) => { - promise.catch(() => { - error = true; - }).finally(() => { - finished++; - if (finished === toFinish) { - if (error) { - this.currentPart.state = DiagnosticPartState.ERROR; - allCompletedDefered.reject('error'); - } else { - allCompletedDefered.resolve('success'); - } - } - }); - }); - return allCompletedDefered.promise; - } - - /** - * Build a new callback item - * @param text the text to set in the callback - * @param diagnosticPart the diagnostic part - * @returns {DiagnosticCallback} the newly callback - */ - public newItem(text: string, diagnosticPart: DiagnosticPart): DiagnosticCallback { - let callback: DiagnosticCallback = new DiagnosticCallback(this.$q, this.$timeout, text, this.sharedMap, this, diagnosticPart); - diagnosticPart.addCallback(callback); - return callback; - } - - /** - * Sets the details part. - * @param part the part to be displayed for the details - */ - public setDetailsPart(part: DiagnosticPart): void { - this.currentPart = part; - } - - /** - * Checks the workspace master. - * @returns {ng.IPromise} - */ - public checkWorkspaceMaster(): ng.IPromise { - this.currentPart = this.wsMasterPart; - - this.wsMasterPart.state = DiagnosticPartState.IN_PROGRESS; - let promiseWorkspaceMaster: ng.IPromise = this.diagnosticsWebsocketWsMaster.start(this.newItem('Websockets', this.wsMasterPart)); - promiseWorkspaceMaster.then(() => { - this.wsMasterPart.state = DiagnosticPartState.SUCCESS; - }).catch((error: any) => { - this.wsMasterPart.state = DiagnosticPartState.ERROR; - }); - - return promiseWorkspaceMaster; - } - - /** - * Checks the workspace agent. - * @returns {ng.IPromise} - */ - public checkWorkspaceAgent(): ng.IPromise { - this.currentPart = this.wsAgentPart; - - this.wsAgentPart.state = DiagnosticPartState.IN_PROGRESS; - let promiseWorkspaceAgent: ng.IPromise = this.diagnosticsWorkspaceStartCheck.start(this.newItem('Create Workspace', this.wsAgentPart)); - promiseWorkspaceAgent.then(() => { - this.wsAgentPart.state = DiagnosticPartState.SUCCESS; - }).catch((error: any) => { - this.wsAgentPart.state = DiagnosticPartState.ERROR; - }); - - return promiseWorkspaceAgent; - } - - /** - * Check the REST API on ws agent - * @returns {ng.IPromise} - */ - public checkWorkspaceCheck(): ng.IPromise { - return this.diagnosticsRunningWorkspaceCheck.checkWsAgent(this.newItem('REST Call on Workspace Agent', this.wsAgentPart), true); - } - - /** - * Check the websockets on ws agent - * @returns {ng.IPromise} - */ - public checkWebSocketWsAgent(): ng.IPromise { - return this.diagnosticsRunningWorkspaceCheck.checkWebSocketWsAgent(this.newItem('Websocket on Workspace Agent', this.wsAgentPart)); - } - - /** - * Allow to toggle details - */ - public toggleDetails(): void { - this.showDetails = !this.showDetails; - } - - /** - * Checks the state of the controller - * @returns {boolean} true if state is READY - */ - public isReady(): boolean { - return DiagnosticPartState.READY === this.state; - } - - /** - * Checks the state of the controller - * @returns {boolean} true if state is IN_PROGRESS - */ - public isInProgress(): boolean { - return DiagnosticPartState.IN_PROGRESS === this.state; - } - - /** - * Checks the state of the controller - * @returns {boolean} true if state is SUCCESS - */ - public isSuccess(): boolean { - return DiagnosticPartState.SUCCESS === this.state; - } - - /** - * Checks the state of the controller - * @returns {boolean} true if state is FAILURE - */ - public isFailure(): boolean { - return DiagnosticPartState.FAILURE === this.state; - } - - /** - * Checks the state of the controller - * @returns {boolean} true if state is ERROR - */ - public isError(): boolean { - return DiagnosticPartState.ERROR === this.state; - } - - /** - * Toggle log display. - */ - public showLogs(): void { - this.isLogDisplayed = !this.isLogDisplayed; - } - -} diff --git a/dashboard/src/app/diagnostics/diagnostics.directive.ts b/dashboard/src/app/diagnostics/diagnostics.directive.ts deleted file mode 100644 index 79702ed5880..00000000000 --- a/dashboard/src/app/diagnostics/diagnostics.directive.ts +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2015-2018 Red Hat, Inc. - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Red Hat, Inc. - initial API and implementation - */ -'use strict'; - -/** - * @ngdoc directive - * @name diagnostics.directive:diagnostics - * @restrict E - * @element - * - * @description - * ` for displaying diagnostics. - * - * @usage - * - * - * @author Florent Benoit - */ -export class Diagnostics implements ng.IDirective { - - replace: boolean = false; - restrict: string = 'E'; - templateUrl: string = 'app/diagnostics/diagnostics-widget.html'; - controller: string = 'DiagnosticsController'; - controllerAs: string = 'diagnosticsController'; - bindToController: boolean = true; - - scope: { - [propName: string]: string - }; - - /** - * Default constructor that is using resource - */ - constructor() { - // scope values - this.scope = {}; - } - -} diff --git a/dashboard/src/app/diagnostics/diagnostics.html b/dashboard/src/app/diagnostics/diagnostics.html deleted file mode 100644 index e870046c5b9..00000000000 --- a/dashboard/src/app/diagnostics/diagnostics.html +++ /dev/null @@ -1,18 +0,0 @@ - - -Self diagnostic tool. - - - diff --git a/dashboard/src/app/diagnostics/diagnostics.styl b/dashboard/src/app/diagnostics/diagnostics.styl deleted file mode 100644 index 2ac5aae63e9..00000000000 --- a/dashboard/src/app/diagnostics/diagnostics.styl +++ /dev/null @@ -1,210 +0,0 @@ -.diagnostics-content - overflow visible - min-height 110px - padding 0 0 15px 0 - - .che-diagnostic-parent-list - margin-left 20px - margin-right 20px - border 1px solid $list-separator-color - - .che-list-diagnostic - min-height 50vh - max-height 50vh - margin-left 0px - margin-right 0px - - .diagnostics-toolbar-progress - width 150px - height 150px - - .che-list-item-diagnostic - padding 20px - - .che-list-diagnostic-empty-state - margin 40px - min-height 50vh - max-height 50vh - - .che-list-item-content - line-height 20px !important - - .diagnostics-toolbar - margin-left 40px - margin-right 40px - margin-bottom 20px - margin-top 20px - - .diagnostics-action - margin-left 20px - margin-right 20px - border-top 1px solid $list-separator-color - padding-top 40px - - .diagnostic-part-content - padding 20px - - .diagnostic-test-numbers - color $list-action-color - - .diagnostic-item-message - color $list-action-color - - .diagnostic-part-link-details - min-width 70px - font-weight bold - font-size 1.4em - color $list-action-color - - .diagnostics-toolbar-main-title - font-size 2.5em - - .diagnostics-toolbar-main-title-success - color $secondary-color - - .diagnostics-toolbar-main-title-error - color $error-color - - .diagnostics-toolbar-main-title-ready - color $label-primary-color - - .diagnostics-toolbar-main-title-progress - color $primary-color - - .diagnostics-toolbar-main-title-failure - color $warning-color - - - .diagnostics-toolbar-main-subtitle - font-size 1.5em - color $label-primary-color - - .diagnotic-hints-title - margin-left 10px - font-size 22px - font-weight bold - - .diagnostic-button - min-height 50px - min-width 220px - - .diagnostic-part - position relative - min-height 150px - max-height 150px - padding 10px - cursor pointer - outline none - - .diagnostic-part:hover - background-color $list-checkbox-background-color - - .diagnostic-part-selected - background-color $table-header-color - - .diagnostics-dropdown - position absolute - right 15px - bottom 10px - font-size 13px - cursor pointer - - .diagnostic-part-subtitle - color $list-action-color - margin-bottom 3px - margin-left 5px - - .diagnostic-part-percent - color $list-action-color - margin-top 3px - - .diagnostic-part-title - font-size 1.5em - font-weight bold - text-transform uppercase - letter-spacing 1.95px - - .diagnostic-part-icon - font-size 48px - - .diagnostic-part-progress - margin-top 20px - margin-bottom 20px !important - - .diagnostics-output - white-space pre !important - line-height 22px - font-family monospace - background-color lightgrey - margin-left 45px - padding 5px - overflow-y scroll !important - max-height 200px - - .check-item-icon - color $label-info-color - line-height inherit - font-size 20px !important - margin 1px 5px - - .check-item-ok - color $secondary-color - - .check-item-running - color $secondary-color - - .check-item-ko - color $error-color - - .check-item-fail - color $warning-color - - .hint-item - color $secondary-light - - .hint-item-icon - margin-right 5px - line-height inherit - font-size 17px - margin-bottom -7px - - .check-spinner - margin-left 10px - .check-spinner .spinner - margin-top 5px - width 24px - height 30px - font-size 30px - div - width 4px - border-radius 0 - margin-right 2px - - - .diagnostic-log-part - margin 20px - - .diagnostic-log-part-title - font-size 1.2em - text-transform uppercase - font-weight bold - letter-spacing 1.1px - - .diagnostic-log-callback - margin-left 20px - padding 10px - background lightgrey - margin-top 16px - - .diagnostic-log-callback-title - font-weight bold - - .diagnostic-log-callback-content - font-size 9px - white-space pre-wrap - margin-left 20px - font-family monospace - - .diagnostic-log-title - font-size 2em - text-transform uppercase diff --git a/dashboard/src/app/diagnostics/test/diagnostics-websocket-wsmaster.factory.ts b/dashboard/src/app/diagnostics/test/diagnostics-websocket-wsmaster.factory.ts deleted file mode 100644 index 52cdd1b64cb..00000000000 --- a/dashboard/src/app/diagnostics/test/diagnostics-websocket-wsmaster.factory.ts +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (c) 2015-2018 Red Hat, Inc. - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Red Hat, Inc. - initial API and implementation - */ -'use strict'; -import {DiagnosticCallback} from '../diagnostic-callback'; -import {CheJsonRpcApi} from '../../../components/api/json-rpc/che-json-rpc-api.factory'; -import {CheJsonRpcMasterApi} from '../../../components/api/json-rpc/che-json-rpc-master-api'; -import {CheAPI} from '../../../components/api/che-api.factory'; - -/** - * Test for launching websocket connection to the workspace master - * @author Florent Benoit - */ -export class DiagnosticsWebsocketWsMaster { - - static $inject = ['cheAPI', 'cheJsonRpcApi', '$timeout']; - - private jsonRpcMasterApi: CheJsonRpcMasterApi; - private wsMasterLocation: string; - - /** - * Timeout handling. - */ - private $timeout: ng.ITimeoutService; - - /** - * Default constructor - */ - constructor(cheAPI: CheAPI, cheJsonRpcApi: CheJsonRpcApi, $timeout: ng.ITimeoutService) { - this.wsMasterLocation = cheAPI.getWorkspace().getJsonRpcApiLocation(); - this.jsonRpcMasterApi = cheJsonRpcApi.getJsonRpcMasterApi(this.wsMasterLocation); - this.$timeout = $timeout; - } - - /** - * Start the diagnostic and report all progress through the callback - * @param {DiagnosticCallback} diagnosticCallback - * @returns {ng.IPromise} when test is finished - */ - start(diagnosticCallback: DiagnosticCallback): ng.IPromise { - try { - // define callback - let callback = (message: any) => { - diagnosticCallback.success('Websocket message received'); - }; - - this.jsonRpcMasterApi.connect(this.wsMasterLocation).then(() => { - this.jsonRpcMasterApi.fetchClientId().then(callback); - // default fallback if no answer in 5 seconds - diagnosticCallback.delayError('No reply of websocket test after 5 seconds. Websocket is failing to connect to ' + this.wsMasterLocation, 5000); - }); - } catch (error) { - diagnosticCallback.error('Unable to connect with websocket to ' + this.wsMasterLocation + ': ' + error); - } - return diagnosticCallback.getPromise(); - } - -} diff --git a/dashboard/src/app/diagnostics/test/diagnostics-workspace-check-workspace.factory.ts b/dashboard/src/app/diagnostics/test/diagnostics-workspace-check-workspace.factory.ts deleted file mode 100644 index 646f01a4503..00000000000 --- a/dashboard/src/app/diagnostics/test/diagnostics-workspace-check-workspace.factory.ts +++ /dev/null @@ -1,251 +0,0 @@ -/* - * Copyright (c) 2015-2018 Red Hat, Inc. - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Red Hat, Inc. - initial API and implementation - */ -'use strict'; -import {DiagnosticCallback} from '../diagnostic-callback'; -import {CheWorkspace} from '../../../components/api/workspace/che-workspace.factory'; -import {CheBranding} from '../../../components/branding/che-branding.factory'; -import {CheJsonRpcApi} from '../../../components/api/json-rpc/che-json-rpc-api.factory'; -import {CheJsonRpcWsagentApi} from '../../../components/api/json-rpc/che-json-rpc-wsagent-api'; - -/** - * Ability to tests a running workspace. - * @author Florent Benoit - */ -export class DiagnosticsRunningWorkspaceCheck { - - static $inject = ['$q', 'lodash', 'cheWorkspace', 'cheJsonRpcApi', '$resource', '$location', 'cheBranding']; - - /** - * Q service for creating delayed promises. - */ - private $q: ng.IQService; - - /** - * Workspace API used to grab details. - */ - private cheWorkspace; - - /** - * JSON RPC API factory. - */ - private cheJsonRpcApi: CheJsonRpcApi; - - /** - * Lodash utility. - */ - private lodash: any; - - /** - * Resource service used in tests. - */ - private $resource: ng.resource.IResourceService; - - /** - * Location service used to get data from browser URL. - */ - private $location: ng.ILocationService; - - /** - * Branding info. - */ - private cheBranding: CheBranding; - - /** - * Default constructor - */ - constructor($q: ng.IQService, lodash: any, cheWorkspace: CheWorkspace, cheJsonRpcApi: CheJsonRpcApi, - $resource: ng.resource.IResourceService, $location: ng.ILocationService, cheBranding: CheBranding) { - this.$q = $q; - this.lodash = lodash; - this.cheWorkspace = cheWorkspace; - this.cheJsonRpcApi = cheJsonRpcApi; - this.cheBranding = cheBranding; - this.$resource = $resource; - this.$location = $location; - } - - /** - * Check WS Agent by using the browser host - * @param {DiagnosticCallback} diagnosticCallback - * @returns {ng.IPromise} - */ - checkAgentWithBrowserHost(diagnosticCallback: DiagnosticCallback): ng.IPromise { - - let wsAgentHRef = this.getWsAgentURL(diagnosticCallback); - let parser = document.createElement('a'); - parser.href = wsAgentHRef; - wsAgentHRef = parser.protocol + '//' + this.$location.host() + ':' + parser.port + parser.pathname; - - let promise: ng.IPromise = this.callSCM(diagnosticCallback, wsAgentHRef, false); - promise.then(() => { - let hint: string; - if (this.cheBranding.getName() === 'Eclipse Che') { - hint = 'CHE_DOCKER_IP_EXTERNAL property could be used or '; - } - diagnosticCallback.notifyHint(this.cheBranding.getCLI().name + '_HOST value in `' + this.cheBranding.getCLI().configName + '` file should use the hostname ' + this.$location.host() + ' instead of ' + parser.hostname); - }); - return diagnosticCallback.getPromise(); - } - - /** - * Check the Workspace Agent by calling REST API. - * @param {DiagnosticCallback} diagnosticCallback - * @param {boolean} errorInsteadOfFailure - * @returns {ng.IPromise} - */ - checkWsAgent(diagnosticCallback: DiagnosticCallback, errorInsteadOfFailure: boolean): ng.IPromise { - let wsAgentHRef = this.getWsAgentURL(diagnosticCallback); - let promise = this.callSCM(diagnosticCallback, wsAgentHRef, errorInsteadOfFailure); - promise.catch((error: any) => { - // try with browser host if different location - let parser = document.createElement('a'); - parser.href = wsAgentHRef; - - if (parser.hostname !== this.$location.host()) { - this.checkAgentWithBrowserHost(diagnosticCallback.newCallback('Try WsAgent on browser host')); - } - }); - - return diagnosticCallback.getPromise(); - } - - /** - * Start the diagnostic and report all progress through the callback - * @param {DiagnosticCallback} diagnosticCallback - * @returns {ng.IPromise} when test is finished - */ - checkWebSocketWsAgent(diagnosticCallback: DiagnosticCallback): ng.IPromise { - let machineToken: string = diagnosticCallback.getShared('machineToken'); - let clientId: string = diagnosticCallback.getShared('clientId'); - - let wsAgentSocketWebLink = this.getWsAgentWebsocket(diagnosticCallback); - if (machineToken) { - wsAgentSocketWebLink += '?token=' + machineToken; - } - - let callback = (message: any) => { - diagnosticCallback.success('Websocket Agent Message received'); - }; - - let cheJsonRpcWsagentApi: CheJsonRpcWsagentApi = this.cheJsonRpcApi.getJsonRpcWsagentApi(wsAgentSocketWebLink); - try { - cheJsonRpcWsagentApi.connect(wsAgentSocketWebLink, clientId).then(callback); - // default fallback if no answer in 5 seconds - diagnosticCallback.delayError('No reply of websocket test after 5 seconds. Websocket is failing to connect to ' + wsAgentSocketWebLink, 15000); - - } catch (error) { - diagnosticCallback.error('Unable to connect with websocket to ' + wsAgentSocketWebLink + ': ' + error); - } - return diagnosticCallback.getPromise(); - } - - /** - * Get data on API and retrieve SCM revision. - * @param {DiagnosticCallback} diagnosticCallback - * @param {string} wsAgentHRef - * @param {boolean} errorInsteadOfFailure - * @returns {Promise} - */ - callSCM(diagnosticCallback: DiagnosticCallback, wsAgentHRef: string, errorInsteadOfFailure: boolean): ng.IPromise { - let uriWsAgent: string = wsAgentHRef + '/'; - let machineToken: string = diagnosticCallback.getShared('machineToken'); - if (machineToken) { - uriWsAgent += '?token=' + machineToken; - } - - // connect to the workspace agent - let resourceAPI: any = this.$resource(uriWsAgent, {}, { - getDetails: {method: 'OPTIONS', timeout: 15000} - }, { - stripTrailingSlashes: false - }); - - return resourceAPI.getDetails().$promise.then((data: any) => { - diagnosticCallback.success(wsAgentHRef + '. Got SCM revision ' + angular.fromJson(data).scmRevision); - }).catch((error: any) => { - let errorMessage: string = 'Unable to perform call on ' + wsAgentHRef + ': Status ' + error.status + ', statusText:' + error.statusText + '/' + error.data; - if (errorInsteadOfFailure) { - if (this.cheBranding.getName() === 'Eclipse Che') { - diagnosticCallback.error(errorMessage, 'Workspace Agent is running but browser is unable to connect to it. Please check CHE_HOST and CHE_DOCKER_IP_EXTERNAL in che.env and the firewall settings.'); - } else { - diagnosticCallback.error(errorMessage, 'Workspace Agent is running but unable to connect. Please check HOST defined in the env file and the firewall settings.'); - } - } else { - diagnosticCallback.notifyFailure(errorMessage); - } - throw error; - }); - } - - /** - * Utility method used to get Workspace Agent URL from a callback shared data - * @param {DiagnosticCallback} diagnosticCallback - * @returns {string} - */ - getWsAgentURL(diagnosticCallback: DiagnosticCallback): string { - let workspace: che.IWorkspace = diagnosticCallback.getShared('workspace'); - - let errMessage: string = 'Workspace has no runtime: unable to test workspace not started'; - let runtime: any = workspace.runtime; - if (!runtime) { - diagnosticCallback.error(errMessage); - throw errMessage; - } - - const devMachine = Object.keys(runtime.machines).map((machineName: string) => { - return runtime.machines[machineName]; - }).find((machine: any) => { - return Object.keys(machine.servers).some((serverName: string) => { - return serverName === 'wsagent/http'; - }); - }); - - if (!devMachine) { - diagnosticCallback.error(errMessage); - throw errMessage; - } - - return devMachine.servers['wsagent/http'].url; - } - - /** - * Utility method used to get Workspace Agent websocket endpoint from a callback shared data - * @param {DiagnosticCallback} diagnosticCallback - * @returns {string} - */ - getWsAgentWebsocket(diagnosticCallback: DiagnosticCallback): string { - let workspace: che.IWorkspace = diagnosticCallback.getShared('workspace'); - - let errMessage: string = 'Workspace has no runtime: unable to test workspace not started'; - let runtime: any = workspace.runtime; - if (!runtime) { - diagnosticCallback.error(errMessage); - throw errMessage; - } - - const devMachine = Object.keys(runtime.machines).map((machineName: string) => { - return runtime.machines[machineName]; - }).find((machine: any) => { - return Object.keys(machine.servers).some((serverName: string) => { - return serverName === 'wsagent/ws'; - }); - }); - - if (!devMachine) { - diagnosticCallback.error(errMessage); - throw errMessage; - } - - return devMachine.servers['wsagent/ws'].url; - } - -} diff --git a/dashboard/src/app/diagnostics/test/diagnostics-workspace-start-check.factory.ts b/dashboard/src/app/diagnostics/test/diagnostics-workspace-start-check.factory.ts deleted file mode 100644 index 8fae076773d..00000000000 --- a/dashboard/src/app/diagnostics/test/diagnostics-workspace-start-check.factory.ts +++ /dev/null @@ -1,318 +0,0 @@ -/* - * Copyright (c) 2015-2018 Red Hat, Inc. - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Red Hat, Inc. - initial API and implementation - */ -'use strict'; -import {DiagnosticCallback} from '../diagnostic-callback'; -import {CheWorkspace} from '../../../components/api/workspace/che-workspace.factory'; -import {DiagnosticsRunningWorkspaceCheck} from './diagnostics-workspace-check-workspace.factory'; -import {CheBranding} from '../../../components/branding/che-branding.factory'; -import {CheJsonRpcApi} from '../../../components/api/json-rpc/che-json-rpc-api.factory'; -import {CheJsonRpcMasterApi} from '../../../components/api/json-rpc/che-json-rpc-master-api'; - -/** - * Test the start of a workspace - * @author Florent Benoit - */ -export class DiagnosticsWorkspaceStartCheck { - - static $inject = ['$q', 'lodash', 'cheWorkspace', 'diagnosticsRunningWorkspaceCheck', 'cheBranding', '$location', 'cheJsonRpcApi', 'userDashboardConfig', 'keycloakAuth', 'proxySettings']; - - /** - * Q service for creating delayed promises. - */ - private $q: ng.IQService; - - /** - * Workspace API used to grab details. - */ - private cheWorkspace; - - /** - * Lodash utility. - */ - private lodash: any; - - /** - * Other checker used to spawn new tests. - */ - private diagnosticsRunningWorkspaceCheck: DiagnosticsRunningWorkspaceCheck; - - /** - * Keep a reference to the workspace Agent callback - */ - private wsAgentCallback: DiagnosticCallback; - - /** - * Keep a reference to the workspace callback - */ - private workspaceCallback: DiagnosticCallback; - - /** - * Keep a reference to the machine callback - */ - private machineCallback: DiagnosticCallback; - - /** - * Keep a reference to the exec agent callback - */ - private execAgentCallback: DiagnosticCallback; - - /** - * Branding info. - */ - private cheBranding: CheBranding; - - /** - * Location service. - */ - private $location: ng.ILocationService; - - /** - * RPC API location string. - */ - private jsonRpcApiLocation: string; - - /** - * Workspace master interceptions. - */ - private cheJsonRpcMasterApi: CheJsonRpcMasterApi; - - /** - * Default constructor - */ - constructor($q: ng.IQService, - lodash: any, - cheWorkspace: CheWorkspace, - diagnosticsRunningWorkspaceCheck: DiagnosticsRunningWorkspaceCheck, - cheBranding: CheBranding, - $location: ng.ILocationService, - cheJsonRpcApi: CheJsonRpcApi, - userDashboardConfig: any, - keycloakAuth: any, - proxySettings: string) { - this.$q = $q; - this.lodash = lodash; - this.cheWorkspace = cheWorkspace; - this.cheBranding = cheBranding; - this.$location = $location; - this.diagnosticsRunningWorkspaceCheck = diagnosticsRunningWorkspaceCheck; - - const keycloakToken = keycloakAuth.isPresent ? '?token=' + keycloakAuth.keycloak.token : ''; - this.jsonRpcApiLocation = this.cheWorkspace.formJsonRpcApiLocation($location, proxySettings, userDashboardConfig.developmentMode) + cheBranding.getWebsocketContext(); - this.jsonRpcApiLocation += keycloakToken; - this.cheJsonRpcMasterApi = cheJsonRpcApi.getJsonRpcMasterApi(this.jsonRpcApiLocation); - } - - /** - * Delete the diagnostic workspace (by stopping it first) if it's already running - * @param {DiagnosticCallback} diagnosticCallback the callback used to send response - * @returns {ng.IPromise} - */ - deleteDiagnosticWorkspaceIfPresent(diagnosticCallback: DiagnosticCallback): ng.IPromise { - let defered = this.$q.defer(); - this.cheWorkspace.fetchWorkspaces().finally(() => { - let workspaces: Array = this.cheWorkspace.getWorkspaces(); - let workspace: any = this.lodash.find(workspaces, (workspace: che.IWorkspace) => { - return workspace.config.name === 'diagnostics'; - }); - // need to delete it - if (workspace) { - // first stop - if (workspace.status === 'RUNNING' || workspace.status === 'STARTING') { - // listen on the events - const callback = (message: any) => { - if (message.status === 'STOPPED') { - this.cheWorkspace.deleteWorkspaceConfig(workspace.id).finally(() => { - defered.resolve(true); - }); - } else if ('ERROR' === message.status) { - defered.reject(message.content); - } - }; - this.cheJsonRpcMasterApi.subscribeWorkspaceStatus(workspace.id, callback); - defered.promise.then((wsIsStopped: boolean) => { - if (wsIsStopped) { - this.cheJsonRpcMasterApi.unSubscribeWorkspaceStatus(workspace.id, callback); - } - }); - this.cheWorkspace.stopWorkspace(workspace.id); - } else { - this.cheWorkspace.deleteWorkspaceConfig(workspace.id).finally(() => { - defered.resolve(true); - }); - } - } else { - defered.resolve(true); - } - }).catch((error: any) => { - defered.reject(error); - }); - return defered.promise; - } - - /** - * Always create a fresh workspace (by removing the old one if it exists) - * @param {DiagnosticCallback} diagnosticCallback - * @returns {ng.IPromise} - */ - recreateDiagnosticWorkspace(diagnosticCallback: DiagnosticCallback): ng.IPromise { - let defered = this.$q.defer(); - - // delete if present - this.deleteDiagnosticWorkspaceIfPresent(diagnosticCallback).then(() => { - // now create workspace config - let workspaceConfig: che.IWorkspaceConfig = { - 'projects': [], - 'environments': { - 'diagnostics': { - 'machines': { - 'dev-machine': { - 'servers': {}, - 'attributes': {'memoryLimitBytes': '1147483648'} - } - }, - 'recipe': { - 'content': 'eclipse/ubuntu_jdk8', - 'type': 'dockerimage' - } - } - }, - 'name': 'diagnostics', - 'defaultEnv': 'diagnostics', - 'commands': [] - }; - return this.cheWorkspace.createWorkspaceFromConfig(null, workspaceConfig); - }).then((workspace: che.IWorkspace) => { - defered.resolve(workspace); - }).catch((error: any) => { - defered.reject(error); - } - ); - return defered.promise; - } - - /** - * Starts the test by adding new callbacks after this one - * @param {DiagnosticCallback} diagnosticCallback the original check - * @returns {ng.IPromise} - */ - start(diagnosticCallback: DiagnosticCallback): ng.IPromise { - this.workspaceCallback = diagnosticCallback.newCallback('Workspace State'); - this.wsAgentCallback = diagnosticCallback.newCallback('Workspace Agent State'); - this.machineCallback = diagnosticCallback.newCallback('Workspace Runtime State'); - this.execAgentCallback = diagnosticCallback.newCallback('Workspace Exec Agent State'); - - let workspaceIsStarted: boolean = false; - this.recreateDiagnosticWorkspace(diagnosticCallback).then((workspace: che.IWorkspace) => { - - diagnosticCallback.shared('workspace', workspace); - this.cheJsonRpcMasterApi.subscribeWorkspaceStatus(workspace.id, (message: any) => { - diagnosticCallback.addContent('EventChannel : ' + JSON.stringify(message)); - if (message.status === 'RUNNING') { - workspaceIsStarted = true; - this.workspaceCallback.stateRunning('RUNNING'); - this.cheWorkspace.fetchWorkspaces().then(() => { - let workspace = diagnosticCallback.getShared('workspace'); - let workspaceId = workspace.id; - this.cheWorkspace.fetchWorkspaceDetails(workspace.id).then(() => { - let workspace = this.cheWorkspace.getWorkspaceById(workspaceId); - diagnosticCallback.shared('workspace', workspace); - diagnosticCallback.shared('machineToken', workspace.runtime.machineToken); - diagnosticCallback.shared('clientId', this.cheJsonRpcMasterApi.getClientId()); - diagnosticCallback.success('Starting workspace OK'); - }); - }); - } - }); - - this.cheJsonRpcMasterApi.subscribeEnvironmentStatus(workspace.id, (message: any) => { - if (message.eventType === 'DESTROYED' && message.identity.workspaceId === workspace.id) { - diagnosticCallback.error('Error while starting the workspace : Workspace has been destroyed', 'Please check the diagnostic logs.'); - } - if (message.eventType === 'ERROR' && message.identity.workspaceId === workspace.id) { - diagnosticCallback.error('Error while starting the workspace : ' + JSON.stringify(message)); - } - - if (message.eventType === 'RUNNING' && message.identity.workspaceId === workspace.id && message.machineName === 'dev-machine') { - this.machineCallback.stateRunning('RUNNING'); - } - - diagnosticCallback.addContent('StatusChannel : ' + JSON.stringify(message)); - - }); - - this.cheJsonRpcMasterApi.subscribeWsAgentOutput(workspace.id, (message: any) => { - diagnosticCallback.addContent('agent channel :' + message); - - if (message.text.indexOf(' Server startup') > 0) { - this.wsAgentCallback.stateRunning('RUNNING'); - - // server has been startup in the workspace agent and tries to reach workspace agent but is unable to do it - // try with the browser ip - diagnosticCallback.delayFunction(() => { - - let hint: string = 'The workspace agent has started in the workspace, but the ' + this.cheBranding.getName() + ' server cannot verify this. There is a failure for ' + this.cheBranding.getName() + ' server to connect to your workspace\'s agent. Either your firewall is blocking essential ports or you can change '; - if (this.cheBranding.getName() === 'Eclipse Che') { - hint += 'CHE_DOCKER_IP and DOCKER_HOST to values '; - } - hint += 'specific to your environment. See the `' + this.cheBranding.getCLI().configName + '` file for specifics.'; - diagnosticCallback.notifyFailure('The workspace started, but ' + this.cheBranding.getName() + ' <--> Workspace connection not established', hint); - let workspaceId = workspace.id; - this.cheWorkspace.fetchWorkspaceDetails(workspace.id).then(() => { - let workspace = this.cheWorkspace.getWorkspaceById(workspaceId); - diagnosticCallback.shared('workspace', workspace); - diagnosticCallback.shared('machineToken', workspace.runtime.machineToken); - let newCallback: DiagnosticCallback = diagnosticCallback.newCallback('Test connection from browser to workspace agent by using Workspace Agent IP'); - this.diagnosticsRunningWorkspaceCheck.checkWsAgent(newCallback, false); - let websocketCallback: DiagnosticCallback = diagnosticCallback.newCallback('Test connection from browser to workspace agent with websocket'); - this.diagnosticsRunningWorkspaceCheck.checkWebSocketWsAgent(websocketCallback); - }); - - }, 7000); - } - - diagnosticCallback.addContent(message); - }); - - this.cheJsonRpcMasterApi.subscribeWsAgentOutput(workspace.id, (message: any) => { - const content = message.text; - diagnosticCallback.addContent(content); - - // check if connected (always pull) - if (content.indexOf('Client.Timeout exceeded while awaiting headers') > 0) { - diagnosticCallback.error('Network connection issue', 'Docker was unable to pull the right Docker image for the workspace. Either networking is not working from your Docker daemon or try disabling CHE_DOCKER_ALWAYSE__PULL__IMAGE in `che.env` to avoid pulling images over the network.'); - } - - if (content.indexOf('dial tcp: lookup') > 0 && content.indexOf('server misbehaving') > 0) { - diagnosticCallback.error('Network connection issue', 'Docker is trying to connect to a Docker registry but the connection is failing. Check Docker\'s DNS settings and network connectivity.'); - } - - if (content.indexOf('Exec-agent configuration') > 0) { - this.execAgentCallback.stateRunning('RUNNING'); - } - diagnosticCallback.addContent('output channel message :' + JSON.stringify(message)); - }); - - diagnosticCallback.delayError('Test limit is for up to 5minutes. Time has exceed.', 5 * 60 * 1000); - - let startWorkspacePromise = this.cheWorkspace.startWorkspace(workspace.id, workspace.config.defaultEnv); - startWorkspacePromise.then((workspaceData: che.IWorkspace) => { - diagnosticCallback.shared('workspace', workspaceData); - }); - - }).catch((error: any) => { - diagnosticCallback.error('Unable to start workspace: ' + error); - }); - - return diagnosticCallback.getPromise(); - } - -} diff --git a/dashboard/src/app/index.module.ts b/dashboard/src/app/index.module.ts index ab4d4101e60..bb080b8e157 100755 --- a/dashboard/src/app/index.module.ts +++ b/dashboard/src/app/index.module.ts @@ -16,7 +16,6 @@ import {FactoryConfig} from './factories/factories-config'; import {ComponentsConfig} from '../components/components-config'; import {AdminsConfig} from './admin/admin-config'; import {AdministrationConfig} from './administration/administration-config'; -import {DiagnosticsConfig} from './diagnostics/diagnostics-config'; import {CheColorsConfig} from './colors/che-color.constant'; import {CheOutputColorsConfig} from './colors/che-output-colors.constant'; import {CheCountriesConfig} from './constants/che-countries.constant'; @@ -477,7 +476,6 @@ new ComponentsConfig(instanceRegister); new AdminsConfig(instanceRegister); new AdministrationConfig(instanceRegister); new IdeConfig(instanceRegister); -new DiagnosticsConfig(instanceRegister); new NavbarConfig(instanceRegister); new WorkspacesConfig(instanceRegister); diff --git a/dashboard/src/components/widget/footer/che-footer.html b/dashboard/src/components/widget/footer/che-footer.html index 32f75a6dcba..c5fabca78c5 100644 --- a/dashboard/src/components/widget/footer/che-footer.html +++ b/dashboard/src/components/widget/footer/che-footer.html @@ -24,8 +24,6 @@ {{cheFooterController.supportHelpTitle}} - Diagnostics - {{link.title}}