diff --git a/README.md b/README.md
index 2b83fa8e..07e684d2 100644
--- a/README.md
+++ b/README.md
@@ -38,7 +38,12 @@ SecretNote SF 现在隐语实训平台提供云端版本,开箱即用,无需
使用上述配置的节点地址为 `127.0.0.1:8090` 和 `127.0.0.1:8092`。在代码中,节点间可通过 service 名相互访问;镜像使用 8888 作为 Notebook 服务端口,6379 作为 Ray 端口,8000 作为 SecretFlow 集群网络端口,8001 作为 SPU 端口
-- 如有需要,请查看更完整的具体[示例](docs/SECRETFLOW-INTRO.md)
+- 典型的本地运行的两计算节点(2PC)架构示意图如下所示。如有需要,请查看更完整的具体[示例](docs/SECRETFLOW-INTRO.md)
+
+
+
+
+
### 本地启动 SecretNote SCQL
diff --git a/docker/secretflow-secretnote/Dockerfile b/docker/secretflow-secretnote/Dockerfile
index 56da71d3..2f3fc5ce 100644
--- a/docker/secretflow-secretnote/Dockerfile
+++ b/docker/secretflow-secretnote/Dockerfile
@@ -1,7 +1,7 @@
# This Dockerfile will build the secretflow/secretnote image for depolying a node
# for SecretNote.
-ARG SECRETFLOW_VERSION="1.10.0b0"
+ARG SECRETFLOW_VERSION="1.11.0b1"
# Get the repository and remove unncessary files
FROM alpine:3.14 AS source-tree
diff --git a/docker/secretflow-secretnote/root/scripts/start.sh b/docker/secretflow-secretnote/root/scripts/start.sh
index 260f3454..c6f85d06 100755
--- a/docker/secretflow-secretnote/root/scripts/start.sh
+++ b/docker/secretflow-secretnote/root/scripts/start.sh
@@ -11,4 +11,7 @@ if [ -z "${PORT}" ]; then
PORT=8888
fi
-secretnote sf --config=/home/secretnote/.jupyter/jupyter_server_config.py --allow-root --no-browser --port $PORT
+# `--_as-compute-node` is a private flag only used for SecretNote SF Docker image build
+secretnote sf --_as-compute-node \
+ --config=/home/secretnote/.jupyter/jupyter_server_config.py \
+ --allow-root --no-browser --port $PORT
diff --git a/docker/secretnote-sf-sim/docker-compose.yml b/docker/secretnote-sf-sim/docker-compose.yml
index 9a4b8ca5..bc31d77e 100644
--- a/docker/secretnote-sf-sim/docker-compose.yml
+++ b/docker/secretnote-sf-sim/docker-compose.yml
@@ -1,6 +1,6 @@
services:
alice:
- image: secretflow/secretnote:1.10.0b0
+ image: secretflow/secretnote:1.11.0b1
pull_policy: if_not_present
platform: linux/amd64
environment:
@@ -11,7 +11,7 @@ services:
- ./alice:/home/secretnote/workspace
bob:
- image: secretflow/secretnote:1.10.0b0
+ image: secretflow/secretnote:1.11.0b1
pull_policy: if_not_present
platform: linux/amd64
environment:
diff --git a/docs/images/sf-2pc-arch.jpg b/docs/images/sf-2pc-arch.jpg
new file mode 100644
index 00000000..1b680b08
Binary files /dev/null and b/docs/images/sf-2pc-arch.jpg differ
diff --git a/package.json b/package.json
index 2b126cb6..87c2d84e 100644
--- a/package.json
+++ b/package.json
@@ -16,7 +16,7 @@
"ci:check:javascript": "nx run-many -t format:prettier -t lint:eslint -t typecheck:tsc",
"ci:check:python": "nx run-many -t format:black -t test:pytest -t typecheck:pyright",
"ci:build": "nx run-many -t build:component -t build:site && nx run-many -t build:py:ci",
- "docker:build": "docker buildx build --build-arg SECRETFLOW_VERSION=1.10.0b0 --platform linux/arm64 -t secretflow/secretnote:1.10.0b0 -f ./docker/secretflow-secretnote/Dockerfile .",
+ "docker:build": "docker buildx build --build-arg SECRETFLOW_VERSION=1.11.0b1 --platform linux/arm64 -t secretflow/secretnote:1.11.0b1 -f ./docker/secretflow-secretnote/Dockerfile .",
"docker:up": "docker-compose -f ./docker/secretnote-sf-sim/docker-compose.yml up"
},
"devDependencies": {
diff --git a/packages/secretnote-sf/package.json b/packages/secretnote-sf/package.json
index ac0f380f..f3d14a86 100644
--- a/packages/secretnote-sf/package.json
+++ b/packages/secretnote-sf/package.json
@@ -1,6 +1,6 @@
{
"name": "@alipay/secretnote-sf",
- "version": "0.0.51",
+ "version": "0.0.52",
"license": "Apache-2.0",
"author": "vectorse@126.com",
"repository": "https://github.com/secretflow/secretnote/tree/main/packages/secretnote",
diff --git a/packages/secretnote-sf/src/modules/preview/index.less b/packages/secretnote-sf/src/modules/preview/index.less
index 45baa4ca..8e820b82 100644
--- a/packages/secretnote-sf/src/modules/preview/index.less
+++ b/packages/secretnote-sf/src/modules/preview/index.less
@@ -1,5 +1,13 @@
-.secretnote-split-panel-right {
+.secretnote-preview-split-panel-right {
.libro-view-content-left {
padding-right: 0 !important;
}
+
+ > .mana-view-container {
+ > .libro-view {
+ > .libro-view-top {
+ display: none;
+ }
+ }
+ }
}
diff --git a/packages/secretnote-sf/src/modules/preview/layout.tsx b/packages/secretnote-sf/src/modules/preview/layout.tsx
index aba0cb68..51f70b28 100644
--- a/packages/secretnote-sf/src/modules/preview/layout.tsx
+++ b/packages/secretnote-sf/src/modules/preview/layout.tsx
@@ -23,7 +23,7 @@ const PreviewSecreteNoteLayout: React.FC = () => {
{
minSize={400}
flex={1}
flexGrow={1}
- className="secretnote-split-panel-right"
+ className="secretnote-preview-split-panel-right"
>
diff --git a/packages/secretnote-sf/src/pages/sf-preview/index.less b/packages/secretnote-sf/src/pages/sf-preview/index.less
deleted file mode 100644
index 28efadff..00000000
--- a/packages/secretnote-sf/src/pages/sf-preview/index.less
+++ /dev/null
@@ -1,9 +0,0 @@
-.secretnote-sf-preview-container {
- .mana-view-container {
- > .libro-view {
- > .libro-view-top {
- display: none;
- }
- }
- }
-}
diff --git a/packages/secretnote-sf/src/pages/sf-preview/index.tsx b/packages/secretnote-sf/src/pages/sf-preview/index.tsx
index 49d2a2cc..20ba3542 100644
--- a/packages/secretnote-sf/src/pages/sf-preview/index.tsx
+++ b/packages/secretnote-sf/src/pages/sf-preview/index.tsx
@@ -16,7 +16,6 @@ import { useRunOnce } from '@/utils/hook';
import '@/lang';
import '../../override.less';
-import './index.less';
export interface ISecretNotePreviewProps {
fileURL?: string; // file URL of the notebook to preview
diff --git a/pyprojects/secretnote/package.json b/pyprojects/secretnote/package.json
index 6bb4b89b..665a1377 100644
--- a/pyprojects/secretnote/package.json
+++ b/pyprojects/secretnote/package.json
@@ -1,7 +1,7 @@
{
"name": "secretnote",
"private": true,
- "version": "0.0.51",
+ "version": "0.0.52",
"type": "module",
"scripts": {
"dev:sf": "cd .. && NODE_ENV=development python -m secretnote sf --config=./secretnote/secretnote/sf/.jupyter/config_dev.py --no-browser",
diff --git a/pyprojects/secretnote/secretnote/__init__.py b/pyprojects/secretnote/secretnote/__init__.py
index a3ebe305..478240bb 100644
--- a/pyprojects/secretnote/secretnote/__init__.py
+++ b/pyprojects/secretnote/secretnote/__init__.py
@@ -1 +1 @@
-__version__ = "0.0.51"
+__version__ = "0.0.52"
diff --git a/pyprojects/secretnote/secretnote/__main__.py b/pyprojects/secretnote/secretnote/__main__.py
index 10cdcd8e..135abff9 100644
--- a/pyprojects/secretnote/secretnote/__main__.py
+++ b/pyprojects/secretnote/secretnote/__main__.py
@@ -6,7 +6,7 @@ def main():
parser.add_argument(
"_positionals",
nargs=argparse.ZERO_OR_MORE,
- help=f"? ?. in {MODE_CHOICES} (default: sf). (default: .).",
+ help=f"? ? [ in {MODE_CHOICES} (default: sf); (default: .)]",
)
# [DEPRECATED] legacy --mode support
_deprecationWarning = "[DEPRECATED] `--mode`. Use positional `mode` instead."
@@ -17,6 +17,8 @@ def main():
required=False,
help=_deprecationWarning,
)
+ # [PRIVATE] whether it's running as a compute node inside the Docker image
+ parser.add_argument("--_as-compute-node", action=argparse.BooleanOptionalAction)
args, rest_args = parser.parse_known_args()
# normalize positional arguments
@@ -38,7 +40,9 @@ def main():
SecretNoteApp().launch([work_dir, *rest_args])
else:
- from .sf.server.app import SecretNoteApp
+ from .sf.server.app import SecretNoteApp, set_as_compute_node
+
+ set_as_compute_node(args._as_compute_node)
SecretNoteApp().launch([work_dir, *rest_args])
diff --git a/pyprojects/secretnote/secretnote/sf/server/app.py b/pyprojects/secretnote/secretnote/sf/server/app.py
index 1e78b445..04cb7b0c 100644
--- a/pyprojects/secretnote/secretnote/sf/server/app.py
+++ b/pyprojects/secretnote/secretnote/sf/server/app.py
@@ -4,12 +4,19 @@
import os
from jupyter_server.extension.application import ExtensionApp, ExtensionAppJinjaMixin
from .services.nodes_handlers import nodes_handlers
-from .services.pages_handlers import pages_handlers
+from .services.pages_handlers import pages_handlers, compute_node_pages_handlers
from .services.misc_handlers import misc_handlers
from .services.contents_handlers import contents_handlers
__dirname__ = os.path.dirname(__file__)
+_AS_COMPUTE_NODE = False
+
+
+def set_as_compute_node(value: bool):
+ global _AS_COMPUTE_NODE
+ _AS_COMPUTE_NODE = value
+
class SecretNoteApp(ExtensionAppJinjaMixin, ExtensionApp):
"""The SecretNote application acted as an ExtensionApp of Jupyter Server."""
@@ -39,7 +46,7 @@ def initialize_handlers(self):
*misc_handlers,
*contents_handlers,
*nodes_handlers,
- *pages_handlers,
+ *(compute_node_pages_handlers if _AS_COMPUTE_NODE else pages_handlers),
]
self.handlers.extend(handlers)
diff --git a/pyprojects/secretnote/secretnote/sf/server/services/pages_handlers.py b/pyprojects/secretnote/secretnote/sf/server/services/pages_handlers.py
index 5a83a63b..c5e5dcbf 100644
--- a/pyprojects/secretnote/secretnote/sf/server/services/pages_handlers.py
+++ b/pyprojects/secretnote/secretnote/sf/server/services/pages_handlers.py
@@ -32,6 +32,21 @@ async def get(self, path: str = "/"):
self.write(self.render_template("index.html"))
+class ThisIsComputeNodeHintPageHandler(
+ ExtensionHandlerMixin,
+ ExtensionHandlerJinjaMixin,
+ FileFindHandler,
+):
+ @web.authenticated
+ async def get(self, *_):
+ """This handler is only activated when `--_as-compute-node` flag is set,
+ so as to hint the user is visiting the wrong SecretNote page holding
+ by the compute node instead of the SecretNote installed locally.
+ """
+ self.clear()
+ self.write(self.render_template("this-is-compute-node.html"))
+
+
pages_handlers: List[Tuple[str, Type[JupyterHandler], Dict]] = [
(
"/secretnote/(.*)",
@@ -39,3 +54,11 @@ async def get(self, path: str = "/"):
{"path": single_page_static_path},
),
]
+
+compute_node_pages_handlers: List[Tuple[str, Type[JupyterHandler], Dict]] = [
+ (
+ "/secretnote/(.*)",
+ ThisIsComputeNodeHintPageHandler,
+ {},
+ ),
+]
diff --git a/scripts/clean.js b/scripts/clean.js
index 22e40666..d62efb8b 100644
--- a/scripts/clean.js
+++ b/scripts/clean.js
@@ -23,6 +23,11 @@ const candidates = [
// Python projects
'./pyprojects/secretnote/.ipynb_checkpoints',
...distAndDep('./pyprojects/secretnote'),
+ './pyprojects/secretnote/secretnote/__pycache__',
+ './pyprojects/secretnote/secretnote/sf/www',
+ './pyprojects/secretnote/secretnote/scql/www',
+ './pyprojects/secretnote/secretnote/sf/__pycache__',
+ './pyprojects/secretnote/secretnote/scql/__pycache__',
].map((v) => path.join(workDir, v));
candidates.forEach((dir) => {
diff --git a/scripts/post-build-site.js b/scripts/post-build-site.js
index 2dde1e9d..5ebe3194 100644
--- a/scripts/post-build-site.js
+++ b/scripts/post-build-site.js
@@ -24,3 +24,11 @@ fs.rmSync(dst, {
fs.cpSync(src, dst, {
recursive: true,
});
+// copy the hint page for --_as-compute-node
+if (siteName === 'sf') {
+ const filename = 'this-is-compute-node.html';
+ fs.copyFileSync(
+ path.join(__dirname, `./${filename}`),
+ path.join(dst, `./${filename}`),
+ );
+}
diff --git a/scripts/this-is-compute-node.html b/scripts/this-is-compute-node.html
new file mode 100644
index 00000000..849c7e1a
--- /dev/null
+++ b/scripts/this-is-compute-node.html
@@ -0,0 +1,53 @@
+
+
+
+
+
+ 这是 SecretNote SF 的计算节点
+
+
+
+
+
👉 这是 SecretNote SF 的计算节点
+
+ 您正在直接访问计算节点上的 Jupyter
+ Server,这不符合预期。计算节点只用来承载计算任务,不用来编写程序。
+
+
+ 请使用本地的 SecretNote SF(通常在
+ http://localhost:8888
+ )在右上角添加计算节点(见
+ 文档),随后即可正常使用相关功能。
+
+
+
+