Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added API To Config Themes #61

Merged
merged 50 commits into from
Nov 4, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
e48def9
Add: ReturnPromise pass stderr to the success callback
OmriBarZik Oct 30, 2020
9ace212
Add: RunInContainer
OmriBarZik Oct 30, 2020
f9aff0f
Update: CreateWordpressCliContainer to use RunInContainer
OmriBarZik Oct 30, 2020
1fca7fc
Update: docs
OmriBarZik Oct 30, 2020
3866600
Merge branch 'main' of github.com:OmriBarZik/cywp into feature/theme-…
OmriBarZik Oct 30, 2020
e5a2c7a
Add: commands to better check conatiner health
OmriBarZik Oct 30, 2020
c471533
Fix: health test
OmriBarZik Oct 30, 2020
ee22d11
Update: CreateWordpressContainer
OmriBarZik Oct 30, 2020
c2c5507
Update: presets to use the health checks
OmriBarZik Oct 30, 2020
e3931a5
Add: command to check container health
OmriBarZik Oct 30, 2020
bcaec9b
Update: setupDatabase
OmriBarZik Oct 30, 2020
9607e5e
Add: class to control wp theme
OmriBarZik Oct 30, 2020
af42ae9
Add: RunInContainerOutput type
OmriBarZik Oct 30, 2020
77eb84c
Fix: Test
OmriBarZik Oct 30, 2020
21c5249
Fix: Tests
OmriBarZik Oct 31, 2020
f9eaf0b
Add: install command
OmriBarZik Oct 31, 2020
0f15b30
Fix: flikers in wordpress continer
OmriBarZik Oct 31, 2020
7af4374
Fix: Flikers
OmriBarZik Oct 31, 2020
3d1f5be
Update: pram check to util file
OmriBarZik Oct 31, 2020
670bb88
Add: tests to util
OmriBarZik Oct 31, 2020
841cbf5
Add: checks to install version
OmriBarZik Oct 31, 2020
855f5ec
Add: tests for theme
OmriBarZik Oct 31, 2020
1ef4e08
Remove: environment Tests
OmriBarZik Oct 31, 2020
1f13e02
Fix: Theme Tests
OmriBarZik Oct 31, 2020
3bfb248
Add: tests for RunInContainer
OmriBarZik Nov 1, 2020
6f4328e
Fix: docs
OmriBarZik Nov 1, 2020
29cbd8b
Add: Checks to options.health
OmriBarZik Nov 1, 2020
56febf5
Add: tests for options.health
OmriBarZik Nov 1, 2020
208ddc2
Fix: isHealthy
OmriBarZik Nov 1, 2020
5a8f949
Add: Tests
OmriBarZik Nov 1, 2020
8b4d916
Add: isActive and isInstalled
OmriBarZik Nov 1, 2020
d6c9c57
Add: list command
OmriBarZik Nov 1, 2020
6a1b53b
Add: exec to container
OmriBarZik Nov 1, 2020
46b9c63
Update: Checks for exec
OmriBarZik Nov 1, 2020
8f858ac
Fix: mysql health checks
OmriBarZik Nov 1, 2020
944b9b1
Add: function to Setup Sites
OmriBarZik Nov 1, 2020
7abbae0
Add: theme.path
OmriBarZik Nov 1, 2020
ec235dd
Add: stdout to ReturnPromise callback
OmriBarZik Nov 2, 2020
f45ea4a
Update: docker to use ReturnPromise
OmriBarZik Nov 2, 2020
eea88d7
Update ReturnPromise
OmriBarZik Nov 3, 2020
6d6b4e0
Update: Using dockerContainer
OmriBarZik Nov 3, 2020
9a7490e
Update: docs
OmriBarZik Nov 3, 2020
4834d41
Add: Tests
OmriBarZik Nov 3, 2020
1ae8fb8
Fix: isInstalled
OmriBarZik Nov 3, 2020
b29e653
Fix: list
OmriBarZik Nov 3, 2020
2d0529d
Add: error if filter not object
OmriBarZik Nov 4, 2020
609f30c
Add: Tests
OmriBarZik Nov 4, 2020
4a2257a
Update: Theme Tests
OmriBarZik Nov 4, 2020
d8f3fa2
Add: Tests
OmriBarZik Nov 4, 2020
9e7ea7e
Add: docs
OmriBarZik Nov 4, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
113 changes: 68 additions & 45 deletions src/docker/container.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,28 @@ class Container {
this.options = options
}

/**
* @param {string[]} args - docker container arguments
* @param {(stdout: string, stderr: string) => any} callback - callback that deterred what to return when the process is successful.
* @returns {Promise} return what said to return form the callback
*/
dockerContainer (args, callback) {
args = ['container'].concat(args)

const container = spawn('docker', args)

return ReturnPromise(container, callback)
}

/**
* Start the container.
*
* @returns {Promise<Container>} Return the current container.
*/
start () {
const start = spawn('docker', ['container', 'start', this.options.id])
const startArgs = ['start', this.options.id]

return ReturnPromise(start, () => {
return this.dockerContainer(startArgs, () => {
this.options.status = 'started'
return this
})
Expand All @@ -34,16 +47,14 @@ class Container {
* @returns {Promise<Container>} Return the current container.
*/
rm (force = false, volumes = true) {
const rmArgs = ['container', 'rm']
const rmArgs = ['rm']

if (force) { rmArgs.push('--force') }
if (volumes) { rmArgs.push('--volumes') }

rmArgs.push(this.options.id)

const rm = spawn('docker', rmArgs)

return ReturnPromise(rm, () => {
return this.dockerContainer(rmArgs, () => {
this.options.status = 'removed'
return this
})
Expand All @@ -56,15 +67,16 @@ class Container {
* @returns {Promise<Container>} Return the current container.
*/
stop (time = 10) {
const stopArgs = ['container', 'stop']
const stopArgs = ['stop']

stopArgs.push('--time', time)
if (0 > time) {
throw new Error('time must be bigger then 0')
}

stopArgs.push('--time', time)
stopArgs.push(this.options.id)

const stop = spawn('docker', stopArgs)

return ReturnPromise(stop, () => {
return this.dockerContainer(stopArgs, () => {
this.options.status = 'stopped'
return this
})
Expand All @@ -80,38 +92,20 @@ class Container {
* @returns {Promise<{stdout: string, stderr: string, container: Container}}>} Return Promise for container logs.
*/
logs (options = {}) {
const logsArgs = ['container', 'logs']
let stdout = ''
let stderr = ''
const logsArgs = ['logs']

if (options.since) { logsArgs.push('--since', options.since) }
if (options.tail) { logsArgs.push('--tail', options.tail) }
if (options.timeStamps) { logsArgs.push('--timestamps') } // eslint-disable-line spellcheck/spell-checker

logsArgs.push(this.options.id)

const logs = spawn('docker', logsArgs)

logs.stdout.on('data', (data) => {
stdout += data
})

logs.stderr.on('data', (data) => {
stderr += data
})

return new Promise((resolve, reject) => {
logs.on('close', (code) => {
if (code) {
reject(stderr)
return
}
resolve({
stdout: stdout,
stderr: stderr,
container: this,
})
})
return this.dockerContainer(logsArgs, (stdout, stderr) => {
return {
stdout: stdout,
stderr: stderr,
container: this,
}
})
}

Expand All @@ -122,20 +116,13 @@ class Container {
* @returns {Promise<string|object>} container info.
*/
inspect (format) {
const inspectArgs = ['container', 'inspect']
let stdout = ''
const inspectArgs = ['inspect']

if (format) { inspectArgs.push('--format', format) }

inspectArgs.push(this.options.id)

const inspect = spawn('docker', inspectArgs)

inspect.stdout.on('data', (data) => {
stdout += data
})

return ReturnPromise(inspect, () => {
return this.dockerContainer(inspectArgs, (stdout) => {
return CleanInspect(stdout)
})
}
Expand All @@ -151,6 +138,42 @@ class Container {
return status
})
}

/**
* Checks if the container is healthy or not.
*
* @returns {Promise<boolean>} if the continer is healthy or not
*/
isHealthy () {
if (!this.options.health) {
throw new Error('options.health.command must be defined to use IsHealthy')
}

return this.inspect('{{.State.Health.Status}}')
.then(status => 'healthy' === status)
}

/**
* Run commands in a running container.
*
* @param {Array} commands - Commands to run.
* @returns {Promise<Container>} Return the current container.
*/
exec (commands) {
if (!Array.isArray(commands)) {
throw new Error('commands must be an array')
}

const execArgs = ['exec']

execArgs.push(this.options.id)

execArgs.push.apply(execArgs, commands)

return this.dockerContainer(execArgs, () => {
return this
})
}
}

module.exports = Container
76 changes: 53 additions & 23 deletions src/docker/docker.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,11 @@ class Docker {
* @returns {Promise<Container>} Return promise for continer object
*/
CreateContainer (options, run = false, detach = true) {
let stdout = ''

const args = processCreateContainerOptions(options, run, detach)

const process = spawn('docker', args)

process.stdout.on('data', (data) => {
stdout += data
})

return ReturnPromise(process, () => {
return ReturnPromise(process, (stdout) => {
options.id = stdout.replace('\n', '')
options.status = run ? 'started' : 'created'

Expand All @@ -35,22 +29,40 @@ class Docker {
})
}

/**
* Run commands in a docker container return it's output.
*
* @param {ContainerOptions} options - Docker container options.
* @returns {Promise<RunInContainerOutput>} Container outputs.
*/
RunInContainer (options) {
if (!options.commands) {
throw new TypeError('options.commands must be provided to use RunInContainer.')
}

if (!options.rm) {
throw new TypeError('options.rm must be true to use RunInContainer. (we don\'t want to leave garbage aroud)')
}

const args = processCreateContainerOptions(options, true, false)

const process = spawn('docker', args)

return ReturnPromise(process, (stdout, stderr) => {
return { stdout: stdout, stderr: stderr }
})
}

/**
* Create docker volume.
*
* @param {string} name - Name of the volume.
* @returns {Promise<Volume>} return promise for volume object.
*/
CreateVolume (name) {
let stdout = ''

const process = spawn('docker', ['volume', 'create', name])

process.stdout.on('data', (data) => {
stdout += data
})

return ReturnPromise(process, () => {
return ReturnPromise(process, (stdout) => {
const options = {}
options.name = stdout.replace('\n', '')
options.status = 'alive'
Expand All @@ -66,8 +78,6 @@ class Docker {
* @returns {Promise<Network>} return promise for network object.
*/
CreateNetwork (options) {
let stdout = ''

if ('string' === typeof options) {
options = { name: options }
}
Expand All @@ -76,11 +86,7 @@ class Docker {

const process = spawn('docker', args)

process.stdout.on('data', (data) => {
stdout += data
})

return ReturnPromise(process, () => {
return ReturnPromise(process, (stdout) => {
options.id = stdout.replace('\n', '')
options.status = 'alive'

Expand Down Expand Up @@ -116,8 +122,32 @@ function processCreateContainerOptions (options, run, detach) {
args.push('--net', options.network)
}

if (options.healthCommand) {
args.push('--health-cmd', `${options.healthCommand}`)
if (options.health) {
if (!options.health.command) {
throw new TypeError('options.health.command must not be defined to use options.health')
}

args.push('--health-cmd', options.health.command)

if (options.health.interval) {
args.push('--health-interval', options.health.interval)
}

if (options.health.retries) {
if (!Number.isInteger(options.health.retries)) {
throw new TypeError('options.health.retries must be an integer.')
}

args.push('--health-retries', options.health.retries)
}

if (options.health.startPeriod) {
args.push('--health-start-period', options.health.startPeriod)
}

if (options.health.timeout) {
args.push('--health-timeout', options.health.timeout)
}
}

if (options.rm) {
Expand Down
8 changes: 1 addition & 7 deletions src/docker/network.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,19 +34,13 @@ class Network {
inspect (format) {
const inspectArgs = ['network', 'inspect']

let stdout = ''

if (format) { inspectArgs.push('--format', format) }

inspectArgs.push(this.options.id)

const inspect = spawn('docker', inspectArgs)

inspect.stdout.on('data', (data) => {
stdout += data
})

return ReturnPromise(inspect, () => {
return ReturnPromise(inspect, (stdout) => {
return CleanInspect(stdout)
})
}
Expand Down
18 changes: 15 additions & 3 deletions src/docker/presets/containers.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,12 @@ function CreateMysqlContainer (name, port, run = false) {
environmentVariables: [
{ name: 'MYSQL_ROOT_PASSWORD', value: 'cywp' },
],
healthCommand: 'mysqladmin ping --silent', // eslint-disable-line spellcheck/spell-checker
health: {
command: 'mysqladmin ping -u root -p$MYSQL_ROOT_PASSWORD | grep \'mysqld is alive\'', // eslint-disable-line spellcheck/spell-checker
startPeriod: '5s',
retries: 30,
interval: '1s',
},
}, run)
}

Expand All @@ -47,6 +52,7 @@ function CreateWordpressContainer (name, port, mysqlContainer, run = false) {
environmentVariables: [
{ name: 'WORDPRESS_DB_HOST', value: `${mysqlContainer.options.name}:${mysqlContainer.options.exposePorts[0].host}` },
{ name: 'WORDPRESS_DB_PASSWORD', value: 'cywp' },
{ name: 'WORDPRESS_DB_USER', value: 'root' },
{ name: 'WORDPRESS_DB_NAME', value: `cywp-${name}-db` },
],
volumes: [
Expand All @@ -57,6 +63,12 @@ function CreateWordpressContainer (name, port, mysqlContainer, run = false) {
image: 'wordpress',
network: 'cywp-network',
name: `cywp-${name}-wordpress`,
health: {
command: 'test -r wp-includes/version.php',
startPeriod: '1s',
interval: '1s',
retries: 30,
},
}, run)
}

Expand All @@ -65,14 +77,14 @@ function CreateWordpressContainer (name, port, mysqlContainer, run = false) {
*
* @param {Container} wordpress - WordPress docker container based from.
* @param {string[]} commands - commands to pass to the container.
* @returns {Promise<Container>} retrun promise for WordPress continer object.
* @returns {Promise<RunInContainerOutput>} retrun promise for WordPress continer object.
*/
function CreateWordpressCliContainer (wordpress, commands) {
if (!Array.isArray(commands)) {
throw new TypeError('commands must be an array')
}

return Docker.prototype.CreateContainer({
return Docker.prototype.RunInContainer({
volumes: wordpress.options.volumes,
image: 'wordpress:cli',
network: wordpress.options.network,
Expand Down
Loading