本文共 12854 字,大约阅读时间需要 42 分钟。
这篇文章整理一下因误操作删除了某个Tab的撤销和恢复的方法。
目录
环境准备
- Node-RED 以容器方式启动Node-RED服务,启动命令如下所示:
启动命令:docker run -it -p 1880:1880 -v $PWD/data:/data -e TZ=Asia/Shanghai --name nodered -d nodered/node-red:1.0.4
- 执行日志示例
liumiaocn:nodered liumiao$ docker run -it -p 1880:1880 -v $PWD/data:/data -e TZ=Asia/Shanghai --name nodered -d nodered/node-red:1.0.48286e234916a7dbd320d88c2dee7c1b6d119a9803ef6e633a7b0d3f1f6ab9993liumiaocn:nodered liumiao$ docker psCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES8286e234916a nodered/node-red:1.0.4 "npm start -- --user…" 27 seconds ago Up 27 seconds (health: starting) 0.0.0.0:1880->1880/tcp noderedliumiaocn:nodered liumiao$
事前准备:示例flow
创建如下的简单flow:
[ { "id": "ec475e12.7b432", "type": "inject", "z": "73554227.4474dc", "name": "", "topic": "", "payload": "", "payloadType": "date", "repeat": "", "crontab": "", "once": false, "onceDelay": 0.1, "x": 140, "y": 140, "wires": [ [ "99255b3e.062578" ] ] }, { "id": "f1bd528c.1175", "type": "debug", "z": "73554227.4474dc", "name": "", "active": true, "tosidebar": true, "console": false, "tostatus": false, "complete": "payload", "targetType": "msg", "x": 530, "y": 340, "wires": [] }, { "id": "99255b3e.062578", "type": "function", "z": "73554227.4474dc", "name": "时间转换", "func": "// 使用payload创建日期对象\nvar date = new Date(msg.payload);\n// 转换payload的时间格式\nmsg.payload = date.toString();\n// msg中的payload的格式已经转换\nreturn msg;", "outputs": 1, "noerr": 0, "x": 320, "y": 240, "wires": [ [ "f1bd528c.1175" ] ] }]
具体flow如下所示:
保存位置确认
上述json导入之后,执行deploy之后,保存的位置,如果是本文使用的官方镜像的话,保存文件为/data/flows.json:
/data $ pwd/data/data $ ls -larttotal 56drwxr-xr-x 1 root root 4096 Sep 1 19:00 ..-rw-r--r-- 1 node-red node-red 12478 Sep 1 19:00 settings.js-rw-r--r-- 1 node-red node-red 120 Sep 1 19:00 package.jsondrwxr-xr-x 3 node-red node-red 96 Sep 1 19:00 lib-rw-r--r-- 1 node-red node-red 9385 Sep 1 19:00 .config.json.backup-rw-r--r-- 1 node-red node-red 9633 Sep 1 19:34 .config.json-rw-r--r-- 1 node-red node-red 44 Sep 1 19:38 flows_cred.json-rw-r--r-- 1 node-red node-red 854 Sep 1 19:38 flows.jsondrwxr-xr-x 9 node-red node-red 288 Sep 1 19:38 ./data $ cat flows.json [{ "id":"439fcec6.28b5e","type":"tab","label":"Flow 1","disabled":false,"info":""},{ "id":"3b7a781d.61e6e8","type":"inject","z":"439fcec6.28b5e","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":180,"y":120,"wires":[["762e7a64.734334"]]},{ "id":"7ca09953.b7c7d8","type":"debug","z":"439fcec6.28b5e","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","x":570,"y":320,"wires":[]},{ "id":"762e7a64.734334","type":"function","z":"439fcec6.28b5e","name":"时间转换","func":"// 使用payload创建日期对象\nvar date = new Date(msg.payload);\n// 转换payload的时间格式\nmsg.payload = date.toString();\n// msg中的payload的格式已经转换\nreturn msg;","outputs":1,"noerr":0,"x":360,"y":220,"wires":[["7ca09953.b7c7d8"]]}]/data $ /data $
再创建一个Flow 2的tab,然后将Flow 1的内容拷贝过来,为了区分,这里将中间节点的名称修改为 时间转换2 ,其余均不变
然后再确认flows.json文件,发现其中已经包含了Flow 2的内容了。/data $ ls -lrttotal 28-rw-r--r-- 1 node-red node-red 12478 Sep 1 19:00 settings.js-rw-r--r-- 1 node-red node-red 120 Sep 1 19:00 package.jsondrwxr-xr-x 3 node-red node-red 96 Sep 1 19:00 lib-rw-r--r-- 1 node-red node-red 44 Sep 1 19:38 flows_cred.json-rw-r--r-- 1 node-red node-red 1709 Sep 1 19:43 flows.json/data $ cat flows.json [{ "id":"439fcec6.28b5e","type":"tab","label":"Flow 1","disabled":false,"info":""},{ "id":"bced581b.cdf098","type":"tab","label":"Flow 2","disabled":false,"info":""},{ "id":"3b7a781d.61e6e8","type":"inject","z":"439fcec6.28b5e","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":180,"y":120,"wires":[["762e7a64.734334"]]},{ "id":"7ca09953.b7c7d8","type":"debug","z":"439fcec6.28b5e","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","x":570,"y":320,"wires":[]},{ "id":"762e7a64.734334","type":"function","z":"439fcec6.28b5e","name":"时间转换","func":"// 使用payload创建日期对象\nvar date = new Date(msg.payload);\n// 转换payload的时间格式\nmsg.payload = date.toString();\n// msg中的payload的格式已经转换\nreturn msg;","outputs":1,"noerr":0,"x":360,"y":220,"wires":[["7ca09953.b7c7d8"]]},{ "id":"d33e6ccb.e1f4a","type":"inject","z":"bced581b.cdf098","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":160,"y":100,"wires":[["fb0063b7.9ff31"]]},{ "id":"f3f3669e.fb2ae8","type":"debug","z":"bced581b.cdf098","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","x":550,"y":300,"wires":[]},{ "id":"fb0063b7.9ff31","type":"function","z":"bced581b.cdf098","name":"时间转换2","func":"// 使用payload创建日期对象\nvar date = new Date(msg.payload);\n// 转换payload的时间格式\nmsg.payload = date.toString();\n// msg中的payload的格式已经转换\nreturn msg;","outputs":1,"noerr":0,"x":350,"y":200,"wires":[["f3f3669e.fb2ae8"]]}]/data $ /data $
试验1: 删除Flow 2但并不进行Deploy
此时确认一下flows.json,会发现和之前仍然一样/data $ ls -lrttotal 28-rw-r--r-- 1 node-red node-red 12478 Sep 1 19:00 settings.js-rw-r--r-- 1 node-red node-red 120 Sep 1 19:00 package.jsondrwxr-xr-x 3 node-red node-red 96 Sep 1 19:00 lib-rw-r--r-- 1 node-red node-red 44 Sep 1 19:38 flows_cred.json-rw-r--r-- 1 node-red node-red 1709 Sep 1 19:43 flows.json/data $
实际上会有一个备份文件,此处为.flows.json.backup , 可以看到,此文件目前正是我们添加Flow 2之前的内容。
/data $ ls -larttotal 60drwxr-xr-x 1 root root 4096 Sep 1 19:00 ..-rw-r--r-- 1 node-red node-red 12478 Sep 1 19:00 settings.js-rw-r--r-- 1 node-red node-red 120 Sep 1 19:00 package.jsondrwxr-xr-x 3 node-red node-red 96 Sep 1 19:00 lib-rw-r--r-- 1 node-red node-red 9385 Sep 1 19:00 .config.json.backup-rw-r--r-- 1 node-red node-red 9633 Sep 1 19:34 .config.json-rw-r--r-- 1 node-red node-red 44 Sep 1 19:38 flows_cred.json-rw-r--r-- 1 node-red node-red 854 Sep 1 19:38 .flows.json.backup-rw-r--r-- 1 node-red node-red 1709 Sep 1 19:43 flows.jsondrwxr-xr-x 10 node-red node-red 320 Sep 1 19:43 ./data $ diff flows.json .flows.json.backup --- flows.json+++ .flows.json.backup@@ -1 +1 @@-[{ "id":"439fcec6.28b5e","type":"tab","label":"Flow 1","disabled":false,"info":""},{ "id":"bced581b.cdf098","type":"tab","label":"Flow 2","disabled":false,"info":""},{ "id":"3b7a781d.61e6e8","type":"inject","z":"439fcec6.28b5e","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":180,"y":120,"wires":[["762e7a64.734334"]]},{ "id":"7ca09953.b7c7d8","type":"debug","z":"439fcec6.28b5e","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","x":570,"y":320,"wires":[]},{ "id":"762e7a64.734334","type":"function","z":"439fcec6.28b5e","name":"时间转换","func":"// 使用payload创建日期对象\nvar date = new Date(msg.payload);\n// 转换payload的时间格式\nmsg.payload = date.toString();\n// msg中的payload的格式已经转换\nreturn msg;","outputs":1,"noerr":0,"x":360,"y":220,"wires":[["7ca09953.b7c7d8"]]},{ "id":"d33e6ccb.e1f4a","type":"inject","z":"bced581b.cdf098","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":160,"y":100,"wires":[["fb0063b7.9ff31"]]},{ "id":"f3f3669e.fb2ae8","type":"debug","z":"bced581b.cdf098","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","x":550,"y":300,"wires":[]},{ "id":"fb0063b7.9ff31","type":"function","z":"bced581b.cdf098","name":"时间转换2","func":"// 使用payload创建日期对象\nvar date = new Date(msg.payload);\n// 转换payload的时间格式\nmsg.payload = date.toString();\n// msg中的payload的格式已经转换\nreturn msg;","outputs":1,"noerr":0,"x":350,"y":200,"wires":[["f3f3669e.fb2ae8"]]}]\ No newline at end of file+[{ "id":"439fcec6.28b5e","type":"tab","label":"Flow 1","disabled":false,"info":""},{ "id":"3b7a781d.61e6e8","type":"inject","z":"439fcec6.28b5e","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":180,"y":120,"wires":[["762e7a64.734334"]]},{ "id":"7ca09953.b7c7d8","type":"debug","z":"439fcec6.28b5e","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","x":570,"y":320,"wires":[]},{ "id":"762e7a64.734334","type":"function","z":"439fcec6.28b5e","name":"时间转换","func":"// 使用payload创建日期对象\nvar date = new Date(msg.payload);\n// 转换payload的时间格式\nmsg.payload = date.toString();\n// msg中的payload的格式已经转换\nreturn msg;","outputs":1,"noerr":0,"x":360,"y":220,"wires":[["7ca09953.b7c7d8"]]}]\ No newline at end of file/data $
此种场景下的恢复方法:Ctrl + Z即可恢复
试验2: 删除Flow 2同时进行Deploy
- 删除和Deploy之前
/data $ ls -larttotal 60drwxr-xr-x 1 root root 4096 Sep 1 19:00 ..-rw-r--r-- 1 node-red node-red 12478 Sep 1 19:00 settings.js-rw-r--r-- 1 node-red node-red 120 Sep 1 19:00 package.jsondrwxr-xr-x 3 node-red node-red 96 Sep 1 19:00 lib-rw-r--r-- 1 node-red node-red 9385 Sep 1 19:00 .config.json.backup-rw-r--r-- 1 node-red node-red 9633 Sep 1 19:34 .config.json-rw-r--r-- 1 node-red node-red 44 Sep 1 19:38 flows_cred.json-rw-r--r-- 1 node-red node-red 854 Sep 1 19:38 .flows.json.backup-rw-r--r-- 1 node-red node-red 1709 Sep 1 19:43 flows.jsondrwxr-xr-x 10 node-red node-red 320 Sep 1 19:43 ./data $
- 删除并部署
- 确认结果: 可以看到.flows.json.backup的内容正是之前的内容
/data $ ls -larttotal 60drwxr-xr-x 1 root root 4096 Sep 1 19:00 ..-rw-r--r-- 1 node-red node-red 12478 Sep 1 19:00 settings.js-rw-r--r-- 1 node-red node-red 120 Sep 1 19:00 package.jsondrwxr-xr-x 3 node-red node-red 96 Sep 1 19:00 lib-rw-r--r-- 1 node-red node-red 9385 Sep 1 19:00 .config.json.backup-rw-r--r-- 1 node-red node-red 9633 Sep 1 19:34 .config.json-rw-r--r-- 1 node-red node-red 44 Sep 1 19:38 flows_cred.json-rw-r--r-- 1 node-red node-red 1709 Sep 1 19:43 .flows.json.backup-rw-r--r-- 1 node-red node-red 854 Sep 1 20:02 flows.jsondrwxr-xr-x 10 node-red node-red 320 Sep 1 20:02 ./data $
我们这里首先将其备份一下,改一个名字
/data $ cp -p .flows.json.backup flows.backup/data $ ls -larttotal 64drwxr-xr-x 1 root root 4096 Sep 1 19:00 ..-rw-r--r-- 1 node-red node-red 12478 Sep 1 19:00 settings.js-rw-r--r-- 1 node-red node-red 120 Sep 1 19:00 package.jsondrwxr-xr-x 3 node-red node-red 96 Sep 1 19:00 lib-rw-r--r-- 1 node-red node-red 9385 Sep 1 19:00 .config.json.backup-rw-r--r-- 1 node-red node-red 9633 Sep 1 19:34 .config.json-rw-r--r-- 1 node-red node-red 44 Sep 1 19:38 flows_cred.json-rw-r--r-- 1 node-red node-red 1709 Sep 1 19:43 flows.backup-rw-r--r-- 1 node-red node-red 1709 Sep 1 19:43 .flows.json.backup-rw-r--r-- 1 node-red node-red 854 Sep 1 20:02 flows.jsondrwxr-xr-x 11 node-red node-red 352 Sep 1 20:04 ./data $
随便移动一点Flow 1中的某个节点,然后Deploy,然后再确认结果,发现.flows.json.backup又一次更新了,如果没有之前备份的文件flows.backup,我们就找不回来了,也就是说,即使Deploy,还是有一次恢复的机会的,但是连续Deploy的话,就找不回来了。换句话说,只能找回最近一次Deploy前的内容。
/data $ ls -larttotal 64drwxr-xr-x 1 root root 4096 Sep 1 19:00 ..-rw-r--r-- 1 node-red node-red 12478 Sep 1 19:00 settings.js-rw-r--r-- 1 node-red node-red 120 Sep 1 19:00 package.jsondrwxr-xr-x 3 node-red node-red 96 Sep 1 19:00 lib-rw-r--r-- 1 node-red node-red 9385 Sep 1 19:00 .config.json.backup-rw-r--r-- 1 node-red node-red 9633 Sep 1 19:34 .config.json-rw-r--r-- 1 node-red node-red 44 Sep 1 19:38 flows_cred.json-rw-r--r-- 1 node-red node-red 1709 Sep 1 19:43 flows.backup-rw-r--r-- 1 node-red node-red 854 Sep 1 20:02 .flows.json.backup-rw-r--r-- 1 node-red node-red 854 Sep 1 20:04 flows.jsondrwxr-xr-x 11 node-red node-red 352 Sep 1 20:04 ./data $
总结
简单总结如下:没有Deploy,直接Ctrl + z即可撤销。如果已经Deploy,可在隐藏的备份文件.flows.json.backup中找回。如果Deploy了2次或者以上,就无力回天了。
转载地址:https://liumiaocn.blog.csdn.net/article/details/108347779 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!