@mikarinneoracle/oci-cdk-code-only-preview 0.0.36 → 0.0.38
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -5
- package/bin/deploy-code-only.js +40 -11
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -127,16 +127,16 @@ export OCI_CLI_PATH="/Users/MRINNE/projects/ocdk/.tools/oci-preview-bin/oci"
|
|
|
127
127
|
# Required: OCI target
|
|
128
128
|
export OCI_COMPARTMENT_ID='ocid1.compartment.oc1...'
|
|
129
129
|
|
|
130
|
-
#
|
|
130
|
+
# Optional explicit code-only handler. OCDK converts the standard Python
|
|
131
|
+
# func.yaml entrypoint to func.handler automatically.
|
|
131
132
|
# Optionally pin one: export OCI_CODE_ONLY_RUNTIME_NAME='python312.ol9'
|
|
132
|
-
export OCI_FUNCTION_HANDLER='func.handler'
|
|
133
133
|
|
|
134
134
|
# Required in func.yaml: name: my-function
|
|
135
135
|
# Terraform creates the Function App; OCI CLI preview uploads the ZIP function
|
|
136
136
|
npx ocdk deploy --auto-approve --code-only
|
|
137
137
|
```
|
|
138
138
|
|
|
139
|
-
For a Node.js function, use the JavaScript file as the handler (not `fdk.handle` or `node func.js`):
|
|
139
|
+
For a Node.js function, use the JavaScript file as the handler (not `fdk.handle` or `node func.js`). OCDK resolves the runtime from `build_image` or `run_image` when present:
|
|
140
140
|
|
|
141
141
|
```bash
|
|
142
142
|
export OCI_CODE_ONLY_RUNTIME_NAME='node24.ol9'
|
|
@@ -154,7 +154,7 @@ entrypoint: node func.js
|
|
|
154
154
|
|
|
155
155
|
Keep `@fnproject/fdk` in `package.json` dependencies. The function source file uses `fdk.handle(...)`; it is not the OCI handler value.
|
|
156
156
|
|
|
157
|
-
For Java, the code-only archive must contain exactly one fat/uber JAR at the ZIP root. Build it first and point OCDK to it when necessary:
|
|
157
|
+
For Java, the code-only archive must contain exactly one fat/uber JAR at the ZIP root. OCDK resolves the runtime from a `jdk`/`jre` version in `build_image` or `run_image` when present. Build it first and point OCDK to it when necessary:
|
|
158
158
|
|
|
159
159
|
```bash
|
|
160
160
|
export OCI_CODE_ONLY_RUNTIME_NAME='java21.ol9'
|
|
@@ -173,7 +173,7 @@ OCDK also runs this build automatically when no artifact exists yet, and searche
|
|
|
173
173
|
|
|
174
174
|
#### Find the available code-only runtimes
|
|
175
175
|
|
|
176
|
-
The exact `OCI_CODE_ONLY_RUNTIME_NAME` values are enabled per tenancy and region during this Limited Availability preview. For Python, OCDK queries this list automatically
|
|
176
|
+
The exact `OCI_CODE_ONLY_RUNTIME_NAME` values are enabled per tenancy and region during this Limited Availability preview. For Python, Node.js, and Java, OCDK queries this list automatically. With a plain runtime name, it selects the version in `build_image` or `run_image` (for example `fnproject/python:3.12` selects `python312...`, and `jdk17` selects `java17...`); without a versioned image, it selects the newest matching runtime. Set `OCI_CODE_ONLY_RUNTIME_NAME` to pin or override that choice. Query the Preview CLI to inspect available runtimes or when deploying another language:
|
|
177
177
|
|
|
178
178
|
```bash
|
|
179
179
|
# List every runtime available to the active OCI profile
|
package/bin/deploy-code-only.js
CHANGED
|
@@ -60,17 +60,37 @@ function listItems(result) {
|
|
|
60
60
|
return [];
|
|
61
61
|
}
|
|
62
62
|
|
|
63
|
-
function
|
|
64
|
-
const
|
|
63
|
+
function runtimeLanguage(runtime) {
|
|
64
|
+
const normalized = runtime.toLowerCase().replace(/[^a-z0-9]/g, '');
|
|
65
|
+
return ['python', 'node', 'java'].find((language) => normalized.startsWith(language));
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function runtimeSortKey(runtimeName, language) {
|
|
69
|
+
const match = runtimeName.toLowerCase().match(new RegExp(`^${language}(\\d+)`));
|
|
65
70
|
return match ? Number.parseInt(match[1], 10) : -1;
|
|
66
71
|
}
|
|
67
72
|
|
|
68
|
-
function
|
|
69
|
-
// OCI's preview runtime names omit separators from
|
|
70
|
-
//
|
|
71
|
-
//
|
|
73
|
+
function runtimePrefix(runtime, yaml) {
|
|
74
|
+
// OCI's preview runtime names omit separators from language versions, such
|
|
75
|
+
// as Python 3.12 -> python312. For a plain language name, honor the version
|
|
76
|
+
// in Fn's build_image/run_image before falling back to the newest runtime.
|
|
72
77
|
const normalizedRuntime = runtime.toLowerCase().replace(/[^a-z0-9]/g, '');
|
|
73
|
-
const
|
|
78
|
+
const language = runtimeLanguage(runtime);
|
|
79
|
+
if (!language || normalizedRuntime !== language) return normalizedRuntime;
|
|
80
|
+
for (const key of ['build_image', 'run_image']) {
|
|
81
|
+
const image = yamlValue(yaml, key);
|
|
82
|
+
const versionMatch = language === 'java'
|
|
83
|
+
? image.match(/(?:jdk|jre|java)[-:]?(\d+)/i)
|
|
84
|
+
: image.match(new RegExp(`(?:^|/)${language}:(\\d+)(?:\\.(\\d+))?(?:[-.]|$)`, 'i'));
|
|
85
|
+
if (versionMatch) return `${language}${versionMatch[1]}${versionMatch[2] || ''}`;
|
|
86
|
+
}
|
|
87
|
+
return language;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function resolveRuntime(runtime, yaml) {
|
|
91
|
+
const language = runtimeLanguage(runtime);
|
|
92
|
+
if (!language) return '';
|
|
93
|
+
const namePrefix = runtimePrefix(runtime, yaml);
|
|
74
94
|
const result = jsonOci(['fn', 'runtime', 'list', '--all', '--name-starts-with', namePrefix]);
|
|
75
95
|
const candidates = listItems(result)
|
|
76
96
|
.map(runtimeResourceName)
|
|
@@ -79,14 +99,21 @@ function resolvePythonRuntime(runtime) {
|
|
|
79
99
|
fail(`no available code-only runtime matches ${runtime}. Set OCI_CODE_ONLY_RUNTIME_NAME to a runtime returned by "oci fn runtime list --all".`);
|
|
80
100
|
}
|
|
81
101
|
candidates.sort((left, right) => {
|
|
82
|
-
const versionDifference =
|
|
102
|
+
const versionDifference = runtimeSortKey(right, language) - runtimeSortKey(left, language);
|
|
83
103
|
return versionDifference || right.localeCompare(left);
|
|
84
104
|
});
|
|
85
105
|
const selected = candidates[0];
|
|
86
|
-
console.log(`Selected OCI code-only runtime ${selected} for func.yaml runtime ${runtime}. Set OCI_CODE_ONLY_RUNTIME_NAME to pin a different runtime.`);
|
|
106
|
+
console.log(`Selected OCI code-only runtime ${selected} for func.yaml runtime ${runtime} (runtime prefix ${namePrefix}). Set OCI_CODE_ONLY_RUNTIME_NAME to pin a different runtime.`);
|
|
87
107
|
return selected;
|
|
88
108
|
}
|
|
89
109
|
|
|
110
|
+
function codeOnlyPythonHandler(handler) {
|
|
111
|
+
// Fn's generated container entrypoint is not a code-only handler. Convert
|
|
112
|
+
// the standard form to the handler syntax required by the managed runtime.
|
|
113
|
+
const match = handler.match(/^\/python\/bin\/fdk\s+\/function\/(.+?)\.py\s+([A-Za-z_][A-Za-z0-9_]*)$/);
|
|
114
|
+
return match ? `${match[1].replace(/[\\/]/g, '.')}.${match[2]}` : handler;
|
|
115
|
+
}
|
|
116
|
+
|
|
90
117
|
function readFunctionMetadata() {
|
|
91
118
|
const funcYamlPath = path.join(projectDir, 'func.yaml');
|
|
92
119
|
const yaml = fs.existsSync(funcYamlPath) ? fs.readFileSync(funcYamlPath, 'utf8') : '';
|
|
@@ -94,19 +121,21 @@ function readFunctionMetadata() {
|
|
|
94
121
|
const appName = (process.env.OCI_FUNCTION_APP_NAME || functionName).trim();
|
|
95
122
|
const configuredRuntime = yamlValue(yaml, 'runtime');
|
|
96
123
|
const runtimeName = (process.env.OCI_CODE_ONLY_RUNTIME_NAME || '').trim()
|
|
97
|
-
|| (configuredRuntime
|
|
124
|
+
|| resolveRuntime(configuredRuntime, yaml);
|
|
98
125
|
const configuredHandler = (process.env.OCI_FUNCTION_HANDLER || yamlValue(yaml, 'cmd') || yamlValue(yaml, 'entrypoint')).trim();
|
|
99
126
|
// The managed Node runtime already invokes `node`; its handler is the script
|
|
100
127
|
// path, whereas a conventional func.yaml entrypoint is `node func.js`.
|
|
101
128
|
const handler = runtimeName.toLowerCase().startsWith('node')
|
|
102
129
|
? configuredHandler.replace(/^node\s+/, '')
|
|
130
|
+
: runtimeName.toLowerCase().startsWith('python')
|
|
131
|
+
? codeOnlyPythonHandler(configuredHandler)
|
|
103
132
|
: configuredHandler;
|
|
104
133
|
const memory = integerValue(process.env.OCI_FUNCTION_MEMORY_MB || yamlValue(yaml, 'memory'), 'OCI_FUNCTION_MEMORY_MB', 256);
|
|
105
134
|
const timeout = integerValue(process.env.OCI_FUNCTION_TIMEOUT_SECONDS || yamlValue(yaml, 'timeout'), 'OCI_FUNCTION_TIMEOUT_SECONDS', 30);
|
|
106
135
|
|
|
107
136
|
if (!functionName) fail('set OCI_FUNCTION_NAME or add name: to func.yaml.');
|
|
108
137
|
if (!appName) fail('set OCI_FUNCTION_APP_NAME.');
|
|
109
|
-
if (!runtimeName) fail('set OCI_CODE_ONLY_RUNTIME_NAME (for example python312.ol9). Automatic runtime resolution
|
|
138
|
+
if (!runtimeName) fail('set OCI_CODE_ONLY_RUNTIME_NAME (for example python312.ol9). Automatic runtime resolution supports Python, Node.js, and Java func.yaml runtimes.');
|
|
110
139
|
if (!handler) fail('set OCI_FUNCTION_HANDLER or add cmd: to func.yaml.');
|
|
111
140
|
|
|
112
141
|
return { functionName, appName, handler, runtimeName, memory, timeout };
|