diff --git a/doc/apis.md b/doc/apis.md
index a790938..35efcf6 100644
--- a/doc/apis.md
+++ b/doc/apis.md
@@ -75,7 +75,7 @@
| _List spool files_ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| _Read spool file_ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| _Get job JCL_ | ✅ | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ |
-| _Submit job_ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ |
+| _Submit job_ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| _Delete job_ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| Cancel job | ✅ | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ 1 |
| Hold job | ✅ | ❌ | ✅ | ✅ | ✅ | ✅ | ➖ 2 |
diff --git a/native/CHANGELOG.md b/native/CHANGELOG.md
index 5ebc0e6..2ede9fc 100644
--- a/native/CHANGELOG.md
+++ b/native/CHANGELOG.md
@@ -27,6 +27,7 @@ Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how
- `c`: Added check for maximum data set pattern length before making a list request. Now, requests with patterns longer than 44 characters are rejected. [#185](https://github.com/zowe/zowe-native-proto/pull/185)
- `c,golang`: Fixed issue where submit JCL handler did not convert input data from UTF-8 and did not support an `--encoding` option. [#198](https://github.com/zowe/zowe-native-proto/pull/198)
- `c`: Fixed issue where submit JCL handler did not support raw bytes from stdin when the binary is directly invoked through a shell. [#198](https://github.com/zowe/zowe-native-proto/pull/198)
+- `c,golang`: Added `submitUss` function. [#184](https://github.com/zowe/zowe-native-proto/pull/184)
## [Unreleased]
diff --git a/native/c/zowex.cpp b/native/c/zowex.cpp
index 54a7b2a..4880d39 100644
--- a/native/c/zowex.cpp
+++ b/native/c/zowex.cpp
@@ -42,6 +42,7 @@ int handle_job_view_file(ZCLIResult);
int handle_job_view_jcl(ZCLIResult);
int handle_job_submit(ZCLIResult);
int handle_job_submit_jcl(ZCLIResult);
+int handle_job_submit_uss(ZCLIResult);
int handle_job_delete(ZCLIResult);
int handle_job_cancel(ZCLIResult);
int handle_job_hold(ZCLIResult);
@@ -312,6 +313,18 @@ int main(int argc, char *argv[])
job_submit_jcl.get_options().push_back(encoding_option);
job_group.get_verbs().push_back(job_submit_jcl);
+ ZCLIVerb job_submit_uss("submit-uss");
+ job_submit_uss.get_aliases().push_back("sub-u");
+ job_submit_uss.set_description("submit a job from USS files");
+ job_submit_uss.set_zcli_verb_handler(handle_job_submit_uss);
+ ZCLIPositional job_uss_file("file-path");
+ job_uss_file.set_required(true);
+ job_uss_file.set_description("USS file containing JCL");
+ job_submit_uss.get_positionals().push_back(job_uss_file);
+
+ job_submit_uss.get_options().push_back(job_jobid_only);
+ job_group.get_verbs().push_back(job_submit_uss);
+
ZCLIVerb job_delete("delete");
job_delete.get_aliases().push_back("del");
job_delete.set_description("delete a job");
@@ -790,6 +803,44 @@ int handle_job_submit(ZCLIResult result)
return RTNCD_SUCCESS;
}
+int handle_job_submit_uss(ZCLIResult result)
+{
+ int rc = 0;
+ ZJB zjb = {0};
+ string file(result.get_positional("file-path")->get_value());
+
+ ZUSF zusf = {0};
+ string response;
+ rc = zusf_read_from_uss_file(&zusf, file, response);
+ if (0 != rc)
+ {
+ cerr << "Error: could not view USS file: '" << file << "' rc: '" << rc << "'" << endl;
+ cerr << " Details:\n"
+ << zusf.diag.e_msg << endl
+ << response << endl;
+ return RTNCD_FAILURE;
+ }
+
+ vector jobs;
+ string jobid;
+ rc = zjb_submit(&zjb, response, jobid);
+
+ if (0 != rc)
+ {
+ cerr << "Error: could not submit JCL: '" << file << "' rc: '" << rc << "'" << endl;
+ cerr << " Details: " << zjb.diag.e_msg << endl;
+ return RTNCD_FAILURE;
+ }
+
+ string only_jobid(result.get_option("--only-jobid")->get_value());
+ if ("true" == only_jobid)
+ cout << jobid << endl;
+ else
+ cout << "Submitted " << file << ", " << jobid << endl;
+
+ return RTNCD_SUCCESS;
+}
+
int handle_job_submit_jcl(ZCLIResult result)
{
int rc = 0;
diff --git a/native/golang/cmds/definitions.go b/native/golang/cmds/definitions.go
index a6718bc..fbbe60e 100644
--- a/native/golang/cmds/definitions.go
+++ b/native/golang/cmds/definitions.go
@@ -51,6 +51,7 @@ func initializeJobHandlers(disp *CmdDispatcher) {
"readSpool": HandleReadSpoolRequest,
"submitJob": HandleSubmitJobRequest,
"submitJcl": HandleSubmitJclRequest,
+ "submitUss": HandleSubmitUssRequest,
"cancelJob": HandleCancelJobRequest,
"deleteJob": HandleDeleteJobRequest,
"holdJob": HandleHoldJobRequest,
diff --git a/native/golang/cmds/jobs.go b/native/golang/cmds/jobs.go
index 58113a1..1748884 100644
--- a/native/golang/cmds/jobs.go
+++ b/native/golang/cmds/jobs.go
@@ -262,7 +262,29 @@ func HandleSubmitJobRequest(conn *utils.StdioConn, params []byte) (result any, e
result = jobs.SubmitJobResponse{
Success: true,
Dsname: request.Dsname,
- JobId: strings.TrimSpace(string(out)),
+ JobId: string(out),
+ }
+ return
+}
+
+// HandleSubmitUssRequest handles a SubmitUssRequest by invoking the `zowex job submit-uss` command
+func HandleSubmitUssRequest(conn *utils.StdioConn, params []byte) (result any, e error) {
+ request, err := utils.ParseCommandRequest[jobs.SubmitUssRequest](params)
+ if err != nil {
+ return nil, err
+ }
+
+ out, err := conn.ExecCmd([]string{"job", "submit-uss", request.Path, "--only-jobid", "true"})
+
+ if err != nil {
+ e = fmt.Errorf("Failed to submit job: %v", err)
+ return
+ }
+
+ result = jobs.SubmitUssResponse{
+ Success: true,
+ Path: request.Path,
+ JobId: string(out),
}
return
}
@@ -309,7 +331,7 @@ func HandleSubmitJclRequest(conn *utils.StdioConn, params []byte) (result any, e
result = jobs.SubmitJclResponse{
Success: true,
- JobId: strings.TrimSpace(string(out)),
+ JobId: string(out),
}
return
}
diff --git a/native/golang/types/jobs/requests.go b/native/golang/types/jobs/requests.go
index 1f57c25..92cd060 100644
--- a/native/golang/types/jobs/requests.go
+++ b/native/golang/types/jobs/requests.go
@@ -64,6 +64,13 @@ type SubmitJobRequest struct {
Dsname string `json:"dsname"`
}
+type SubmitUssRequest struct {
+ common.CommandRequest `tstype:",extends"`
+ Command string `json:"command" tstype:"\"submitUss\""`
+ // File path w/ contents to submit as JCL
+ Path string `json:"fspath"`
+}
+
type SubmitJclRequest struct {
common.CommandRequest `tstype:",extends"`
Command string `json:"command" tstype:"\"submitJcl\""`
diff --git a/native/golang/types/jobs/responses.go b/native/golang/types/jobs/responses.go
index 802c3e5..6abe878 100644
--- a/native/golang/types/jobs/responses.go
+++ b/native/golang/types/jobs/responses.go
@@ -60,6 +60,16 @@ type SubmitJobResponse struct {
Dsname string `json:"dsname"`
}
+type SubmitUssResponse struct {
+ common.CommandResponse `tstype:",extends"`
+ // Whether the job was successfully submitted
+ Success bool `json:"success"`
+ // The job ID of the newly-submitted job
+ JobId string `json:"jobId"`
+ // The USS file where the JCL was read from
+ Path string `json:"fspath"`
+}
+
type SubmitJclResponse struct {
common.CommandResponse `tstype:",extends"`
// Whether the JCL was successfully submitted
diff --git a/packages/cli/CHANGELOG.md b/packages/cli/CHANGELOG.md
index a424180..d970473 100644
--- a/packages/cli/CHANGELOG.md
+++ b/packages/cli/CHANGELOG.md
@@ -12,6 +12,7 @@ Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how
- Added support for cancelling jobs. [#138](https://github.com/zowe/zowe-native-proto/pull/138)
- Added support for holding and releasing jobs. [#182](https://github.com/zowe/zowe-native-proto/pull/182)
- Updated error handling for listing data sets. [#185](https://github.com/zowe/zowe-native-proto/pull/185)
+- Added `zssh submit uss-file|local-file|data-set` commands. [#184](https://github.com/zowe/zowe-native-proto/pull/184)
## [Unreleased]
diff --git a/packages/cli/src/submit/Submit.definition.ts b/packages/cli/src/submit/Submit.definition.ts
index fe49e28..44734b6 100644
--- a/packages/cli/src/submit/Submit.definition.ts
+++ b/packages/cli/src/submit/Submit.definition.ts
@@ -12,7 +12,10 @@
import type { ICommandDefinition } from "@zowe/imperative";
import { SshSession } from "@zowe/zos-uss-for-zowe-sdk";
import { Constants } from "../Constants";
+import { SubmitDsDefinition } from "./ds/Dataset.definition";
+import { SubmitLocalFileDefinition } from "./local-file/LocalFile.definition";
import { SubmitStdinDefinition } from "./stdin/Stdin.definition";
+import { SubmitUssDefinition } from "./uss/Uss.definition";
const SubmitDefinition: ICommandDefinition = {
name: "submit",
@@ -20,7 +23,7 @@ const SubmitDefinition: ICommandDefinition = {
summary: "Submit contents",
description: "Submit resource contents or requests to a mainframe system",
type: "group",
- children: [SubmitStdinDefinition],
+ children: [SubmitStdinDefinition, SubmitDsDefinition, SubmitUssDefinition, SubmitLocalFileDefinition],
passOn: [
{
property: "options",
diff --git a/packages/cli/src/submit/ds/Dataset.definition.ts b/packages/cli/src/submit/ds/Dataset.definition.ts
new file mode 100644
index 0000000..0628f51
--- /dev/null
+++ b/packages/cli/src/submit/ds/Dataset.definition.ts
@@ -0,0 +1,37 @@
+/**
+ * This program and the accompanying materials are made available under the terms of the
+ * Eclipse Public License v2.0 which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-v20.html
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Copyright Contributors to the Zowe Project.
+ *
+ */
+
+import type { ICommandDefinition } from "@zowe/imperative";
+
+export const SubmitDsDefinition: ICommandDefinition = {
+ handler: `${__dirname}/Dataset.handler`,
+ description: "Submit a job from JCL written in a dataset.",
+ type: "command",
+ name: "data-set",
+ aliases: ["ds"],
+ summary: "Submit a job from a dataset",
+ examples: [
+ {
+ description: 'Submit a job from the dataset "IBMUSER.PUBLIC.CNTL(IEFBR14)"',
+ options: '"IBMUSER.PUBLIC.CNTL(IEFBR14)"',
+ },
+ ],
+ positionals: [
+ {
+ name: "name",
+ description: "The dataset containing the JCL to submit",
+ type: "string",
+ required: true,
+ },
+ ],
+ profile: { optional: ["ssh"] },
+ outputFormatOptions: true,
+};
diff --git a/packages/cli/src/submit/ds/Dataset.handler.ts b/packages/cli/src/submit/ds/Dataset.handler.ts
new file mode 100644
index 0000000..53a3e65
--- /dev/null
+++ b/packages/cli/src/submit/ds/Dataset.handler.ts
@@ -0,0 +1,30 @@
+/**
+ * This program and the accompanying materials are made available under the terms of the
+ * Eclipse Public License v2.0 which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-v20.html
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Copyright Contributors to the Zowe Project.
+ *
+ */
+
+import { text } from "node:stream/consumers";
+import type { IHandlerParameters } from "@zowe/imperative";
+import type { ZSshClient, jobs } from "zowe-native-proto-sdk";
+import { SshBaseHandler } from "../../SshBaseHandler";
+
+export default class SubmitDsHandler extends SshBaseHandler {
+ public async processWithClient(params: IHandlerParameters, client: ZSshClient): Promise {
+ const dsname = params.arguments.name;
+ const response = await client.jobs.submitJob({ dsname });
+
+ const msg = `Job submitted: ${response.jobId}`;
+ params.response.data.setMessage(msg);
+ params.response.data.setObj(response);
+ if (response.success) {
+ params.response.console.log(msg);
+ }
+ return response;
+ }
+}
diff --git a/packages/cli/src/submit/local-file/LocalFile.definition.ts b/packages/cli/src/submit/local-file/LocalFile.definition.ts
new file mode 100644
index 0000000..c967006
--- /dev/null
+++ b/packages/cli/src/submit/local-file/LocalFile.definition.ts
@@ -0,0 +1,37 @@
+/**
+ * This program and the accompanying materials are made available under the terms of the
+ * Eclipse Public License v2.0 which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-v20.html
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Copyright Contributors to the Zowe Project.
+ *
+ */
+
+import type { ICommandDefinition } from "@zowe/imperative";
+
+export const SubmitLocalFileDefinition: ICommandDefinition = {
+ handler: `${__dirname}/LocalFile.handler`,
+ description: "Submit a job from JCL written in a local file.",
+ type: "command",
+ name: "local-file",
+ aliases: ["lf"],
+ summary: "Submit a job from local files",
+ examples: [
+ {
+ description: 'Submit a job from the file "my_jcl.txt"',
+ options: '"my_jcl.txt"',
+ },
+ ],
+ positionals: [
+ {
+ name: "fspath",
+ description: "The path to the JCL to submit",
+ type: "string",
+ required: true,
+ },
+ ],
+ profile: { optional: ["ssh"] },
+ outputFormatOptions: true,
+};
diff --git a/packages/cli/src/submit/local-file/LocalFile.handler.ts b/packages/cli/src/submit/local-file/LocalFile.handler.ts
new file mode 100644
index 0000000..5deec65
--- /dev/null
+++ b/packages/cli/src/submit/local-file/LocalFile.handler.ts
@@ -0,0 +1,40 @@
+/**
+ * This program and the accompanying materials are made available under the terms of the
+ * Eclipse Public License v2.0 which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-v20.html
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Copyright Contributors to the Zowe Project.
+ *
+ */
+
+import { readFileSync } from "node:fs";
+import { type IHandlerParameters, ImperativeError } from "@zowe/imperative";
+import { B64String, type ZSshClient, type jobs } from "zowe-native-proto-sdk";
+import { SshBaseHandler } from "../../SshBaseHandler";
+
+export default class SubmitLocalFileHandler extends SshBaseHandler {
+ public async processWithClient(params: IHandlerParameters, client: ZSshClient): Promise {
+ const fspath = params.arguments.fspath;
+ let JclString: Buffer;
+ try {
+ JclString = readFileSync(fspath);
+ } catch (err) {
+ throw new ImperativeError({
+ msg: "Failed to read local file",
+ additionalDetails: err.toString(),
+ causeErrors: err,
+ });
+ }
+ const response = await client.jobs.submitJcl({ jcl: B64String.encode(JclString) });
+
+ const msg = `Job submitted: ${response.jobId}`;
+ params.response.data.setMessage(msg);
+ params.response.data.setObj(response);
+ if (response.success) {
+ params.response.console.log(msg);
+ }
+ return response;
+ }
+}
diff --git a/packages/cli/src/submit/uss/Uss.definition.ts b/packages/cli/src/submit/uss/Uss.definition.ts
new file mode 100644
index 0000000..f293a9a
--- /dev/null
+++ b/packages/cli/src/submit/uss/Uss.definition.ts
@@ -0,0 +1,37 @@
+/**
+ * This program and the accompanying materials are made available under the terms of the
+ * Eclipse Public License v2.0 which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-v20.html
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Copyright Contributors to the Zowe Project.
+ *
+ */
+
+import type { ICommandDefinition } from "@zowe/imperative";
+
+export const SubmitUssDefinition: ICommandDefinition = {
+ handler: `${__dirname}/Uss.handler`,
+ description: "Submit a job from JCL written in a USS file.",
+ type: "command",
+ name: "uss-file",
+ aliases: ["uss"],
+ summary: "Submit a job from USS files",
+ examples: [
+ {
+ description: 'Submit a job from the USS file "my_jcl.txt"',
+ options: '"my_jcl.txt"',
+ },
+ ],
+ positionals: [
+ {
+ name: "fspath",
+ description: "The USS path to the JCL to submit",
+ type: "string",
+ required: true,
+ },
+ ],
+ profile: { optional: ["ssh"] },
+ outputFormatOptions: true,
+};
diff --git a/packages/cli/src/submit/uss/Uss.handler.ts b/packages/cli/src/submit/uss/Uss.handler.ts
new file mode 100644
index 0000000..36ece5f
--- /dev/null
+++ b/packages/cli/src/submit/uss/Uss.handler.ts
@@ -0,0 +1,29 @@
+/**
+ * This program and the accompanying materials are made available under the terms of the
+ * Eclipse Public License v2.0 which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-v20.html
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Copyright Contributors to the Zowe Project.
+ *
+ */
+
+import type { IHandlerParameters } from "@zowe/imperative";
+import type { ZSshClient, jobs } from "zowe-native-proto-sdk";
+import { SshBaseHandler } from "../../SshBaseHandler";
+
+export default class SubmitUssHandler extends SshBaseHandler {
+ public async processWithClient(params: IHandlerParameters, client: ZSshClient): Promise {
+ const fspath = params.arguments.fspath;
+ const response = await client.jobs.submitUss({ fspath });
+
+ const msg = `Job submitted: ${response.jobId}`;
+ params.response.data.setMessage(msg);
+ params.response.data.setObj(response);
+ if (response.success) {
+ params.response.console.log(msg);
+ }
+ return response;
+ }
+}
diff --git a/packages/sdk/CHANGELOG.md b/packages/sdk/CHANGELOG.md
index 9423e92..02ad40a 100644
--- a/packages/sdk/CHANGELOG.md
+++ b/packages/sdk/CHANGELOG.md
@@ -9,6 +9,7 @@ Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how
- Added `ds.restoreDataset` function. [#38](https://github.com/zowe/zowe-native-proto/pull/38)
- Added support for cancelling jobs. [#138](https://github.com/zowe/zowe-native-proto/pull/138)
- Added support for holding and releasing jobs. [#182](https://github.com/zowe/zowe-native-proto/pull/182)
+- Added `jobs.submitUss` function. [#184](https://github.com/zowe/zowe-native-proto/pull/184)
## [Unreleased]
diff --git a/packages/sdk/src/AbstractRpcClient.ts b/packages/sdk/src/AbstractRpcClient.ts
index b7b8168..f5b18c0 100644
--- a/packages/sdk/src/AbstractRpcClient.ts
+++ b/packages/sdk/src/AbstractRpcClient.ts
@@ -53,6 +53,8 @@ export abstract class AbstractRpcClient {
this.request({ command: "deleteJob", ...request }),
submitJob: (request: Omit): Promise =>
this.request({ command: "submitJob", ...request }),
+ submitUss: (request: Omit): Promise =>
+ this.request({ command: "submitUss", ...request }),
submitJcl: (request: Omit): Promise =>
this.request({ command: "submitJcl", ...request }),
holdJob: (request: Omit): Promise =>
diff --git a/packages/sdk/src/doc/gen/jobs.ts b/packages/sdk/src/doc/gen/jobs.ts
index 7d9e49f..464cc3d 100644
--- a/packages/sdk/src/doc/gen/jobs.ts
+++ b/packages/sdk/src/doc/gen/jobs.ts
@@ -74,6 +74,13 @@ export interface SubmitJobRequest extends common.CommandRequest {
*/
dsname: string;
}
+export interface SubmitUssRequest extends common.CommandRequest {
+ command: "submitUss";
+ /**
+ * File path w/ contents to submit as JCL
+ */
+ fspath: string;
+}
export interface SubmitJclRequest extends common.CommandRequest {
command: "submitJcl";
/**
@@ -173,6 +180,20 @@ export interface SubmitJobResponse extends common.CommandResponse {
*/
dsname: string;
}
+export interface SubmitUssResponse extends common.CommandResponse {
+ /**
+ * Whether the job was successfully submitted
+ */
+ success: boolean;
+ /**
+ * The job ID of the newly-submitted job
+ */
+ jobId: string;
+ /**
+ * The USS file where the JCL was read from
+ */
+ fspath: string;
+}
export interface SubmitJclResponse extends common.CommandResponse {
/**
* Whether the JCL was successfully submitted