Skip to content

Latest commit

 

History

History
398 lines (286 loc) · 9.35 KB

programmatic-access-local.md

File metadata and controls

398 lines (286 loc) · 9.35 KB

Help

  1. Starting and stopping processes
  2. Controlling the Daemon
  3. Managing clusters
  4. Installing and running apps
  5. Remote access and monitoring (e.g. guv-web)
  6. Web interface
  7. Web interface - configuration
  8. Web interface - user management
  9. Programmatic access
  10. Programmatic access - local
  11. Programmatic access - remote
  12. Programmatic access - events

Programmatic access - local

A interface to an instance of guvnor running on the same host.

Usage

var Local = require('guvnor').Local

All methods take an optional config argument and an optional logger argument.

config

The config argument is a plain object of config settings as loaded from the config file. If omitted, the default config file will be loaded and it's properties overwritten by the config file at /etc/guvnor/guvnor if available.

logger

If specified the logger argument must have the following structure:

{
  info: function() {},
  warn: function() {},
  error: function() {},
  debug: function() {}
}

If omitted it defaults to console.info and friends with debug being a no-op.

Local.running([config], [logger], callback(running))

The passed callback will receive a boolean value indicating if the daemon is running or not.

Local.running(function(running) {
  console.info('Daemon is', running ? 'running' : 'not running')
})

Local.connect([config], [logger], callback(error, daemon))

Attempts to connect to an already running daemon. If the daemon is not running the callback will receive an error.

Local.connect(function(error, daemon) {
  if(error) {
    if(error.code == 'DAEMON_NOT_RUNNING') {
      // .. no daemon was running on this machine
    } else {
      throw error
    }
  }

  daemon.listProcesses(function(error, processes) {
    // ...
    
    daemon.disconnect(function (error) {
      // ...
    })
  })
})

Local.connectOrStart([config], [logger], callback(error, daemon))

Attempts to connect to an already running daemon. If the daemon is not running it will attempt to start the daemon.

If this fails for any reason, the callback will receive an error.

Since the daemon can only be started as root, code calling this method will need to be run as root.

To connect with a non-privileged user, use Local.connect instead.

Local.connectOrStart(function(error, daemon) {
  if(error) throw error

  daemon.listProcesses(function(error, processes) {
    // ...
    
    daemon.disconnect(function (error) {
      // ...
    })
  })
})

Daemon methods

The daemon argument passed to Local.connect and Local.connectOrStart has the following methods:

disconnect(callback(error))

Disconnect from the local daemon

daemon.disconnect(function(error) {
  // all sockets should be closed and the process should be able to exit cleanly
})

listProcesses(callback(error, processes))

Get a list of processes.

daemon.listProcesses(function(error, processes) {
  // processes is an array of processInfo objects
})

startProcess(pathOrName, options, callback(error, processInfo))

Start a process. Pass either the path to a script, the name of a stopped process or installed app.

daemon.startProcess(pathOrName, options, function(error, processInfo) {
  // processInfo.id is the process id of the newly started process

  daemon.on('process:ready', function(error, readyProcessInfo) {
    if(processInfo.id == readyProcessInfo.id) {
      // process has now started
    }
  })
})

stopProcess(id, callback(error))

Stop a process. N.b. This method is for killing processes that have not started up properly - e.g. if it's status never gets beyond starting. Otherwise you should use the kill method on it's RPC service instead.

daemon.findProcessInfoByName(name, function(error, processInfo) {
  daemon.kill(processInfo.id, function(error) {
    // process has now been killed, if it has not finished starting,
    // otherwise `error` will be set - instead use processInfo.kill()
  })
})

### removeProcess(id, function(error)

Remove a stopped process

// id is processInfo.id
daemon.removeProcess(id, function(error) {

})

Find ProcessInfo by id

Every managed process is assigned an id. This id is stable even if the process is restarted.

// id is processInfo.id
daemon.findProcessInfoById(id, function(error, processInfo) {
  // processInfo is undefined if no process with that id existed
})

Find ProcessInfo by pid

The pid of a managed process is assigned by the operating system and will change when the process is restarted.

// pid is the pid of a managed process
daemon.findProcessInfoByPid(pid, function(error, processInfo) {
  // processInfo is undefined if no process with that pid existed
})

Find ProcessInfo by name

The name of the process is either specified by the -n argument, it's the name of the script or it's the name field of an adjacent package.json file.

// pid is the pid of a managed process
daemon.findProcessInfoByName(name, function(error, processInfo) {
  // processInfo is undefined if no process with that name existed
})

deployApplication(name, url, user, onOut, onErr, callback)

daemon.deployApplication(name, url, user, console.info, console.error, function(error, appInfo) {
  // ...
})

List applications

daemon.listApplications

List applications refs

daemon.listApplicationRefs

Current applications ref

Calls the passed callback with the app's current ref name and commit id.

daemon.currentRef(appName, function (error, refName, commitHash) {
 // ...
})

Switch applications refs

daemon.switchApplicationRefs

Update applications refs

daemon.updateApplicationRefs

Remove application

daemon.removeApplication

Admin methods

If you are connected as a privileged user (e.g. root or the user that guvnor is configured to run as), you will have these additional methods available.

Dump processes

daemon.dumpProcesses

Restore processes

daemon.restoreProcesses

Generate remote RPC certificates

daemon.generateRemoteRpcCertificates

kill

daemon.kill

Remote host config

daemon.remoteHostConfig

Add remote user

daemon.addRemoteUser

Remove remote user

daemon.removeRemoteUser

List remote users

daemon.listRemoteUsers

Rotate remote user keys

daemon.rotateRemoteUserKeys

Start process as user

daemon.startProcessAsUser

Process methods

### kill(callback(error))

To stop a process, first connect to the daemon, then use the daemon to connect to the process and kill it.

// id is processInfo.id. Alternatively use findProcessInfoByName or findProcessInfoByPid
daemon.findProcessInfoById(id, function(error, managedProcess) {
  managedProcess.kill()
  managedProcess.disconnect()
})

### Send a process an event

Causes the global process object to emit an event in the managed process.

// id is processInfo.id. Alternatively use findProcessInfoByName or findProcessInfoByPid
daemon.findProcessInfoById(id, function(error, managedProcess) {
  managedProcess.send('custom:event', 'arg1', 'arg2')
  managedProcess.disconnect()
})

In the managed process:

process.on('custom:event', function(arg1, arg2) {
  console.info('received my custom event type with args', arg1, ar2)
})

Functions can be sent too (but note these are executed in the context of the sender, not the receiving process).

// id is processInfo.id. Alternatively use findProcessInfoByName or findProcessInfoByPid
daemon.findProcessInfoById(id, function(error, managedProcess) {
  managedProcess.send('other:event', function(message) {
    console.info('remote process said', message)
    managedProcess.disconnect()
  })
})

In the managed process:

process.on('other:event', function(callback) {
  callback('hello world')
})

### Send a process a signal

// id is processInfo.id. Alternatively use findProcessInfoByName or findProcessInfoByPid
daemon.findProcessInfoById(id, function(error, managedProcess) {
  managedProcess.signal('SIGHUP', managedProcess.disconnect.bind(managedProcess))
})

In the managed process:

process.on('SIGHUP', function() {
  // do something
});

### Write to stdin for a process

// id is processInfo.id. Alternatively use findProcessInfoByName or findProcessInfoByPid
daemon.findProcessInfoById(id, function(error, managedProcess) {
  managedProcess.write('hello', managedProcess.disconnect.bind(managedProcess))
})

In the managed process:

process.stdin.on('data', function(buffer) {
  // do something with buffer
});