From ee61ccba9cdba7e7918a3dc14808b7de5eaa5ce3 Mon Sep 17 00:00:00 2001 From: Gordon Smith Date: Fri, 2 Aug 2024 16:32:52 +0100 Subject: [PATCH 01/12] HPCC-32417 Add visibility changed event to DockPanel Fix linter issue (introduced by wasm version bump) Bump wasm package (avoid additional warnings) Signed-off-by: Gordon Smith --- esp/src/eslint/index.js | 3 ++ esp/src/package-lock.json | 25 +++++------- esp/src/package.json | 2 +- esp/src/src-react/components/ECLArchive.tsx | 2 +- esp/src/src-react/components/Frame.tsx | 2 +- esp/src/src-react/components/Metrics.tsx | 2 +- esp/src/src-react/layouts/DockPanel.tsx | 45 ++++++++++++++++++--- 7 files changed, 57 insertions(+), 24 deletions(-) diff --git a/esp/src/eslint/index.js b/esp/src/eslint/index.js index 3a433ad8a60..c3bdb1cd045 100644 --- a/esp/src/eslint/index.js +++ b/esp/src/eslint/index.js @@ -2,6 +2,9 @@ module.exports = { rules: { "no-src-react": { + meta: { + fixable: "code" + }, create: function (context) { return { ImportDeclaration(node) { diff --git a/esp/src/package-lock.json b/esp/src/package-lock.json index e15b7782995..ecb1390c775 100644 --- a/esp/src/package-lock.json +++ b/esp/src/package-lock.json @@ -31,7 +31,7 @@ "@hpcc-js/timeline": "2.53.0", "@hpcc-js/tree": "2.41.0", "@hpcc-js/util": "2.52.0", - "@hpcc-js/wasm": "2.18.1", + "@hpcc-js/wasm": "2.18.2", "@kubernetes/client-node": "0.20.0", "clipboard": "2.0.11", "d3-dsv": "3.0.1", @@ -89,12 +89,13 @@ "dev": true }, "node_modules/@75lb/deep-merge": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@75lb/deep-merge/-/deep-merge-1.1.1.tgz", - "integrity": "sha512-xvgv6pkMGBA6GwdyJbNAnDmfAIR/DfWhrj9jgWh3TY7gRm3KO46x/GPjRg6wJ0nOepwqrNxFfojebh0Df4h4Tw==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@75lb/deep-merge/-/deep-merge-1.1.2.tgz", + "integrity": "sha512-08K9ou5VNbheZFxM5tDWoqjA3ImC50DiuuJ2tj1yEPRfkp8lLLg6XAaJ4On+a0yAXor/8ay5gHnAIshRM44Kpw==", "dev": true, + "license": "MIT", "dependencies": { - "lodash.assignwith": "^4.2.0", + "lodash": "^4.17.21", "typical": "^7.1.1" }, "engines": { @@ -2334,9 +2335,9 @@ "license": "0BSD" }, "node_modules/@hpcc-js/wasm": { - "version": "2.18.1", - "resolved": "https://registry.npmjs.org/@hpcc-js/wasm/-/wasm-2.18.1.tgz", - "integrity": "sha512-fT8NCOTaF0NDnT+ZwWpV2VQ6ywFEqw+fG87GSPNQemEmg7FFqUaKRQOW9MBICrkZcXaJBb7VHo1t5UF6bi/JgQ==", + "version": "2.18.2", + "resolved": "https://registry.npmjs.org/@hpcc-js/wasm/-/wasm-2.18.2.tgz", + "integrity": "sha512-9FIpuXvIsIY3UbUd/HZPPiaZe6IFIuA6k5j9Lh54QcINP1s9hbMr/na0xjt+qRPXlwZdrOz3zQJBzHEEQDKnCw==", "license": "Apache-2.0", "dependencies": { "yargs": "17.7.2" @@ -8065,12 +8066,6 @@ "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==" }, - "node_modules/lodash.assignwith": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.assignwith/-/lodash.assignwith-4.2.0.tgz", - "integrity": "sha512-ZznplvbvtjK2gMvnQ1BR/zqPFZmS6jbK4p+6Up4xcRYA7yMIwxHCfbTcrYxXKzzqLsQ05eJPVznEW3tuwV7k1g==", - "dev": true - }, "node_modules/lodash.camelcase": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", @@ -12322,4 +12317,4 @@ } } } -} \ No newline at end of file +} diff --git a/esp/src/package.json b/esp/src/package.json index c1ec1651488..e9d7224d6f4 100644 --- a/esp/src/package.json +++ b/esp/src/package.json @@ -57,7 +57,7 @@ "@hpcc-js/timeline": "2.53.0", "@hpcc-js/tree": "2.41.0", "@hpcc-js/util": "2.52.0", - "@hpcc-js/wasm": "2.18.1", + "@hpcc-js/wasm": "2.18.2", "@kubernetes/client-node": "0.20.0", "clipboard": "2.0.11", "d3-dsv": "3.0.1", diff --git a/esp/src/src-react/components/ECLArchive.tsx b/esp/src/src-react/components/ECLArchive.tsx index 8d63d3ae8f5..a84ceaae3ac 100644 --- a/esp/src/src-react/components/ECLArchive.tsx +++ b/esp/src/src-react/components/ECLArchive.tsx @@ -111,7 +111,7 @@ export const ECLArchive: React.FunctionComponent = ({ return } main={ - + { // Only render after archive is loaded (to ensure it "defaults to open") --- archive?.modAttrs.length && diff --git a/esp/src/src-react/components/Frame.tsx b/esp/src/src-react/components/Frame.tsx index 9821ffdfd43..76b39bd3a5d 100644 --- a/esp/src/src-react/components/Frame.tsx +++ b/esp/src/src-react/components/Frame.tsx @@ -88,7 +88,7 @@ export const Frame: React.FunctionComponent = () => { router.resolve(hashHistory.location).then(setBody); - userKeyValStore().get("user_cookie_consent") + userKeyValStore().get(USER_COOKIE_CONSENT) .then((resp) => { setShowCookieConsent(resp === "1"); }) diff --git a/esp/src/src-react/components/Metrics.tsx b/esp/src/src-react/components/Metrics.tsx index f0df3a94f6a..40413d012c7 100644 --- a/esp/src/src-react/components/Metrics.tsx +++ b/esp/src/src-react/components/Metrics.tsx @@ -634,7 +634,7 @@ export const Metrics: React.FunctionComponent = ({ } main={ - + diff --git a/esp/src/src-react/layouts/DockPanel.tsx b/esp/src/src-react/layouts/DockPanel.tsx index 8ebea0e1c74..d359e0397b9 100644 --- a/esp/src/src-react/layouts/DockPanel.tsx +++ b/esp/src/src-react/layouts/DockPanel.tsx @@ -3,8 +3,8 @@ import * as ReactDOM from "react-dom"; import { Theme, ThemeProvider } from "@fluentui/react"; import { useConst } from "@fluentui/react-hooks"; import { FluentProvider, Theme as ThemeV9 } from "@fluentui/react-components"; -import { HTMLWidget, Widget } from "@hpcc-js/common"; -import { DockPanel as HPCCDockPanel, IClosable } from "@hpcc-js/phosphor"; +import { HTMLWidget, Widget, Utility } from "@hpcc-js/common"; +import { DockPanel as HPCCDockPanel, IClosable, WidgetAdapter } from "@hpcc-js/phosphor"; import { compare2 } from "@hpcc-js/util"; import { lightTheme, lightThemeV9 } from "../themes"; import { useUserTheme } from "../hooks/theme"; @@ -96,6 +96,7 @@ export class ResetableDockPanel extends HPCCDockPanel { protected _origLayout: DockPanelLayout | undefined; protected _lastLayout: DockPanelLayout | undefined; + protected _visibility: { [id: string]: boolean }; resetLayout() { if (this._origLayout) { @@ -118,8 +119,19 @@ export class ResetableDockPanel extends HPCCDockPanel { return formatLayout(this.layout()) ?? this._lastLayout ?? this._origLayout; } + getVisibility() { + return this._visibility; + } + render(callback?: (w: Widget) => void) { - const retVal = super.render(); + const retVal = this._visibility !== undefined ? super.render() : super.render(() => { + if (this._visibility === undefined) { + this._visibility = {}; + this.widgetAdapters().forEach(wa => { + this._visibility[wa.widget.id()] = wa.isVisible; + }); + } + }); if (this._origLayout === undefined) { this._origLayout = formatLayout(this.layout()); } @@ -130,9 +142,27 @@ export class ResetableDockPanel extends HPCCDockPanel { } // Events --- + childActivation(w: Widget, wa: WidgetAdapter) { + } + + childVisibility(w: Widget, visible: boolean, wa: WidgetAdapter) { + if (this._visibility && this._visibility[w.id()] !== visible) { + this._visibility[w.id()] = visible; + this._lazyVisibilityChanged(); + } + } + layoutChanged() { this._lastLayout = this.getLayout(); } + + // Exposed Events --- + private _lazyVisibilityChanged = Utility.debounce(async () => { + this.visibilityChanged(this._visibility); + }, 60); + + visibilityChanged(visibility: { [id: string]: boolean }) { + } } interface DockPanelItemProps { @@ -154,14 +184,16 @@ export const DockPanelItem: React.FunctionComponent = ({ interface DockPanelProps { layout?: object; hideSingleTabs?: boolean; - onDockPanelCreate?: (dockpanel: ResetableDockPanel) => void; + onCreate?: (dockpanel: ResetableDockPanel) => void; + onVisibilityChanged?: (visibility: { [id: string]: boolean }) => void; children?: React.ReactElement | React.ReactElement[]; } export const DockPanel: React.FunctionComponent = ({ layout, hideSingleTabs, - onDockPanelCreate, + onCreate: onDockPanelCreate, + onVisibilityChanged: onDockPanelVisibilityChanged, children }) => { const items = React.useMemo(() => { @@ -179,6 +211,9 @@ export const DockPanel: React.FunctionComponent = ({ onDockPanelCreate(retVal); }, 0); } + if (onDockPanelVisibilityChanged) { + retVal.on("visibilityChanged", visibility => onDockPanelVisibilityChanged(visibility), true); + } return retVal; }); From 2311d12cdde170bce5aea19e76076359367c88ac Mon Sep 17 00:00:00 2001 From: Gordon Smith Date: Fri, 2 Aug 2024 16:32:52 +0100 Subject: [PATCH 02/12] HPCC-32418 Make toolbar optional for all source editor components Signed-off-by: Gordon Smith --- esp/src/src-react/components/SourceEditor.tsx | 32 +++++++++++++------ 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/esp/src/src-react/components/SourceEditor.tsx b/esp/src/src-react/components/SourceEditor.tsx index 5e070c6f419..5164848df25 100644 --- a/esp/src/src-react/components/SourceEditor.tsx +++ b/esp/src/src-react/components/SourceEditor.tsx @@ -147,38 +147,44 @@ export const SourceEditor: React.FunctionComponent = ({ interface TextSourceEditorProps { text: string; readonly?: boolean; + toolbar?: boolean; } export const TextSourceEditor: React.FunctionComponent = ({ text = "", - readonly = false + readonly, + toolbar }) => { - return ; + return ; }; interface XMLSourceEditorProps { text: string; readonly?: boolean; + toolbar?: boolean; } export const XMLSourceEditor: React.FunctionComponent = ({ text = "", - readonly = false + readonly, + toolbar }) => { - return ; + return ; }; interface JSONSourceEditorProps { json?: object; readonly?: boolean; + toolbar?: boolean; onChange?: (obj: object) => void; } export const JSONSourceEditor: React.FunctionComponent = ({ json, - readonly = false, + readonly, + toolbar, onChange = (obj: object) => { } }) => { @@ -197,7 +203,7 @@ export const JSONSourceEditor: React.FunctionComponent = } }, [onChange]); - return ; + return ; }; export interface WUXMLSourceEditorProps { @@ -215,10 +221,12 @@ export const WUXMLSourceEditor: React.FunctionComponent export interface WUResourceEditorProps { src: string; + toolbar?: boolean; } export const WUResourceEditor: React.FunctionComponent = ({ - src + src, + toolbar }) => { const [text, setText] = React.useState(""); @@ -231,7 +239,7 @@ export const WUResourceEditor: React.FunctionComponent = }); }, [src]); - return ; + return ; }; interface ECLSourceEditorProps { @@ -266,6 +274,7 @@ interface FetchEditor { url: string; wuid?: string; readonly?: boolean; + toolbar?: boolean; mode?: "ecl" | "xml" | "text"; } @@ -273,6 +282,7 @@ export const FetchEditor: React.FunctionComponent = ({ url, wuid, readonly = true, + toolbar, mode = "text" }) => { @@ -293,11 +303,12 @@ export const FetchEditor: React.FunctionComponent = ({ } }, [url, wuid]); - return ; + return ; }; interface SQLSourceEditorProps { sql: string; + readonly?: boolean; toolbar?: boolean; onSqlChange?: (sql: string) => void; onFetchHints?: (cm: any, option: any) => Promise; @@ -306,11 +317,12 @@ interface SQLSourceEditorProps { export const SQLSourceEditor: React.FunctionComponent = ({ sql, + readonly, toolbar, onSqlChange, onFetchHints, onSubmit }) => { - return ; + return ; }; From 8501cd0e6041a81d1c3233935b6e399264c04263 Mon Sep 17 00:00:00 2001 From: Gordon Smith Date: Thu, 8 Aug 2024 17:20:19 +0100 Subject: [PATCH 03/12] Split off 9.2.112 Signed-off-by: Gordon Smith --- helm/hpcc/Chart.yaml | 4 ++-- helm/hpcc/templates/_helpers.tpl | 2 +- version.cmake | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/helm/hpcc/Chart.yaml b/helm/hpcc/Chart.yaml index 54a76856aaf..541ec0b4765 100644 --- a/helm/hpcc/Chart.yaml +++ b/helm/hpcc/Chart.yaml @@ -6,9 +6,9 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. -version: 9.2.111-closedown0 +version: 9.2.113-closedown0 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. -appVersion: 9.2.111-closedown0 +appVersion: 9.2.113-closedown0 diff --git a/helm/hpcc/templates/_helpers.tpl b/helm/hpcc/templates/_helpers.tpl index 313cafb9530..c35fa1d92b0 100644 --- a/helm/hpcc/templates/_helpers.tpl +++ b/helm/hpcc/templates/_helpers.tpl @@ -1361,7 +1361,7 @@ Pass in dict with .root, .visibility defined {{- end -}} {{- define "hpcc.generateHelmVersion" -}} -helmVersion: 9.2.111-closedown0 +helmVersion: 9.2.113-closedown0 {{- end -}} {{/* diff --git a/version.cmake b/version.cmake index 375f81065b7..3ff7c348647 100644 --- a/version.cmake +++ b/version.cmake @@ -5,8 +5,8 @@ set ( HPCC_NAME "Community Edition" ) set ( HPCC_PROJECT "community" ) set ( HPCC_MAJOR 9 ) set ( HPCC_MINOR 2 ) -set ( HPCC_POINT 111 ) +set ( HPCC_POINT 113 ) set ( HPCC_MATURITY "closedown" ) set ( HPCC_SEQUENCE 0 ) -set ( HPCC_TAG_TIMESTAMP "2024-08-02T10:48:12Z" ) +set ( HPCC_TAG_TIMESTAMP "2024-08-08T16:20:19Z" ) ### From 2e827e20c65605a9d26334c44c09f53346ccf516 Mon Sep 17 00:00:00 2001 From: James McMullan Date: Thu, 8 Aug 2024 14:53:07 -0400 Subject: [PATCH 04/12] HPCC4-32419 Jirabot Improve transition flow and input handling - Removed the need for the issue transition map - Various security improvements around input handling Signed-off-by: James McMullan James.McMullan@lexisnexis.com --- .github/workflows/jirabot.yml | 80 ++++++++++++++++++----------------- 1 file changed, 41 insertions(+), 39 deletions(-) diff --git a/.github/workflows/jirabot.yml b/.github/workflows/jirabot.yml index 277f6e7afb7..2f1db9c80f2 100644 --- a/.github/workflows/jirabot.yml +++ b/.github/workflows/jirabot.yml @@ -38,33 +38,61 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GHUB_JIRA_USER_MAP: ${{ vars.GHUB_JIRA_USER_MAP }} JIRA_ISSUE_PROPERTY_MAP: ${{ vars.JIRA_ISSUE_PROPERTY_MAP }} - JIRA_ISSUE_TRANSITION_MAP: ${{ vars.JIRA_ISSUE_TRANSITION_MAP }} run: | import os import re import time import sys import json + import subprocess + from email.utils import parseaddr from atlassian.jira import Jira - def updateIssue(jira, issue, prAuthor : str, transitionMap: dict, propertyMap: dict, pull_url: str) -> str: + def sanitizeInput(input: str, inputType: str) -> str: + if inputType.lower() == 'email': + # Return the email address only, returns '' if not valid or found + return parseaddr(input)[1] + else: + return '' + + def updateIssue(jira, issue, prAuthor : str, propertyMap: dict, pull_url: str) -> str: result = '' issueName = issue['key'] issueFields = issue['fields'] - statusName = str(issueFields['status']['name']) - transition = transitionMap.get(statusName, None) + # Need to update user first in case we are starting from Unresourced + if prAuthor: + assignee = issueFields['assignee'] + if assignee is None: + assigneeId = '' + assigneeEmail = '' + else: + assigneeId = assignee['accountId'] + assigneeEmail = assignee["emailAddress"] + + assigneeEmail = sanitizeInput(assigneeEmail, 'email') + + prAuthorId = prAuthor["accountId"] + prAuthorEmail = prAuthor["emailAddress"] + prAuthorEmail = sanitizeInput(prAuthorEmail, 'email') + + if assigneeId is None or assigneeId == '': + jira.assign_issue(issueName, prAuthorId) + result += 'Assigning user: ' + prAuthorEmail + '\n' + elif assigneeId != prAuthorId: + result += 'Changing assignee from: ' + assigneeEmail + ' to: ' + prAuthorEmail + '\n' + jira.assign_issue(issueName, prAuthorId) - if transition == None: - print('Error: Unable to find transition for status: ' + statusName) - elif transition != '': + transitionFlow = ['Merge Pending'] + for desiredStatus in transitionFlow: try: - jira.issue_transition(issueName, transition) - result += 'Workflow Transition: ' + transition + '\n' + transitionId = jira.get_transition_id_to_status_name(issueName, desiredStatus) + jira.set_issue_status_by_transition_id(issueName, transitionId) + result += 'Workflow Transition To: ' + desiredStatus + '\n' except Exception as error: transitions = jira.get_issue_transitions(issueName) - result += 'Error: Transition: "' + transition + '" failed with: "' + str(error) + '" Valid transitions=' + str(transitions) + '\n' + result += 'Error: Transitioning to: "' + desiredStatus + '" failed with: "' + str(error) + '" Valid transitions=' + str(transitions) + '\n' prFieldName = propertyMap.get('pullRequestFieldName', 'customfield_10010') @@ -80,24 +108,6 @@ jobs: elif currentPR is not None and currentPR != pull_url: result += 'Additional PR: ' + pull_url + '\n' - if prAuthor: - assignee = issueFields['assignee'] - if assignee is None: - assigneeId = '' - assigneeEmail = '' - else: - assigneeId = assignee['accountId'] - assigneeEmail = assignee["emailAddress"] - - prAuthorId = prAuthor["accountId"] - prAuthorEmail = prAuthor["emailAddress"] - if assigneeId is None or assigneeId == '': - jira.assign_issue(issueName, prAuthorId) - result += 'Assigning user: ' + prAuthorEmail + '\n' - elif assigneeId != prAuthorId: - result += 'Changing assignee from: ' + assigneeEmail + ' to: ' + prAuthorEmail + '\n' - jira.assign_issue(issueName, prAuthorId) - return result jirabot_user = os.environ['JIRABOT_USERNAME'] @@ -110,7 +120,6 @@ jobs: github_token = os.environ['GITHUB_TOKEN'] comments_url = os.environ['COMMENTS_URL'] - print("%s %s %s" % (title, prAuthor, comments_url)) result = '' issuem = re.search("(HPCC|HH|IDE|EPE|ML|HPCC4J|JAPI)-[0-9]+", title) if issuem: @@ -131,7 +140,7 @@ jobs: if userSearchResults and len(userSearchResults) > 0: jiraUser = userSearchResults[0] else: - print('Error: Unable to find Jira user: ' + prAuthor + ' continuing without assigning') + print('Error: Unable to map GitHub user to Jira user, continuing without assigning') if not jira.issue_exists(issue_name): sys.exit('Error: Unable to find Jira issue: ' + issue_name) @@ -140,17 +149,12 @@ jobs: result = 'Jirabot Action Result:\n' - transitionMap = json.loads(os.environ['JIRA_ISSUE_TRANSITION_MAP']) - if not isinstance(transitionMap, dict): - print('Error: JIRA_ISSUE_TRANSITION_MAP is not a valid JSON object, ignoring.') - transitionMap = {} - jiraIssuePropertyMap = json.loads(os.environ['JIRA_ISSUE_PROPERTY_MAP']) if not isinstance(jiraIssuePropertyMap, dict): print('Error: JIRA_ISSUE_PROPERTY_MAP is not a valid JSON object, ignoring.') jiraIssuePropertyMap = {} - result += updateIssue(jira, issue, jiraUser, transitionMap, jiraIssuePropertyMap, pull_url) + result += updateIssue(jira, issue, jiraUser, jiraIssuePropertyMap, pull_url) jira.issue_add_comment(issue_name, result) result = 'Jira Issue: ' + jira_url + '/browse/' + issue_name + '\n\n' + result @@ -158,9 +162,7 @@ jobs: # Escape the result for JSON result = json.dumps(result) - curlCommand = 'curl -X POST %s -H "Content-Type: application/json" -H "Authorization: token %s" --data \'{ "body": %s }\'' % ( comments_url, github_token, result ) - print(curlCommand) - os.system(curlCommand) + subprocess.run(['curl', '-X', 'POST', comments_url, '-H', 'Content-Type: application/json', '-H', f'Authorization: token {github_token}', '--data', f'{{ "body": {result} }}'], check=True) else: print('Unable to find Jira issue name in title') From 952a8b692b5575a4dca447557d5679ec29ef7699 Mon Sep 17 00:00:00 2001 From: Jake Smith Date: Thu, 15 Aug 2024 16:44:19 +0100 Subject: [PATCH 05/12] Split off 9.4.88 Signed-off-by: Jake Smith --- helm/hpcc/Chart.yaml | 4 ++-- helm/hpcc/templates/_helpers.tpl | 2 +- version.cmake | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/helm/hpcc/Chart.yaml b/helm/hpcc/Chart.yaml index f6fd5069a08..6b890d3a750 100644 --- a/helm/hpcc/Chart.yaml +++ b/helm/hpcc/Chart.yaml @@ -6,9 +6,9 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. -version: 9.4.87-closedown0 +version: 9.4.89-closedown0 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. -appVersion: 9.4.87-closedown0 +appVersion: 9.4.89-closedown0 diff --git a/helm/hpcc/templates/_helpers.tpl b/helm/hpcc/templates/_helpers.tpl index 112bf329345..6a04a569072 100644 --- a/helm/hpcc/templates/_helpers.tpl +++ b/helm/hpcc/templates/_helpers.tpl @@ -1473,7 +1473,7 @@ Pass in dict with .root, .visibility defined {{- end -}} {{- define "hpcc.generateHelmVersion" -}} -helmVersion: 9.4.87-closedown0 +helmVersion: 9.4.89-closedown0 {{- end -}} {{/* diff --git a/version.cmake b/version.cmake index 36b64302db2..d1c48e4651d 100644 --- a/version.cmake +++ b/version.cmake @@ -5,8 +5,8 @@ set ( HPCC_NAME "Community Edition" ) set ( HPCC_PROJECT "community" ) set ( HPCC_MAJOR 9 ) set ( HPCC_MINOR 4 ) -set ( HPCC_POINT 87 ) +set ( HPCC_POINT 89 ) set ( HPCC_MATURITY "closedown" ) set ( HPCC_SEQUENCE 0 ) -set ( HPCC_TAG_TIMESTAMP "2024-08-08T16:19:19Z" ) +set ( HPCC_TAG_TIMESTAMP "2024-08-15T15:44:19Z" ) ### From 431e4e30ba6c842a9252dc060176a0337acb3e9a Mon Sep 17 00:00:00 2001 From: Jake Smith Date: Thu, 15 Aug 2024 16:45:07 +0100 Subject: [PATCH 06/12] Split off 9.2.114 Signed-off-by: Jake Smith --- helm/hpcc/Chart.yaml | 4 ++-- helm/hpcc/templates/_helpers.tpl | 2 +- version.cmake | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/helm/hpcc/Chart.yaml b/helm/hpcc/Chart.yaml index 541ec0b4765..38711d74f46 100644 --- a/helm/hpcc/Chart.yaml +++ b/helm/hpcc/Chart.yaml @@ -6,9 +6,9 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. -version: 9.2.113-closedown0 +version: 9.2.115-closedown0 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. -appVersion: 9.2.113-closedown0 +appVersion: 9.2.115-closedown0 diff --git a/helm/hpcc/templates/_helpers.tpl b/helm/hpcc/templates/_helpers.tpl index c35fa1d92b0..00103293fa4 100644 --- a/helm/hpcc/templates/_helpers.tpl +++ b/helm/hpcc/templates/_helpers.tpl @@ -1361,7 +1361,7 @@ Pass in dict with .root, .visibility defined {{- end -}} {{- define "hpcc.generateHelmVersion" -}} -helmVersion: 9.2.113-closedown0 +helmVersion: 9.2.115-closedown0 {{- end -}} {{/* diff --git a/version.cmake b/version.cmake index 3ff7c348647..9b6027ac6bc 100644 --- a/version.cmake +++ b/version.cmake @@ -5,8 +5,8 @@ set ( HPCC_NAME "Community Edition" ) set ( HPCC_PROJECT "community" ) set ( HPCC_MAJOR 9 ) set ( HPCC_MINOR 2 ) -set ( HPCC_POINT 113 ) +set ( HPCC_POINT 115 ) set ( HPCC_MATURITY "closedown" ) set ( HPCC_SEQUENCE 0 ) -set ( HPCC_TAG_TIMESTAMP "2024-08-08T16:20:19Z" ) +set ( HPCC_TAG_TIMESTAMP "2024-08-15T15:45:07Z" ) ### From 56fafb8ad6529a9d731f6cde6612201b3ff053b8 Mon Sep 17 00:00:00 2001 From: Jake Smith Date: Thu, 15 Aug 2024 17:57:49 +0100 Subject: [PATCH 07/12] HPCC-32446 Identify the Thor instance name in interface incompatibility error Signed-off-by: Jake Smith --- thorlcr/master/thgraphmanager.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/thorlcr/master/thgraphmanager.cpp b/thorlcr/master/thgraphmanager.cpp index 5eb01feaca4..9707b5a48d1 100644 --- a/thorlcr/master/thgraphmanager.cpp +++ b/thorlcr/master/thgraphmanager.cpp @@ -545,7 +545,7 @@ bool CJobManager::execute(IConstWorkUnit *workunit, const char *wuid, const char if (workunit->getCodeVersion() == 0) throw makeStringException(0, "Attempting to execute a workunit that hasn't been compiled"); if ((workunit->getCodeVersion() > ACTIVITY_INTERFACE_VERSION) || (workunit->getCodeVersion() < MIN_ACTIVITY_INTERFACE_VERSION)) - throw MakeStringException(0, "Workunit was compiled for eclagent interface version %d, this thor requires version %d..%d", workunit->getCodeVersion(), MIN_ACTIVITY_INTERFACE_VERSION, ACTIVITY_INTERFACE_VERSION); + throw MakeStringException(0, "Workunit was compiled for eclagent interface version %d, this thor (%s) requires version %d..%d", workunit->getCodeVersion(), globals->queryProp("@name"), MIN_ACTIVITY_INTERFACE_VERSION, ACTIVITY_INTERFACE_VERSION); if (workunit->getCodeVersion() == 652) { // Any workunit compiled using eclcc 7.12.0-7.12.18 is not compatible @@ -557,7 +557,7 @@ bool CJobManager::execute(IConstWorkUnit *workunit, const char *wuid, const char const char *point = version + strlen("7.12."); unsigned pointVer = atoi(point); if (pointVer <= 18) - throw MakeStringException(0, "Workunit was compiled by eclcc version %s which is not compatible with this runtime", buildVersion.str()); + throw MakeStringException(0, "Workunit was compiled by eclcc version %s which is not compatible with this thor (%s)", buildVersion.str(), globals->queryProp("@name")); } } From a4cc067029ae61a635754b6ff7caee61e9e11860 Mon Sep 17 00:00:00 2001 From: Jeremy Clements <79224539+jeclrsg@users.noreply.github.com> Date: Mon, 19 Aug 2024 15:16:00 -0400 Subject: [PATCH 08/12] HPCC-32425 ECL Watch v9 copy to clipboard missing columns fixes some missing headers and columns when using the copy selection to clipboard from the Files, Workunits and Queries list pages Signed-off-by: Jeremy Clements <79224539+jeclrsg@users.noreply.github.com> --- esp/src/src-react/components/Files.tsx | 7 ++++++- esp/src/src-react/components/Queries.tsx | 11 +++++++---- esp/src/src-react/components/Workunits.tsx | 18 ++++++++---------- 3 files changed, 21 insertions(+), 15 deletions(-) diff --git a/esp/src/src-react/components/Files.tsx b/esp/src/src-react/components/Files.tsx index 08f5f953c34..6cc33214cbb 100644 --- a/esp/src/src-react/components/Files.tsx +++ b/esp/src/src-react/components/Files.tsx @@ -156,6 +156,7 @@ export const Files: React.FunctionComponent = ({ } return ""; }, + field: nlsHPCC.Protected, }, IsCompressed: { headerIcon: "ZipFolder", @@ -168,6 +169,7 @@ export const Files: React.FunctionComponent = ({ } return ""; }, + field: nlsHPCC.Compressed, }, Name: { label: nlsHPCC.LogicalName, @@ -194,18 +196,21 @@ export const Files: React.FunctionComponent = ({ formatter: (value, row) => { return Utility.formatNum(row.IntRecordCount); }, + csvFormatter: (value, row) => row.IntRecordCount, }, FileSize: { label: nlsHPCC.Size, formatter: (value, row) => { return Utility.convertedSize(row.IntSize); }, + csvFormatter: (value, row) => row.IntSize, }, CompressedFileSizeString: { label: nlsHPCC.CompressedSize, formatter: (value, row) => { return Utility.convertedSize(row.CompressedFileSize); - } + }, + csvFormatter: (value, row) => row.CompressedFileSize, }, Parts: { label: nlsHPCC.Parts, width: 40, diff --git a/esp/src/src-react/components/Queries.tsx b/esp/src/src-react/components/Queries.tsx index e11938a5734..ff45b2a7f6d 100644 --- a/esp/src/src-react/components/Queries.tsx +++ b/esp/src/src-react/components/Queries.tsx @@ -112,7 +112,8 @@ export const Queries: React.FunctionComponent = ({ return ; } return ""; - } + }, + field: nlsHPCC.Suspended, }, ErrorCount: { headerIcon: "Warning", @@ -124,7 +125,8 @@ export const Queries: React.FunctionComponent = ({ return ; } return ""; - } + }, + field: nlsHPCC.ErrorWarnings, }, MixedNodeStates: { headerIcon: "Error", @@ -136,7 +138,7 @@ export const Queries: React.FunctionComponent = ({ return ; } return ""; - } + }, }, Activated: { headerIcon: "SkypeCircleCheck", @@ -147,7 +149,8 @@ export const Queries: React.FunctionComponent = ({ return ; } return ""; - } + }, + field: nlsHPCC.Active, }, Id: { label: nlsHPCC.ID, diff --git a/esp/src/src-react/components/Workunits.tsx b/esp/src/src-react/components/Workunits.tsx index 0fce3d69f16..ab47cf34673 100644 --- a/esp/src/src-react/components/Workunits.tsx +++ b/esp/src/src-react/components/Workunits.tsx @@ -116,7 +116,8 @@ export const Workunits: React.FunctionComponent = ({ return ; } return ""; - } + }, + field: nlsHPCC.Protected, }, Wuid: { label: nlsHPCC.WUID, width: 120, @@ -143,23 +144,20 @@ export const Workunits: React.FunctionComponent = ({ "Compile Cost": { label: nlsHPCC.CompileCost, width: 100, justify: "right", - formatter: (cost, row) => { - return `${formatCost(row.CompileCost)}`; - } + formatter: (cost, row) => `${formatCost(row.CompileCost)}`, + csvFormatter: (cost, row) => row.CompileCost, }, "Execution Cost": { label: nlsHPCC.ExecuteCost, width: 100, justify: "right", - formatter: (cost, row) => { - return `${formatCost(row.ExecuteCost)}`; - } + formatter: (cost, row) => `${formatCost(row.ExecuteCost)}`, + csvFormatter: (cost, row) => row.ExecuteCost, }, "File Access Cost": { label: nlsHPCC.FileAccessCost, width: 100, justify: "right", - formatter: (cost, row) => { - return `${formatCost(row.FileAccessCost)}`; - } + formatter: (cost, row) => `${formatCost(row.FileAccessCost)}`, + csvFormatter: (cost, row) => row.FileAccessCost, } }; }, [filter]); From 5d8b5863988966133749dad3ca396797b8e932d8 Mon Sep 17 00:00:00 2001 From: Jake Smith Date: Thu, 22 Aug 2024 15:27:25 +0100 Subject: [PATCH 09/12] HPCC-32495 Rename splitterSpill option Also rename the force* (compression) options and compressSortOverflow compressAllOutputs Signed-off-by: Jake Smith --- thorlcr/thorutil/thormisc.hpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/thorlcr/thorutil/thormisc.hpp b/thorlcr/thorutil/thormisc.hpp index 4d6ffabe197..4e85c73d6f5 100644 --- a/thorlcr/thorutil/thormisc.hpp +++ b/thorlcr/thorutil/thormisc.hpp @@ -54,7 +54,7 @@ #define THOROPT_HDIST_TARGETWRITELIMIT "hdTargetLimit" // Limit # of writer threads working on a single target (default = unbound, but picks round-robin) #define THOROPT_HDIST_COMP "v9_4_hdCompressorType" // Distribute compressor to use (default = "LZ4") #define THOROPT_HDIST_COMPOPTIONS "v9_4_hdCompressorOptions" // Distribute compressor options, e.g. AES key (default = "") -#define THOROPT_SPLITTER_SPILL "splitterSpill" // Force splitters to spill or not, default is to adhere to helper setting (default = -1) +#define THOROPT_SPLITTER_SPILL "v9_4_splitterSpill" // Force splitters to spill or not, default is to adhere to helper setting (default = -1) #define THOROPT_LOOP_MAX_EMPTY "loopMaxEmpty" // Max # of iterations that LOOP can cycle through with 0 results before errors (default = 1000) #define THOROPT_SMALLSORT "smallSortThreshold" // Use minisort approach, if estimate size of data to sort is below this setting (default = 0) #define THOROPT_PARALLEL_FUNNEL "parallelFunnel" // Use parallel funnel impl. if !ordered (default = true) @@ -66,10 +66,10 @@ #define THOROPT_LKJOIN_LOCALFAILOVER "lkjoin_localfailover" // Force SMART to failover to distributed local lookup join (for testing only) (default = false) #define THOROPT_LKJOIN_HASHJOINFAILOVER "lkjoin_hashjoinfailover" // Force SMART to failover to hash join (for testing only) (default = false) #define THOROPT_MAX_KERNLOG "max_kern_level" // Max kernel logging level, to push to workunit, -1 to disable (default = 3) -#define THOROPT_COMP_FORCELZW "forceLZW" // Forces file compression to use LZW (default = false) -#define THOROPT_COMP_FORCEFLZ "forceFLZ" // Forces file compression to use FLZ (default = false) -#define THOROPT_COMP_FORCELZ4 "forceLZ4" // Forces file compression to use LZ4 (default = false) -#define THOROPT_COMP_FORCELZ4HC "forceLZ4HC" // Forces file compression to use LZ4HC (default = false) +#define THOROPT_COMP_FORCELZW "v9_4_forceLZW" // Forces file compression to use LZW (default = false) +#define THOROPT_COMP_FORCEFLZ "v9_4_forceFLZ" // Forces file compression to use FLZ (default = false) +#define THOROPT_COMP_FORCELZ4 "v9_4_forceLZ4" // Forces file compression to use LZ4 (default = false) +#define THOROPT_COMP_FORCELZ4HC "v9_4_forceLZ4HC" // Forces file compression to use LZ4HC (default = false) #define THOROPT_TRACE_ENABLED "traceEnabled" // Output from TRACE activity enabled (default = false) #define THOROPT_TRACE_LIMIT "traceLimit" // Number of rows from TRACE activity (default = 10) #define THOROPT_READ_CRC "crcReadEnabled" // Enabled CRC validation on disk reads if file CRC are available (default = true) @@ -105,7 +105,7 @@ #define THOROPT_VALIDATE_FILE_TYPE "validateFileType" // validate file type compatibility, e.g. if on fire error if XML reading CSV (default = true) #define THOROPT_MIN_REMOTE_CQ_INDEX_SIZE_MB "minRemoteCQIndexSizeMb" // minimum size of index file to enable server side handling (default = 0, meaning use heuristic to determin) #define THOROPT_KJ_ASSUME_PRIMARY "keyedJoinAssumePrimary" // assume primary part exists (don't check when mapping, which can be slow) -#define THOROPT_COMPRESS_SORTOVERFLOW "compressSortOverflow" // If global sort spills, compress the merged overflow file (default = true) +#define THOROPT_COMPRESS_SORTOVERFLOW "v9_4_compressSortOverflow" // If global sort spills, compress the merged overflow file (default = true) #define THOROPT_TIME_ACTIVITIES "timeActivities" // Time activities (default=true) #define THOROPT_MAX_ACTIVITY_CORES "maxActivityCores" // controls number of default threads to use for very parallel phases (like sort/parallel join helper). (default = # of h/w cores) #define THOROPT_THOR_ROWCRC "THOR_ROWCRC" // Use a CRC checking row allocator (default=false) @@ -114,7 +114,7 @@ #define THOROPT_FAIL_ON_LEAKS "failOnLeaks" // If any leaks are detected at the end of graph, fail the query (default=false) #define THOROPT_SOAP_TRACE_LEVEL "soapTraceLevel" // The trace SOAP level (default=1) #define THOROPT_SORT_ALGORITHM "sortAlgorithm" // The algorithm used to sort records (quicksort/mergesort) -#define THOROPT_COMPRESS_ALLFILES "compressAllOutputs" // Compress all output files (default: bare-metal=off, cloud=on) +#define THOROPT_COMPRESS_ALLFILES "v9_4_compressAllOutputs" // Compress all output files (default: bare-metal=off, cloud=on) #define THOROPT_AVOID_RENAME "avoidRename" // Avoid rename, write directly to target physical filenames (no temp file) From 9e7f3d7e87cf9603adf9dffaa7875559f7bbbef1 Mon Sep 17 00:00:00 2001 From: Jeremy Clements <79224539+jeclrsg@users.noreply.github.com> Date: Thu, 22 Aug 2024 10:54:59 -0400 Subject: [PATCH 10/12] HPCC-32474 ECL Watch v9 allow selection of grid row contents modifies the style of FluentUI grid rows to allow selection of text Signed-off-by: Jeremy Clements <79224539+jeclrsg@users.noreply.github.com> --- esp/src/src-react/components/controls/Grid.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/esp/src/src-react/components/controls/Grid.tsx b/esp/src/src-react/components/controls/Grid.tsx index 7a445acac93..c781322a0f2 100644 --- a/esp/src/src-react/components/controls/Grid.tsx +++ b/esp/src/src-react/components/controls/Grid.tsx @@ -122,6 +122,7 @@ const gridStyles = (height: string): Partial => { maxHeight: height, selectors: { ".ms-DetailsHeader-cellName": { fontSize: "13.5px" }, + ".ms-DetailsRow": { userSelect: "text" }, ".ms-DetailsRow-cell:has(.bgFilled)": { color: "white", boxShadow: "inset 1px 0 var(--colorNeutralBackground1), inset -1px 1px var(--colorNeutralBackground1)" }, ".ms-DetailsRow-cell:has(.bgGreen)": { background: "green" }, ".ms-DetailsRow-cell:has(.bgOrange)": { background: "orange" }, From 074095fc0c974ba393b211de8b71ead61c7f1e43 Mon Sep 17 00:00:00 2001 From: M Kelly Date: Thu, 22 Aug 2024 15:07:23 -0400 Subject: [PATCH 11/12] HPCC-32512 Fix LD_LIBRARY_PATH for internal ssh cmd from frunssh and rsync Signed-off-by: M Kelly --- common/remote/rmtssh.cpp | 3 ++- initfiles/bin/init_thorslave.in | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/common/remote/rmtssh.cpp b/common/remote/rmtssh.cpp index 86682580c7e..f156e2dbd8c 100644 --- a/common/remote/rmtssh.cpp +++ b/common/remote/rmtssh.cpp @@ -99,7 +99,8 @@ class CFRunSSH: public CInterface, implements IFRunSSH break; case 's': { // ssh params bool usepssh = !password.isEmpty(); - cmdbuf.appendf("%s -o LogLevel=QUIET -o StrictHostKeyChecking=%s -o BatchMode=yes ",usepssh?"pssh":"ssh",strict?"yes":"no"); + // reset LD_LIBRARY_PATH here so ssh cmd itself doesn't use HPCC libssl/crypto as they may be different + cmdbuf.appendf("%s -o LogLevel=QUIET -o StrictHostKeyChecking=%s -o BatchMode=yes ",usepssh?"pssh":"LD_LIBRARY_PATH=: ssh",strict?"yes":"no"); if (!identityfile.isEmpty()) cmdbuf.appendf("-i %s ",identityfile.get()); if (background) diff --git a/initfiles/bin/init_thorslave.in b/initfiles/bin/init_thorslave.in index 1048ce6f9ac..ad845f0a74f 100755 --- a/initfiles/bin/init_thorslave.in +++ b/initfiles/bin/init_thorslave.in @@ -102,7 +102,8 @@ start_slaves() rsync_att=3 rsync_stat=1 while [[ $rsync_stat -ne 0 && $rsync_att -gt 0 ]] ; do - rsync -e "ssh -o LogLevel=QUIET -o StrictHostKeyChecking=no" --timeout=60 $master:$instancedir/slaves $slavesfname + # reset LD_LIBRARY_PATH here so ssh cmd doesn't use HPCC libssl/crypto as they may be different + LD_LIBRARY_PATH=: rsync -e "ssh -o LogLevel=QUIET -o StrictHostKeyChecking=no" --timeout=60 $master:$instancedir/slaves $slavesfname rsync_stat=$? ((rsync_att--)) log "rsync returns ${rsync_stat}" From e75fc2be1614bda0714f7df24f4cd3596db894a6 Mon Sep 17 00:00:00 2001 From: M Kelly Date: Fri, 23 Aug 2024 08:17:57 -0400 Subject: [PATCH 12/12] HPCC-32512 Fix LD_LIBRARY_PATH for internal ssh cmd from frunssh and rsync 2 Signed-off-by: M Kelly --- common/remote/rmtssh.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/common/remote/rmtssh.cpp b/common/remote/rmtssh.cpp index f156e2dbd8c..fe08594b4ad 100644 --- a/common/remote/rmtssh.cpp +++ b/common/remote/rmtssh.cpp @@ -99,8 +99,7 @@ class CFRunSSH: public CInterface, implements IFRunSSH break; case 's': { // ssh params bool usepssh = !password.isEmpty(); - // reset LD_LIBRARY_PATH here so ssh cmd itself doesn't use HPCC libssl/crypto as they may be different - cmdbuf.appendf("%s -o LogLevel=QUIET -o StrictHostKeyChecking=%s -o BatchMode=yes ",usepssh?"pssh":"LD_LIBRARY_PATH=: ssh",strict?"yes":"no"); + cmdbuf.appendf("%s -o LogLevel=QUIET -o StrictHostKeyChecking=%s -o BatchMode=yes ",usepssh?"pssh":"ssh",strict?"yes":"no"); if (!identityfile.isEmpty()) cmdbuf.appendf("-i %s ",identityfile.get()); if (background) @@ -423,6 +422,8 @@ class CFRunSSH: public CInterface, implements IFRunSSH printf("%s\n",cmdline.str()); else { Owned pipe = createPipeProcess(); + // reset LD_LIBRARY_PATH here so ssh cmd itself doesn't use HPCC libssl/crypto as they may be different + pipe->setenv("LD_LIBRARY_PATH", ":"); if (pipe->run((verbose&&!usepssh)?"FRUNSSH":NULL,cmdline.str(),workdir, useplink, // for some reason plink needs input handle true,true)) {