XO-Server can now drop priviledges.
This commit is contained in:
parent
ad5e68091f
commit
774b4051bc
@ -1,5 +1,35 @@
|
||||
# Note: Relative paths will be resolved from XO-Server's directory.
|
||||
|
||||
#=====================================================================
|
||||
|
||||
# It may be necessary to run XO-Server as a priviledged user (e.g.
|
||||
# `root`) for instance to allow the HTTP server to listen on a
|
||||
# [priviledged ports](http://www.w3.org/Daemon/User/Installation/PrivilegedPorts.html).
|
||||
#
|
||||
# To avoid security issues, XO-Server can drop its priviledges by
|
||||
# changing the user and the group is running with.
|
||||
#
|
||||
# Note: XO-Server will change them just after reading the
|
||||
# configuration.
|
||||
|
||||
# User to run XO-Server as.
|
||||
#
|
||||
# Note: The user can be specified using either its name or its numeric
|
||||
# identifier.
|
||||
#
|
||||
# Default: undefined
|
||||
#user: 'nobody'
|
||||
|
||||
# Group to run XO-Server as.
|
||||
#
|
||||
# Note: The group can be specified using either its name or its
|
||||
# numeric identifier.
|
||||
#
|
||||
# Default: undefined
|
||||
#group: 'nogroup'
|
||||
|
||||
#=====================================================================
|
||||
|
||||
# Configuration of the embedded HTTP server.
|
||||
http:
|
||||
|
||||
@ -52,6 +82,8 @@ http:
|
||||
mounts:
|
||||
#'/': '/path/to/xo-web/dist/'
|
||||
|
||||
#=====================================================================
|
||||
|
||||
# Connection to the Redis server.
|
||||
redis:
|
||||
# Syntax: tcp://[db[:password]@]hostname[:port]
|
||||
|
@ -21,7 +21,8 @@ $sleep = (ms) ->
|
||||
setTimeout (-> fiber.run()), ms
|
||||
$fiber.yield()
|
||||
|
||||
# Makes an asynchrouneous function synchrouneous (in a fiber).
|
||||
# Makes an Node like asynchrouneous function synchrouneous (in a
|
||||
# fiber).
|
||||
$synchronize = (fn, ctx) ->
|
||||
fn = ctx[fn] if $_.isString fn
|
||||
|
||||
@ -33,22 +34,46 @@ $synchronize = (fn, ctx) ->
|
||||
fiber.throwInto error
|
||||
else
|
||||
fiber.run result
|
||||
result = fn.apply ctx, args
|
||||
|
||||
# A promise can only be detected once the function has been
|
||||
# called.
|
||||
if $isPromise result
|
||||
result.then(
|
||||
(result) -> fiber.run result
|
||||
(error) -> fiber.throwInto error
|
||||
)
|
||||
fn.apply ctx, args
|
||||
|
||||
$fiber.yield()
|
||||
|
||||
# Waits for an event.
|
||||
#
|
||||
# Note: if the *error* event is emitted, this function will throw.
|
||||
$waitEvent = (emitter, event) ->
|
||||
fiber = $fiber.current
|
||||
|
||||
errorHandler = null
|
||||
handler = (args...) ->
|
||||
emitter.removeListener 'error', errorHandler
|
||||
fiber.run args
|
||||
errorHandler = (error) ->
|
||||
emitter.removeListener event, handler
|
||||
fiber.throwInto error
|
||||
|
||||
emitter.once event, handler
|
||||
emitter.once 'error', errorHandler
|
||||
|
||||
$fiber.yield()
|
||||
|
||||
# Waits for a promise to be fulfilled or broken.
|
||||
$waitPromise = (promise) ->
|
||||
fiber = $fiber.current
|
||||
|
||||
promise.then(
|
||||
(result) -> fiber.run result
|
||||
(error) -> fiber.throwInto error
|
||||
)
|
||||
|
||||
$fiber.yield()
|
||||
|
||||
#=====================================================================
|
||||
|
||||
module.exports = {
|
||||
$fiberize
|
||||
$sleep
|
||||
$synchronize
|
||||
$waitEvent
|
||||
$waitPromise
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ $Session = require './session'
|
||||
$XO = require './xo'
|
||||
|
||||
# Helpers for dealing with fibers.
|
||||
{$fiberize, $synchronize} = require './fibers-utils'
|
||||
{$fiberize, $synchronize, $waitEvent} = require './fibers-utils'
|
||||
|
||||
# HTTP/HTTPS server which can listen on multiple ports.
|
||||
$WebServer = require './web-server'
|
||||
@ -112,6 +112,20 @@ do $fiberize ->
|
||||
if $nconf.get entry
|
||||
console.warn "[Warn] `#{entry}` configuration is deprecated."
|
||||
|
||||
# Creates the web server according to the configuration.
|
||||
webServer = new $WebServer()
|
||||
webServer.listen options for options in $nconf.get 'http:listen'
|
||||
|
||||
# Waits for the web server to start listening to drop priviledges.
|
||||
$waitEvent webServer, 'listening'
|
||||
try
|
||||
if (group = $nconf.get 'group')?
|
||||
process.setgid group
|
||||
if (user = $nconf.get 'user')?
|
||||
process.setuid user
|
||||
catch error
|
||||
console.warn "[WARN] Failed to change the user or group: #{error.message}"
|
||||
|
||||
# Creates the main object which will connects to Xen servers and
|
||||
# manages all the models.
|
||||
xo = new $XO()
|
||||
@ -123,10 +137,6 @@ do $fiberize ->
|
||||
}
|
||||
}
|
||||
|
||||
# Creates the web server according to the configuration.
|
||||
webServer = new $WebServer()
|
||||
webServer.listen options for options in $nconf.get 'http:listen'
|
||||
|
||||
# Static file serving (e.g. for XO-Web).
|
||||
connect = $connect()
|
||||
for urlPath, filePaths of $nconf.get 'http:mounts'
|
||||
|
@ -42,6 +42,7 @@ class $WebServer extends $EventEmitter
|
||||
|
||||
constructor: ->
|
||||
@_servers = []
|
||||
@_notYetListening = 0
|
||||
|
||||
close: ->
|
||||
server.close() for server in @_servers
|
||||
@ -65,8 +66,10 @@ class $WebServer extends $EventEmitter
|
||||
else
|
||||
server.listen port, host
|
||||
|
||||
++@_notYetListening
|
||||
|
||||
# Helpful message.
|
||||
server.once 'listening', ->
|
||||
server.once 'listening', =>
|
||||
address = server.address()
|
||||
if $_.isObject address
|
||||
{address, port} = address
|
||||
@ -74,6 +77,10 @@ class $WebServer extends $EventEmitter
|
||||
|
||||
console.log "WebServer listening on #{address}"
|
||||
|
||||
# If the web server is listening on all addresses, fire the
|
||||
# `listening` event.
|
||||
@emit 'listening' unless --@_notYetListening
|
||||
|
||||
# Forwards events to this object.
|
||||
$_.each $events, (event) =>
|
||||
server.on event, (args...) => @emit event, args...
|
||||
|
@ -28,7 +28,7 @@ $Model = require './model'
|
||||
$XAPI = require './xapi'
|
||||
|
||||
# Helpers for dealing with fibers.
|
||||
{$fiberize, $synchronize} = require './fibers-utils'
|
||||
{$fiberize, $synchronize, $waitPromise} = require './fibers-utils'
|
||||
|
||||
#=====================================================================
|
||||
|
||||
@ -266,8 +266,7 @@ class $XO
|
||||
throw error unless error[0] is 'SESSION_NOT_REGISTERED'
|
||||
|
||||
# Connects to existing servers.
|
||||
getServers = $synchronize 'get', @servers
|
||||
connect server for server in getServers()
|
||||
connect server for server in $waitPromise @servers.get()
|
||||
|
||||
# Automatically connects to new servers.
|
||||
@servers.on 'add', (servers) ->
|
||||
|
Loading…
Reference in New Issue
Block a user