# entourage-server

Server for environment bootstrapping

See repository page chriskalmar/entourage for more information.

# Profiles

Create a profiles folder that will be shared with docker container.

# Profile template

At the root of profiles, create a yml | yaml template like demo-profile.yaml. You can use defaults->params to declare default params that will be used to fill out template files declared in renderTemplates.

Still at the root, create a folder that will contain your templates (sourcePath) and another one called demo-profile that will contain the files rendered (targetPath).

These templates will be parsed and variables will be replaced by your default params and those that will be passed to entourage-server API.

.
+-- demo-profile
|   +-- init-db.sh *
|   +-- stop-db.sh *
|   +-- docker-compose.yaml *
|   +-- env *
+-- templates
|   +-- demo-profile.init-db.sh
|   +-- demo-profile.stop-db.sh
|   +-- demo-profile.docker-compose.yaml
|   +-- demo-profile.env
+-- demo-profile.yaml

* created after rendering

# Profile hooks

  • prepare
  • beforeDestroy

These hooks allows you to declare a script that will be executed before the environment will be started / destroyed. Optionally fill the timeout field that will allow the entourage-server to kill the process after duration has passed.

# Docker

docker field allows to declare the path of your composeFile.

# GraphQL API

# createProfile

mutation createProfile($version: String!, $profile: String!, $params: JSON!) {
  initProfile(version: $version, profile: $profile, params: $params) {
    profile
    version
    ready
    ports
  }
}
{
  "version" : "1",
  "profile": "demo-profile",
  "params": {
    "NODE_ENV": "development",
    "HOST": "mqtt-api",
    "MQTT_PORT": "1883",
    "WS_PORT": "3000"
  }
}

# profileCreated

subscription watchProfileCreated($version: String!, $profile: String!) {
  profileCreated(version: $version, profile: $profile) {
    profile
    version
    ports
    ready
  }
}
{
  "version" : "1",
  "profile": "demo-profile"
}

# getProfileStats

query getProfileStats($version: String!, $profile: String!) {
  getProfileStats(version: $version, profile: $profile) {
    version
    ready
    profile
    ports
  }
}
{
  "version" : "1",
  "profile": "demo-profile"
}

# destroyProfile

mutation destroyProfile($version: String!, $profile: String!, $params: JSON!) {
  destroyProfile(version: $version, profile: $profile, params: $params) {
    profile
    version
    ready
    ports
  }
}
{
  "version" : "1",
  "profile": "demo-profile",
  "params": {
    "NODE_ENV": "development",
    "HOST": "mqtt-api",
    "MQTT_PORT": "1883",
    "WS_PORT": "3000"
  }
}

# profileDestroyed

subscription watchProfileDestroyed($version: String!, $profile: String!) {
  profileDestroyed(version: $version, profile: $profile) {
    profile
    version
    ports
    ready
  }
}
{
  "version" : "1",
  "profile": "demo-profile"
}

# Setup

Run entourage server as a privileged docker container and provide a profiles folder and a work folder as volume mounts:

# Via docker

docker run -d --name entourage \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v $PWD/profiles:/app/profiles \
  -v $PWD/work:/app/work \
  -p 5858:5858 \
  -p 4242:4242 \
  chriskalmar/entourage:latest

# Via docker-compose

create a file named docker-compose.yml:

version: '3'

services:
  entourage:
    image: chriskalmar/entourage:latest
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - ./profiles:/app/profiles
      - ./work:/app/work
    ports:
      - '5858:5858'
      - '4242:4242'

and run it with:

docker-compose up -d

# Modules

Broker
Docker
GraphQL
Template
Proxy
Registry
Render
Script
Server
Stats
Template
Utils
Yaml

# Broker

# Broker~initBroker() ⇒ Aedes

Start MQTT broker

Kind: inner method of Broker

# Broker~Aedes

Kind: inner typedef of Broker

# Docker

# Docker~checkDockerComposeFileExists(filePath)

Check docker-compose file presence

Kind: inner method of Docker
Throws:

  • Docker compose file x not found
Param Type
filePath string

# Docker~validateDockerComposeFile(cwd, filePath)

Check docker-compose file validity

Kind: inner method of Docker
Throws:

  • Docker compose error
Param Type
cwd string
filePath string

# Docker~adjustDockerComposeFile(workVersionFolder, filePath) ⇒ object

Update docker-compose file network and ports mapping and generate portRegistry

Kind: inner method of Docker
Returns: object - portRegistry
Throws:

  • At least one service needs to expose a port
Param Type
workVersionFolder string
filePath string

# Docker~updateDockerComposeFilesWithPorts(version, config, portRegistry)

Update docker-compose file

Kind: inner method of Docker

Param Type
version string
config object
portRegistry object

# Docker~processDockerTask(version, config) ⇒ object

Validate compose-file

Convert generated port to random ports

Update docker-compose file

Kind: inner method of Docker
Returns: object - portRegistry

Param Type
version string
config object

# Docker~processDockerTask(version, config)

Pull docker-compose file sources

Kind: inner method of Docker
Throws:

  • Docker compose error
Param Type
version string
config object

# Docker~runDockerComposeFile(cwd, filePath)

Start docker-compose file

Kind: inner method of Docker
Throws:

  • Docker compose error
Param Type
cwd string
filePath string

# Docker~runWorkVersionDockerComposeFile(version, config) ⇒ Promise.<function()>

Start docker-compose file from a work subfolder

Kind: inner method of Docker
Returns: Promise.<function()> - Docker~runDockerComposeFile

Param Type
version string
config object

# Docker~downDockerComposeFile(cwd, filePath, clean)

Stop docker-compose file

Optionally clean volumes, images and orphans

Kind: inner method of Docker
Throws:

  • Docker compose error
Param Type
cwd string
filePath string
clean boolean

# Docker~downWorkVersionDockerComposeFile(version, config, clean) ⇒ Promise.<function()>

Start docker-compose file from a work subfolder

Optionally clean volumes, images and orphans

Kind: inner method of Docker
Returns: Promise.<function()> - Docker~downDockerComposeFile

Param Type
version string
config object
clean boolean

# Docker~getDockerComposeStats(cwd, filePath) ⇒ Promise.<function()>

Get docker-compose stats

Kind: inner method of Docker
Returns: Promise.<function()> - compose.ps
Throws:

  • Docker compose error
Param Type
cwd string
filePath string

# Docker~getWorkFolderMountSource() ⇒ string

Get docker-compose mountpoint

Kind: inner method of Docker
Throws:

  • Cannot detect work folder mount point. Are you running Entourage server via docker?

# GraphQL

# GraphQL~ProfileState : GraphQLType

Kind: inner constant of GraphQL
Properties

Name Type
timestamp string
version string
profile string
params object
docker object
ready boolean
healthy boolean
ports object
stats object

# GraphQL~Query : GraphQLType

Kind: inner constant of GraphQL
Properties

Name Type
getProfileStats GraphQLQuery

# GraphQL~getProfileStats ⇒ GraphQLType

Kind: inner constant of GraphQL
Returns: GraphQLType - ProfileState
Properties

Name Type
version string
profile string

# GraphQL~Mutation : GraphQLType

Kind: inner constant of GraphQL
Properties

Name Type
initProfile GraphQLMutation
destroyProfile GraphQLMutation

# GraphQL~initProfile ⇒ GraphQLType

Kind: inner constant of GraphQL
Returns: GraphQLType - ProfileState
Properties

Name Type
version string
profile string
params object
[asyncMode] boolean

# GraphQL~destroyProfile ⇒ GraphQLType

Kind: inner constant of GraphQL
Returns: GraphQLType - ProfileState
Properties

Name Type
version string
profile string
params object
[asyncMode] boolean

# GraphQL~Subscriptions : GraphQLType

Kind: inner constant of GraphQL
Properties

Name Type
profileCreated GraphQLSubscription
profileDestroyed GraphQLSubscription

# GraphQL~profileCreated ⇒ GraphQLType

Kind: inner constant of GraphQL
Returns: GraphQLType - ProfileState
Properties

Name Type
version string
profile string

# GraphQL~profileDestroyed ⇒ GraphQLType

Kind: inner constant of GraphQL
Returns: GraphQLType - ProfileState
Properties

Name Type
version string
profile string

# Template

# Template~renderTemplate(templateFilename, templateParams) ⇒ function

Load a templateFilename and renders it from templateParams

Kind: inner method of Template
Returns: function - Render~renderFile
Throws:

  • Template x not found
Param Type
templateFilename string
templateParams object

# Template~renderTemplateToFile(templateFilename, templateParams, version, outputFilename)

Load a templateFilename and renders it from templateParams,

then save it as file in a work subfolder

Kind: inner method of Template

Param Type
templateFilename string
templateParams object
version string
outputFilename string

# Proxy

# Proxy~updateProxyConfig()

Update HAproxy configuration from the registry

Populate haproxy.cfg and haproxy.docker-compose.yaml templates

Save them at the root of WORK_PATH

Kind: inner method of Proxy

# Proxy~restartProxy()

Restart HAproxy docker container

Kind: inner method of Proxy

# Registry

# Registry~addWorkVersionConfig(config)

Save a profile configuration in the registry

Kind: inner method of Registry

Param Type
config object

# Registry~getWorkVersionConfig(config) ⇒ object

Find a profile configuration in the registry

Kind: inner method of Registry

Param Type
config object

# Registry~removeWorkVersionConfig(config)

Remove a profile configuration in the registry

Kind: inner method of Registry

Param Type
config object

# Registry~initRegistry()

Initialize the registry from existing work subfolder

Kind: inner method of Registry

# Render

# Render~render(content, templateParams, escapePatterns) ⇒ object

Render a template file by replacing variables

Kind: inner method of Render

Param Type
content string
templateParams object
escapePatterns array

# Render~renderFile(content, templateParams, escapePatterns) ⇒ function

Find a template file and render it by replacing variables

Kind: inner method of Render
Returns: function - Render~render

Param Type
content string
templateParams object
escapePatterns array

# Script

# Script~executeScript(version, script, params, [timeout]) ⇒ Promise.<number>

Execute a bash script from a work subfolder

Optional timeout to kill the process

Kind: inner method of Script
Returns: Promise.<number> - exitCode
Throws:

  • Script timed out: x.
Param Type
version string
script string
params string
[timeout] number

# Script~executeScript(version, scripts, params, [timeout])

Execute a series of bash scripts from a work subfolder

Optional timeout to kill the process

Kind: inner method of Script
Throws:

  • Script execution failed with exit code x.
Param Type
version string
scripts object
params string
[timeout] number

# Server

# Server~initServer() ⇒ GraphQLServer

Start GraphQL HTTP/WS server

Kind: inner method of Server

# Server~GraphQLServer

Kind: inner typedef of Server

# Stats

# Stats~getProfileConfig(profile, version) ⇒ Promise.<object>

Retrieve a profile config from the registry

Kind: inner method of Stats
Throws:

  • Unknown profile
Param Type
profile string
version string

# Stats~getProfileStats(profile, version) ⇒ Promise.<object>

Retrieve profile stats from docker compose

Kind: inner method of Stats
Throws:

  • Unknown profile
Param Type
profile string
version string

# Template

# Template~renderTemplate(templateFilename, templateParams) ⇒ function

Load a templateFilename and renders it from templateParams

Kind: inner method of Template
Returns: function - Render~renderFile
Throws:

  • Template x not found
Param Type
templateFilename string
templateParams object

# Template~renderTemplateToFile(templateFilename, templateParams, version, outputFilename)

Load a templateFilename and renders it from templateParams,

then save it as file in a work subfolder

Kind: inner method of Template

Param Type
templateFilename string
templateParams object
version string
outputFilename string

# Utils

# Utils~log(msg) ⇒ function

Log a message

Kind: inner method of Utils
Returns: function - console.log

Param Type
msg any

# Utils~createWorkPathFolder(version)

Create a work folder from WORK_PATH environement variable

Kind: inner method of Utils

Param Type
version string

# Utils~getWorkVersionFolder(version) ⇒ function

Get a work sub folder name from the version and WORK_PATH environement variable

Kind: inner method of Utils
Returns: function - path.normalize

Param Type
version string

# Utils~checkVersionPathBreakout(version)

Check that a work sub folder name is disposed under WORK_PATH

Kind: inner method of Utils
Throws:

  • Version x needs to be a child of WORK_PATH
Param Type
version string

# Utils~writeFileSync(filename, content) ⇒ function

Write a file

Kind: inner method of Utils
Returns: function - fs.writeFileSync

Param Type
filename string
content any

# Utils~deleteWorkVersionFolder(version)

Delete a work sub folder by version

Kind: inner method of Utils

Param Type
version string

# Utils~createOrResetWorkVersionFolder(version)

Create or reset a work sub folder by version

Kind: inner method of Utils
Throws:

  • Version x is already in use
Param Type
version string

# Utils~createOrResetWorkVersionFolder(task) ⇒ function

Log a task

Kind: inner method of Utils
Returns: function - Utils~log

Param Type
task string

# Utils~getRandomPort(minPort, maxPort) ⇒ Promise.<function()>

Generate a random port within a declared range

Kind: inner method of Utils
Returns: Promise.<function()> - portfinder.getPortPromise

Param Type
minPort number
maxPort number

# Utils~getRandomPorts(count, minPort, maxPort, exclude) ⇒ Promise.<array>

Generate an array of count random ports within a declared range

Kind: inner method of Utils
Throws:

  • Too many tries to find an open port
Param Type
count number
minPort number
maxPort number
exclude Array.<number>

# Utils~storeWorkVersionConfig(version, config) ⇒ Promise.<function()>

Write profile configuration into the work folder

Kind: inner method of Utils
Returns: Promise.<function()> - Utils~writeFileSync

Param Type
version string
config object

# Utils~isEnvFlagSet() ⇒ boolean

Check if an environment flag is set to TRUE

Kind: inner method of Utils

Param Type
process.env[name string

# Yaml

# Yaml~parseYaml(content) ⇒ function

Parse a yaml file content

Kind: inner method of Yaml
Returns: function - yaml.safeLoad

Param Type
content string

# Yaml~parseYamlFile(filePath) ⇒ function

Parse a yaml file

Kind: inner method of Yaml
Returns: function - Yaml~parseYaml

Param Type
filePath string

# Yaml~serializeYaml(content) ⇒ function

Serialize some content to yaml format

Kind: inner method of Yaml
Returns: function - yaml.safeDump

Param Type
content any

# Yaml~serializeYamlFile(content, filePath) ⇒ function

Serialize some content to yaml format and save it as a file

Kind: inner method of Yaml
Returns: function - fs.writeFileSync

Param Type
content any
filePath string