mkloubert/vscode-deploy-reloaded

Allow write like as specific user/permission

AdsonCicilioti opened this issue · 5 comments

Description

I know I can, set chmod on the remote server to allow write via ftp / sftp. but my designs are in production whose permissions are safe. And since I always foresee making changes to the files, I would like to know if there is an option or argument to pass a command that enables writing during deploy.

In the vs-deploy extension I used the connected arguments that allow to pass commands on the remote server, so I would pass something like sudo chmod 775 enabling writing before of sending the files, and then returned to normal by the uploaded argument.

Actual behavior

I do not find an option or form to allow deploy writing on projects that are in production.

Expected behavior

I need suggestions that do not include manually changing the permissions of the remote directory.

My environment

  • Operating system: Windows 10 Pro
  • Visual Studio Code version: 1.20.0
  • Extension version: 0.53.3

Additional comments

My remote environment is a Virtual Machine on Google Cloud Engine with this specs:
OS: Ubuntu Server 16.04.4
WebServer: Nginx (custom-build), HHVM (PHP 7.1), MariaDB
Web Root Directories: /var/www/
Web Root Permissions: Directories => chmod 755, Files => chmod 644, chown www-data

@AdsonCicilioti

I released a new version 0.65.0, which is now able to define logic for "upload events" in SFTP and FTP targets.

For that, you can define scripts, which can use the underlying raw connection to do anything you want.

In your case (if you use SFTP):

First setup your target:

{
    "deploy.reloaded": {
        "targets": [
            {
                "type": "sftp",
                "name": "My SFTP folder",

                "uploaded": "./uploadedToSFTP.js",
                "uploadedOptions": 23979
            }
        ]
    }
}

Create a file, called uploadedToSFTP.js, inside your .vscode folder or .vscode-deploy-reloaded subfolder inside your home directory:

// s. https://nodejs.org/api/path.html
const Path = require('path');
// s. https://code.visualstudio.com/docs/extensionAPI/vscode-api
const vscode = require('vscode');

// script entry
// for 'args', s. https://mkloubert.github.io/vscode-deploy-reloaded/interfaces/_plugins_sftp_.sftpuploadedmoduleexecutorarguments.html
exports.execute = async function(args) {
    if (args.context.error) {
        return;  // rethrow error
    }

    // s. https://github.com/jyu213/ssh2-sftp-client
    const CONN = args.context.connection;

    const DIR = Path.dirname( args.context.file );
    if ('/' !== DIR) {  // only if not root
        await setMode(CONN, DIR, '755');  // mode for directory
    }    

    await setMode(CONN, args.context.file, '644');  // mode for file
};

// execute 'chmod' for a file
function setMode(conn, path, mode) {
    mode = parseInt(mode, 8);

    return new Promise((resolve, reject) => {
        try {
            conn.sftp.chmod(path, mode, (err) => {
                if (err) {
                    reject(err);
                }
                else {
                    resolve();
                }
            });
        } catch (e) {
            reject(e);
        }
    });
}

For FTP targets, this is quite similar.

You only need to replace the part

            conn.sftp.chmod(path, mode, (err) => {
            });

with code of the API, that is provided by ftp or jsftp modules.

This depends on what you have defined in the engine setting of the underlying target.

@AdsonCicilioti

Btw.: If you want to execute a command on a SFTP server, you can try this:

function executeCommand(conn, commandToExecute) {
    return new Promise((resolve, reject) => {
        try {
            conn.client.exec(commandToExecute, (err, stream) => {
                if (err) {
                    reject( err );
                    return;
                }

                let output = Buffer.alloc(0);

                stream.once('error', (streamErr) => {
                    reject( streamErr );
                });

                stream.once('end', () => {
                    resolve( output );
                });

                stream.on('data', (chunk) => {
                    if (chunk) {
                        output = Buffer.concat([ output, chunk ]);
                    }
                });
            });
        } catch (e) {
            reject(e);
        }
    });
}

@AdsonCicilioti

I have reimplemented command feature from vs-deploy in version 0.66.1 for SFTP and FTP targets.

NicE!
Sounds good!

I have not had time to test yet. But I must do so soon. I come back with my observations. But I trust it will work well!

Thanks @mkloubert !

Hey @mkloubert !

Any exemples or Wiki doscs for this exemple?