DELETE Folder operation for FTP Node

Right now we can delete only files. It would be really awesome if we have an option to delete whole folder.

When I set the Path to folder I’m getting this error.

ERROR: delete->delete: Bad path: /home/tempfolder/ must be a regular file

You can achieve that using the list and delete operation right now.

1 Like

That’s cool. Let me try.

Same error bro.

These List Returned by First FTP Node

Seems there are multiple folder present (Not Files) I hooked SplitInBatches Node. But getting same error. Because it’s Folder.


Here is my Workflow

{
  "nodes": [
    {
      "parameters": {},
      "name": "Start",
      "type": "n8n-nodes-base.start",
      "typeVersion": 1,
      "position": [
        510,
        380
      ]
    },
    {
      "parameters": {
        "protocol": "sftp",
        "operation": "list",
        "path": "/etc/nginx/cache/apiapp"
      },
      "name": "FTP",
      "type": "n8n-nodes-base.ftp",
      "typeVersion": 1,
      "position": [
        680,
        380
      ],
      "credentials": {
        "sftp": "Singapore DB Server for Backup"
      }
    },
    {
      "parameters": {
        "protocol": "sftp",
        "operation": "delete",
        "path": "={{$node[\"SplitInBatches\"].json[\"name\"]}}"
      },
      "name": "FTP1",
      "type": "n8n-nodes-base.ftp",
      "typeVersion": 1,
      "position": [
        1040,
        520
      ],
      "credentials": {
        "sftp": "Singapore DB Server for Backup"
      }
    },
    {
      "parameters": {
        "batchSize": 1,
        "options": {}
      },
      "name": "SplitInBatches",
      "type": "n8n-nodes-base.splitInBatches",
      "typeVersion": 1,
      "position": [
        880,
        380
      ]
    }
  ],
  "connections": {
    "Start": {
      "main": [
        [
          {
            "node": "FTP",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "FTP": {
      "main": [
        [
          {
            "node": "SplitInBatches",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "FTP1": {
      "main": [
        [
          {
            "node": "SplitInBatches",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "SplitInBatches": {
      "main": [
        [
          {
            "node": "FTP1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}

You do not need the splitbaches nodes. The node will automatically iterate. Just filter out the ones with type d. I guess forgot to mention that the down side it’s the folder will still be there but all the files inside will be removed.

Getting this error bro.

ERROR: delete->delete: Bad path: d cannot determine parent directory
Error: delete->delete: Bad path: d cannot determine parent directory
    at Object.formatError (/usr/local/lib/node_modules/n8n/node_modules/ssh2-sftp-client/src/utils.js:62:18)
    at SftpClient.delete (/usr/local/lib/node_modules/n8n/node_modules/ssh2-sftp-client/src/index.js:1021:19)
    at processTicksAndRejections (internal/process/task_queues.js:93:5)
    at async Object.execute (/usr/local/lib/node_modules/n8n/node_modules/n8n-nodes-base/dist/nodes/Ftp.node.js:345:36)
    at async /usr/local/lib/node_modules/n8n/node_modules/n8n-core/dist/src/WorkflowExecute.js:416:47

Update:

I tried creating a file. It deletes… But If I specify that file’s parent directory. It’s showing this error.

ERROR: delete->delete: Bad path: /root/temppp/hello/ must be a regular file

Why is it the path resolving to d? is d the name of the folder you want to delete?

1 Like

Let me explain

I want to delete everything inside /etc/ngnix/cache/apiapp/

Since it’s a cache folder, The problem is, the above mentioned path only contains folders with no files in it.

Via SSH, I usually do rm -rf /etc/ngnix/cache/apiapp/*

It’ll remove all the folders inside the apiapp directory.

This is what I’m trying to achieve.

Ok, I see. You can list with the parameter recursive set to true, as shown in the image below. Then, filter out all the records where type is equal to -. To finally, delete those with the delete operation. The downside, as I mentioned before, it will delete just the files, and the folder will stay (empty)

No bro. Can I delete the Whole Directory just not files?

As you can see in the below screenshot. The path /etc/nginx/cache/apiapp/ contains multiple sub folders which recursively contains folder inside the folder.

I want to delete all the folders (including files) from inside this path /etc/nginx/cache/apiapp/

basically this is what I want to perform. rm -rf /etc/nginx/cache/apiapp/*

image

@mcnaveen
Another (slightly less straight-forward) way is to use an external nodejs module.
I also required extensive SFTP/FTP functionality, so started using this module, ‘ssh2-sftp-client’ (Github), within a function node.

Example:

{
  "nodes": [
    {
      "parameters": {
        "keepOnlySet": true,
        "values": {
          "string": [
            {
              "name": "base_path",
              "value": "base_path"
            },
            {
              "name": "config.host",
              "value": "host"
            },
            {
              "name": "config.username",
              "value": "username"
            },
            {
              "name": "config.password",
              "value": "password"
            }
          ],
          "number": [
            {
              "name": "config.port",
              "value": 22
            }
          ]
        },
        "options": {
          "dotNotation": true
        }
      },
      "name": "FTP config",
      "type": "n8n-nodes-base.set",
      "typeVersion": 1,
      "position": [
        711,
        314
      ]
    },
    {
      "parameters": {
        "functionCode": "////////////////////////////////////////////////////////\nconst Client = require('ssh2-sftp-client');\nconst sftp = new Client();\n\nconst config = $node[\"FTP config\"].json[\"config\"];\nconst base_path = $node[\"FTP config\"].json[\"base_path\"];\n\n//// Open SFTP connection\nconst connection = await sftp.connect(config);\n\n//////////////////////////////////////////////////////\n///////////////   Helper Functions   /////////////////\n//////////////////////////////////////////////////////\n\nconst path_check = async function(path){\n  let path_exists = await sftp.exists(path);\n  if(path_exists) return !!path_exists;\n  return false;\n}\nconst folder_create = async function(path){\n  let res = await sftp.mkdir(path);\n  let res1 = await sftp.chmod(path,'0775');\n  return {res,res1};\n}\nconst file_upload = async function(data,path){\n  let res = await sftp.put(data,path,{mode:'0775'});\n  return res;\n}\nconst folder_delete = async function(path){\n  let res = await sftp.rmdir(path,true);\n  return res;\n}\nconst file_delete = async function(){\n  let res = await sftp.delete(path);\n  return res;\n}\n//////////////////////////////////////////////////////\n////////////////    Main Code     ///////////////////\n//////////////////////////////////////////////////////\n\nlet folder_path;\nlet list = await sftp.list(`${base_path}`);\nlet res = await folder_create(`${base_path}/${folder_path}`);\n\n//////////////////////////////////////////////////////\n\n//// Close SFTP connection\nawait sftp.end();\n\nreturn [{json:{res,list}}];"
      },
      "name": "Function",
      "type": "n8n-nodes-base.function",
      "typeVersion": 1,
      "position": [
        871,
        314
      ]
    }
  ],
  "connections": {
    "FTP config": {
      "main": [
        [
          {
            "node": "Function",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
1 Like

That’s great. Let me try this.

I wish to have a built-in functionality inside the node. :unamused:

Ah, funny that you mention that because that is the same library that the FTP node uses.

1 Like

So. I can go ahead just with function node as @shrey-42 mentioned above.

Without needing those options?

Yes, as shown in the example @shrey-42 shared, you can use specifically the rmdir method.

1 Like

Hey @RicardoE105 bro.

I’m getting this error

ERROR: Access denied to require 'ssh2-sftp-client'
VMError: Access denied to require 'ssh2-sftp-client'
    at _require (/usr/local/lib/node_modules/n8n/node_modules/vm2/lib/sandbox.js:303:28)
    at /usr/local/lib/node_modules/n8n/node_modules/n8n-nodes-base/dist/nodes:1:113
    at Object.<anonymous> (/usr/local/lib/node_modules/n8n/node_modules/n8n-nodes-base/dist/nodes:36:29)
    at NodeVM.run (/usr/local/lib/node_modules/n8n/node_modules/vm2/lib/main.js:1121:29)
    at Object.execute (/usr/local/lib/node_modules/n8n/node_modules/n8n-nodes-base/dist/nodes/Function.node.js:65:31)
    at Workflow.runNode (/usr/local/lib/node_modules/n8n/node_modules/n8n-workflow/dist/src/Workflow.js:492:37)
    at /usr/local/lib/node_modules/n8n/node_modules/n8n-core/dist/src/WorkflowExecute.js:416:62

Can you Implement this Functionality inside FTP Node? It’ll make the work much more easier and straight forward. Please add it to your To-do list.

Thank you.

Yeah, that is expected. By default you cannot require packages in the function node. if you want to do so you need to enable that via env variables. Check the link below.

1 Like

Awesome. It Perfectly works :heart:

Thanks @RicardoE105 bro & @shrey-42 bro

@shrey-42 @mcnaveen got added. Can you please test it locally and confirm that it works?

1 Like

Got released with [email protected]

1 Like