Skip to content

Commit 356e7c8

Browse files
committed
2 parents 3e7cab2 + 9387668 commit 356e7c8

File tree

8 files changed

+193
-35
lines changed

8 files changed

+193
-35
lines changed

__tests__/__src__/environment/TestEnvironment.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ export class TestEnvironment {
147147
private static async installPlugin(testEnvironment: ITestEnvironment) {
148148
let installScript: string = TemporaryScripts.SHEBANG;
149149
installScript += TemporaryScripts.ZOWE_BIN + " plugins install ../../../../\n"; // install plugin from root of project
150-
installScript += TemporaryScripts.ZOWE_BIN + " plugins validate @brightside/zowe-cli-cics-deploy-plugin\n";
150+
installScript += TemporaryScripts.ZOWE_BIN + " plugins validate zowe-cli-cics-deploy-plugin\n";
151151
installScript += TemporaryScripts.ZOWE_BIN + " cdep --help\n"; // check that the plugin help is available
152152
const scriptPath = testEnvironment.workingDir + "/install_plugin.sh";
153153
IO.writeFile(scriptPath, Buffer.from(installScript));
@@ -156,7 +156,7 @@ export class TestEnvironment {
156156

157157
if (output.status !== 0) {
158158
throw new ImperativeError({
159-
msg: "Install of '@brightside/zowe-cli-cics-deploy-plugin' plugin failed! You should delete the script: \n'" + scriptPath + "' " +
159+
msg: "Install of 'zowe-cli-cics-deploy-plugin' plugin failed! You should delete the script: \n'" + scriptPath + "' " +
160160
"after reviewing it to check for possible errors.\n Output of the plugin install command:\n" + output.stderr.toString() +
161161
output.stdout.toString()
162162
});

__tests__/api/BundlePush/BundlePusher.test.ts

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,12 @@ const DEFAULT_PARAMTERS: IHandlerParameters = {
2424
},
2525
profiles: {
2626
get: (type: string) => {
27+
if (type === "zosmf") {
28+
return zosmfProfile;
29+
}
30+
if (type === "ssh") {
31+
return sshProfile;
32+
}
2733
return {};
2834
}
2935
} as any,
@@ -60,6 +66,8 @@ const IS_NOT_DIRECTORY: any = {
6066
isDirectory: jest.fn((directory) => (false))
6167
};
6268
let consoleText = "";
69+
let zosmfProfile = {};
70+
let sshProfile = {};
6371

6472
// Initialise xml2json before mocking anything
6573
const parser = require("xml2json");
@@ -99,6 +107,8 @@ describe("BundlePusher01", () => {
99107
readdirSpy = jest.spyOn(fs, "readdirSync").mockImplementation(() => ([]));
100108
lstatSpy = jest.spyOn(fs, "lstatSync").mockImplementation(() => ( IS_NOT_DIRECTORY ));
101109
consoleText = "";
110+
zosmfProfile = {};
111+
sshProfile = {};
102112
});
103113
afterEach(() => {
104114
jest.restoreAllMocks();
@@ -191,6 +201,38 @@ describe("BundlePusher01", () => {
191201
expect(zosMFSpy).toHaveBeenCalledTimes(1);
192202
expect(sshSpy).toHaveBeenCalledTimes(1);
193203
});
204+
it("should complain with mismatching zOSMF and SSH profile host names", async () => {
205+
zosmfProfile = { host: "wibble" };
206+
sshProfile = { host: "wobble" };
207+
208+
await runPushTest("__tests__/__resources__/ExampleBundle01", true,
209+
"PUSH operation completed.");
210+
expect(consoleText).toContain("WARNING: ssh profile --host value 'wobble' does not match zosmf value 'wibble'.");
211+
});
212+
it("should not complain with matching zOSMF and SSH profile host names", async () => {
213+
zosmfProfile = { host: "wibble" };
214+
sshProfile = { host: "wibble" };
215+
216+
await runPushTest("__tests__/__resources__/ExampleBundle01", true,
217+
"PUSH operation completed.");
218+
expect(consoleText).not.toContain("WARNING: ssh profile");
219+
});
220+
it("should complain with mismatching zOSMF and SSH profile user names", async () => {
221+
zosmfProfile = { host: "wibble", user: "fred" };
222+
sshProfile = { host: "wibble", user: "joe" };
223+
224+
await runPushTest("__tests__/__resources__/ExampleBundle01", true,
225+
"PUSH operation completed.");
226+
expect(consoleText).toContain("WARNING: ssh profile --user value 'joe' does not match zosmf value 'fred'.");
227+
});
228+
it("should not complain with matching zOSMF and SSH profile user names", async () => {
229+
zosmfProfile = { host: "wibble", user: "fred" };
230+
sshProfile = { host: "wibble", user: "fred" };
231+
232+
await runPushTest("__tests__/__resources__/ExampleBundle01", true,
233+
"PUSH operation completed.");
234+
expect(consoleText).not.toContain("WARNING: ssh profile");
235+
});
194236
it("should complain if remote bundle dir mkdir fails", async () => {
195237
createSpy.mockImplementationOnce(() => { throw new Error( "Injected Create error" ); });
196238
await runPushTestWithError("__tests__/__resources__/ExampleBundle01", false,

docs/_data/sidebars/cdp_sidebar.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,9 @@ entries:
5353
- title: Log and trace files
5454
url: /cdp-Troubleshooting-General.html
5555
output: web
56+
- title: Potential problems
57+
url: /cdp-Troubleshooting-Symptoms.html
58+
output: web
5659

5760
- title: Commands - zowe profiles
5861
output: web

docs/js/customscripts.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ $(document).ready(function () {
2626
* Modified to use a fontawesome icon.
2727
*/
2828
// get all <pre> elements
29-
var allCodeBlocksElements = $("pre");
29+
var allCodeBlocksElements = $("pre:not(.messageText)");
3030

3131
allCodeBlocksElements.each(function (i) {
3232
// add different id for each code block

docs/pages/cdp/cdp-Troubleshooting-General.md

Lines changed: 48 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,54 @@ permalink: cdp-Troubleshooting-General.html
88
folder: cdp
99
---
1010

11+
### Console output
12+
All Zowe CLI cics deploy plugin commands send output to the console when invoked. Very often, enough information is provided for you to diagnose and pinpoint the cause of a problem. The commands `cics-deploy push`, `cics-deploy deploy` and `cics-deploy undeploy` accept a `--verbose` command-line option which can generate extra information if needed.
13+
1114
### zowe.log
12-
The .zowe directory contains log files, profiles, and plug-ins. The location of this directory can be customised as described in [ Setting the Zowe CLI home directory](https://zowe.github.io/docs-site/latest/user-guide/cli-configuringcli.html#setting-the-zowe-cli-home-directory) and logging level set as described in [Setting Zowe CLI log levels](https://zowe.github.io/docs-site/latest/user-guide/cli-configuringcli.html#setting-zowe-cli-log-levels).
15+
The .zowe directory on your local workstation contains log files, profiles, and plug-ins. The location of this directory can be customised as described in [ Setting the Zowe CLI home directory](https://zowe.github.io/docs-site/latest/user-guide/cli-configuringcli.html#setting-the-zowe-cli-home-directory) and logging level set as described in [Setting Zowe CLI log levels](https://zowe.github.io/docs-site/latest/user-guide/cli-configuringcli.html#setting-zowe-cli-log-levels).
1316

1417
You can use the following command to display messages written to the log file as they occur. This can be useful when troubleshooting problems when using `zowe` and `zowe cics-plugin` commands in another terminal.
15-
```console
16-
tail -f -n 0 ~/.zowe/zowe/logs/zowe.log
17-
```
18+
<ul id="profileTabs" class="nav nav-tabs">
19+
<li class="active"><a href="#windows" data-toggle="tab">Windows</a></li>
20+
<li><a href="#linux" data-toggle="tab">Linux</a></li>
21+
<li><a href="#macos" data-toggle="tab">macOS</a></li>
22+
</ul>
23+
<div class="tab-content">
24+
<div role="tabpanel" class="tab-pane active" id="windows">
25+
<p>On Windows, use the Powershell command
26+
<br/><br/>
27+
<tt>Get-Content $env:USERPROFILE\.zowe\zowe\logs\zowe.log -Tail 30 -wait</tt></p>
28+
</div>
29+
30+
<div role="tabpanel" class="tab-pane" id="linux">
31+
<p>On Linux, use <tt>tail -f -n 0 ~/.zowe/zowe/logs/zowe.log</tt></p></div>
32+
33+
<div role="tabpanel" class="tab-pane" id="macos">
34+
<p>On macOS, use <tt>tail -f -n 0 ~/.zowe/zowe/logs/zowe.log</tt></p>
35+
</div>
36+
</div>
37+
38+
### Node.js logs
39+
By default, CICS writes Node.js log files on z/OS to the `/tmp` directory. However, the `generate bundle` command creates a number of files including `nodejsapps/<my app name>.profile` (often referred to as the Node.js profile), which you can edit to specify a more convenient log file location. Such logs get written to the directory referenced by the environment variable `WORK_DIR`. For example, you might edit your Node.js profile so that it includes the line:
40+
41+
```
42+
WORK_DIR=/u/<your user id>/nodelogs
43+
```
44+
This causes CICS to write all Node.js logs to the specified directory.
45+
46+
Files typically written to `WORK_DIR` include:
47+
48+
* LOG
49+
* STDERR
50+
* STDOUT
51+
* TRACE
52+
53+
They can all be useful when identifying the cause of an error, especially STDERR.
54+
55+
{% include note.html content="If you use [Visual Studio Code](https://code.visualstudio.com/) as your editor, there is a [zowe extension](https://github.com/zowe/vscode-extension-for-zowe) that enables you to interact with USS files from your local workstation." %}
56+
57+
### JES job logs
58+
DFHDPLOY is a CICS utility which provides a set of commands that you can use to deploy, undeploy and set the state of CICS bundles. When you deploy or undeploy a Node.js application to or from CICS, a batch DFHDPLOY job is initiated on z/OS.
59+
60+
If you are familiar with the z/OS environment, you can often find some useful diagnostics by accessing z/OS file assigned to the MSGUSR DD name for the deploy/undeploy job associated with your CICS region. If you are not so fluent with the world of z/OS, you may need to discuss your needs with one of your organization's CICS Systems Programmers.
61+
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
---
2+
title: Possible problems and their resolution
3+
tags: [troubleshooting]
4+
keywords:
5+
summary: "This section describes sets of problem symptoms, their possible causes and suggested solutions."
6+
sidebar: cdp_sidebar
7+
permalink: cdp-Troubleshooting-Symptoms.html
8+
folder: cdp
9+
---
10+
11+
{% include important.html content="To definitively diagnose a problem based on the suggested symptoms, you will need to refer to one or more [system logs and traces](cdp-Troubleshooting-General) particularly the STDERR Node.js log and the file assigned the MSGUSR DD name in the relevant CICS DFHDPLOY job. Depending on your familiarity with z/OS and CICS, and your system privileges, you may need to consult a CICS Systems Programmer to get to the bottom of certain problems." %}
12+
13+
## Deployment errors
14+
15+
### Application incorrectly deploys in a DISABLED state
16+
*Possible cause*: The port requested by the application is already in use.
17+
18+
*Suggested action*: Choose a new port number after double-checking that it is not in use. Redeploy the application using the new value for the port.
19+
20+
{% include note.html content="An application in a `DISABLED` state does not necessarily indicate an error condition. The `cics-deploy deploy`, `cics-deploy push` and `cics-deploy undeploy` commands allow you to specify a `--target-state` option which you may deliberately choose to set to `DISABLED`." %}
21+
22+
### Command error: DFHDPLOY stopped processing due to an error
23+
*Possible causes*:
24+
* The `--scope` and/or `--cicsplex` settings for the current deploy profile are wrong, and don't correctly identify a current CICS system, CICS System Group and/or a correct CICSPlex respectively.
25+
26+
* The CMAS for the current CICSPlex is inactive.
27+
28+
* CPSM is not functioning correctly.
29+
30+
*Representative output*:
31+
<pre class="messageText">
32+
16:22:50.058844 :  DFHDPLOY CICS TS APPLICATION DEPLOYMENT  2019/04/10 4:22pm
33+
16:22:50.059562 :  RELEASE: HCI7300.   SERVICE LEVEL: HCI7300.
34+
16:22:50.060903 :  *
35+
16:22:50.060910 :  SET CICSPLEX(CAPLE);
36+
16:22:50.062721 :  DFHRL2057S DFHDPLOY is unable to connect to CICSPLEX(CAPLE).
37+
16:22:50.065729 :  DFHRL2055I Errors have occurred, processing terminated.
38+
</pre>
39+
40+
*Suggested actions*:
41+
* Confirm that the `--scope` and `--cicsplex` settings are correct.
42+
43+
* Ask your CICS Systems Programmer to check that the CMAS for the current CICSPlex is alive and that CPSM is working properly.
44+
45+
46+
47+
## General errors
48+
49+
TBC
50+
51+

package.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@
3434
"xml2json": "^0.11.2"
3535
},
3636
"devDependencies": {
37-
"@zowe/cli": "^5.3.0-alpha.201904291733",
38-
"@zowe/imperative": "^4.1.2-alpha.201905061426",
37+
"@zowe/cli": "^5.5.0",
38+
"@zowe/imperative": "^4.1.2",
3939
"@types/fs-extra": "^5.0.5",
4040
"@types/jest": "^22.2.3",
4141
"@types/node": "^8.0.28",
@@ -66,8 +66,8 @@
6666
"uuid": "^3.3.2"
6767
},
6868
"peerDependencies": {
69-
"@zowe/cli": "^3.2.0",
70-
"@zowe/imperative": "^3.0.0"
69+
"@zowe/cli": "^5.5.0",
70+
"@zowe/imperative": "^4.1.2"
7171
},
7272
"jest": {
7373
"modulePathIgnorePatterns": [

src/api/BundlePush/BundlePusher.ts

Lines changed: 42 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
"use strict";
1313

14-
import { IHandlerParameters, AbstractSession, ITaskWithStatus, TaskStage, TaskProgress, Logger } from "@zowe/imperative";
14+
import { IHandlerParameters, AbstractSession, ITaskWithStatus, TaskStage, TaskProgress, Logger, IProfile } from "@zowe/imperative";
1515
import { List, ZosmfSession, SshSession, Shell, Upload, IUploadOptions, ZosFilesAttributes, Create } from "@zowe/cli";
1616
import { BundleDeployer } from "../BundleDeploy/BundleDeployer";
1717
import { Bundle } from "../BundleContent/Bundle";
@@ -69,10 +69,15 @@ export class BundlePusher {
6969
"_" + bundle.getVersion();
7070
}
7171

72+
// Get the profiles
73+
const zosMFProfile = this.getProfile("zosmf");
74+
const sshProfile = this.getProfile("ssh");
75+
this.validateProfiles(zosMFProfile, sshProfile);
76+
7277
// Create a zOSMF session
73-
const zosMFSession = await this.createZosMFSession();
78+
const zosMFSession = await this.createZosMFSession(zosMFProfile);
7479
// Create an SSH session
75-
const sshSession = await this.createSshSession();
80+
const sshSession = await this.createSshSession(sshProfile);
7681

7782
// Start a progress bar (but only in non-verbose mode)
7883
this.progressBar = { percentComplete: 0,
@@ -176,23 +181,43 @@ export class BundlePusher {
176181
}
177182
}
178183

179-
private async createZosMFSession(): Promise<AbstractSession> {
180-
// Create a zosMF session
181-
const zosmfProfile = this.params.profiles.get("zosmf");
184+
private getProfile(type: string): IProfile {
185+
const profile = this.params.profiles.get(type);
182186

183-
if (zosmfProfile === undefined) {
184-
throw new Error("No zosmf profile found");
187+
if (profile === undefined) {
188+
throw new Error("No " + type + " profile found");
185189
}
186-
return ZosmfSession.createBasicZosmfSession(zosmfProfile);
190+
191+
return profile;
187192
}
188193

189-
private async createSshSession(): Promise<SshSession> {
190-
// Create an SSH session
191-
const sshProfile = this.params.profiles.get("ssh");
194+
private issueWarning(msg: string) {
195+
const warningMsg = "WARNING: " + msg + "\n";
196+
this.endProgressBar();
197+
this.params.response.console.log(Buffer.from(warningMsg));
198+
if (this.params.arguments.silent === undefined) {
199+
const logger = Logger.getAppLogger();
200+
logger.warn(warningMsg);
201+
}
202+
this.startProgressBar();
203+
}
192204

193-
if (sshProfile === undefined) {
194-
throw new Error("No ssh profile found");
205+
private validateProfiles(zosmfProfile: IProfile, sshProfile: IProfile) {
206+
// Do they share the same host name?
207+
if (zosmfProfile.host !== sshProfile.host) {
208+
this.issueWarning("ssh profile --host value '" + sshProfile.host + "' does not match zosmf value '" + zosmfProfile.host + "'.");
209+
}
210+
// Do they share the same user name?
211+
if (zosmfProfile.user !== sshProfile.user) {
212+
this.issueWarning("ssh profile --user value '" + sshProfile.user + "' does not match zosmf value '" + zosmfProfile.user + "'.");
195213
}
214+
}
215+
216+
private async createZosMFSession(zosmfProfile: IProfile): Promise<AbstractSession> {
217+
return ZosmfSession.createBasicZosmfSession(zosmfProfile);
218+
}
219+
220+
private async createSshSession(sshProfile: IProfile): Promise<SshSession> {
196221
return SshSession.createBasicSshSession(sshProfile);
197222
}
198223

@@ -433,14 +458,7 @@ export class BundlePusher {
433458
}
434459

435460
// A project specific .zosattributes has not been found, so use a default
436-
const warningMsg = "WARNING: No .zosAttributes file found in the bundle directory, default values will be applied.";
437-
this.endProgressBar();
438-
this.params.response.console.log(Buffer.from(warningMsg));
439-
if (this.params.arguments.silent === undefined) {
440-
const logger = Logger.getAppLogger();
441-
logger.warn(warningMsg);
442-
}
443-
this.startProgressBar();
461+
this.issueWarning("No .zosAttributes file found in the bundle directory, default values will be applied.");
444462
return new ZosFilesAttributes(Bundle.getTemplateZosAttributesFile());
445463
}
446464

@@ -468,13 +486,13 @@ export class BundlePusher {
468486
}
469487

470488
private startProgressBar() {
471-
if (this.params.arguments.verbose !== true) {
489+
if (this.params.arguments.verbose !== true && this.progressBar !== undefined) {
472490
this.params.response.progress.startBar({task: this.progressBar});
473491
}
474492
}
475493

476494
private endProgressBar() {
477-
if (this.params.arguments.verbose !== true) {
495+
if (this.params.arguments.verbose !== true && this.progressBar !== undefined) {
478496
this.params.response.progress.endBar();
479497
}
480498
}

0 commit comments

Comments
 (0)