masson
Version:
Module execution engine for cluster deployments.
209 lines (192 loc) • 7.59 kB
Markdown
---
title:
layout: module
---
# Mysql Server
each = require 'each'
escape = (text) -> text.replace(/[\\"]/g, "\\$&")
module.exports = []
module.exports.push 'masson/bootstrap/'
module.exports.push 'masson/commons/mysql_client' # Install the mysql driver
## Configure
module.exports.push module.exports.configure = (ctx) ->
ctx.config.mysql_server ?= {}
ctx.config.mysql_server.sql_on_install ?= []
ctx.config.mysql_server.sql_on_install = [ctx.config.mysql_server.sql_on_install] if typeof ctx.config.mysql_server.sql_on_install is 'string'
ctx.config.mysql_server.current_password ?= ''
ctx.config.mysql_server.port ?= '3306'
ctx.config.mysql_server.username ?= 'root'
ctx.config.mysql_server.password ?= ''
ctx.config.mysql_server.remove_anonymous ?= true
ctx.config.mysql_server.disallow_remote_root_login ?= false
ctx.config.mysql_server.remove_test_db ?= true
ctx.config.mysql_server.reload_privileges ?= true
# /etc/my.cnf
ctx.config.mysql_server.my_cnf ?= {}
ctx.config.mysql_server.my_cnf['mysqld'] ?= {}
ctx.config.mysql_server.my_cnf['mysqld']['tmpdir'] ?= '/tmp/mysql'
## Package
Install the Mysql database server. Secure the temporary directory.
module.exports.push name: 'Mysql Server # Package', timeout: -1, callback: (ctx, next) ->
{my_cnf} = ctx.config.mysql_server
modified = false
do_install = ->
ctx.service
name: 'mysql-server'
chk_name: 'mysqld'
startup: '235'
# action: 'start'
, (err, serviced) ->
return next err if err
modified = true if serviced
do_tmp()
do_tmp = ->
ctx.mkdir
destination: '/tmp/mysql'
uid: 'mysql'
gid: 'mysql'
mode: '0744'
, (err, created) ->
return next err if err
modified = true if created
ctx.ini
destination: '/etc/my.cnf'
content: my_cnf
merge: true
backup: true
, (err, updated) ->
return next err if err
modified = true if updated
do_end()
# do_socket = ->
# # Create the socket inside "/tmp" instead of default "/var/lib/mysql/mysql.sock". That
# # way, on restart, there won't be any existing file preventing the mysql server to start
# ctx.ini
# destination: '/etc/my.cnf'
# content: mysqld: socket: '/tmp/mysql/mysql.sock'
# merge: true
# backup: true
# , (err, updated) ->
# return next err if err
# modified = true if updated
# ctx.link
# source: '/tmp/mysql/mysql.sock'
# destination: '/var/lib/mysql/mysql.sock'
# , (err, linked) ->
# modified = true if linked
# do_start()
do_end = ->
next null, if modified then ctx.OK else ctx.PASS
do_install()
module.exports.push name: 'Mysql Server # Start', callback: (ctx, next) ->
modified = false
do_start = ->
ctx.service
name: 'mysql-server'
srv_name: 'mysqld'
action: 'start'
, (err, started) ->
# return next err if err
return do_clean_sock() if err
modified = true if started
do_end()
do_clean_sock = ->
console.log 'do_clean_sock'
ctx.remove
# destination: "/tmp/mysql/mysql.sock"
destination: "/var/lib/mysql/mysql.sock"
, (err, removed) ->
return next err if err
return next new Error 'Failed to install mysqld' unless removed
ctx.service
name: 'mysql-server'
srv_name: 'mysqld'
action: 'start'
, (err, started) ->
return next err if err
modified = true if started
do_end()
do_end = ->
next null, if modified then ctx.OK else ctx.PASS
do_start()
module.exports.push name: 'Mysql Server # Populate', callback: (ctx, next) ->
{sql_on_install} = ctx.config.mysql_server
each(sql_on_install)
.on 'item', (sql, next) ->
cmd = "mysql -uroot -e \"#{escape sql}\""
ctx.log "Execute: #{cmd}"
ctx.execute
cmd: cmd
code_skipped: 1
, (err, executed) ->
return next err if err
modified = true if executed
next()
.on 'both', (err) ->
next err, ctx.PASS
## Secure Installation
/usr/bin/mysql_secure_installation (run as root after install).
Enter current password for root (enter for none):
Set root password? [Y/n] y
big123
Remove anonymous users? [Y/n] y
Disallow root login remotely? [Y/n] n
Remove test database and access to it? [Y/n] y
module.exports.push name: 'Mysql Server # Secure', callback: (ctx, next) ->
{current_password, password, remove_anonymous, disallow_remote_root_login, remove_test_db, reload_privileges} = ctx.config.mysql_server
test_password = true
modified = false
ctx.ssh.shell (err, stream) ->
stream.write '/usr/bin/mysql_secure_installation\n'
data = ''
error = null
stream.on 'data', (data, extended) ->
ctx.log[if extended is 'stderr' then 'err' else 'out'].write data
switch
when /Enter current password for root/.test data
stream.write "#{if test_password then password else current_password}\n"
data = ''
when /ERROR 1045/.test(data) and test_password
test_password = false
modified = true
data = ''
when /Change the root password/.test data
stream.write "y\n"
data = ''
when /Set root password/.test data
stream.write "y\n"
data = ''
when /New password/.test(data) or /Re-enter new password/.test(data)
stream.write "#{password}\n"
data = ''
when /Remove anonymous users/.test data
stream.write "#{if remove_anonymous then 'y' else 'n'}\n"
data = ''
when /Disallow root login remotely/.test data
stream.write "#{if disallow_remote_root_login then 'y' else 'n'}\n"
data = ''
when /Remove test database and access to it/.test data
stream.write "#{if remove_test_db then 'y' else 'n'}\n"
data = ''
when /Reload privilege tables now/.test data
stream.write "#{if reload_privileges then 'y' else 'n'}\n"
data = ''
when /All done/.test data
stream.end()
when /ERROR/.test data
return if data.toString().indexOf('ERROR 1008 (HY000) at line 1: Can\'t drop database \'test\'') isnt -1
error = new Error data
stream.end()
stream.on 'close', ->
return next error if error
if disallow_remote_root_login then return next null, if modified then ctx.OK else ctx.PASS
# Note, "WITH GRANT OPTION" is required for root
sql = """
USE mysql;
GRANT ALL PRIVILEGES ON *.* TO root@'%' IDENTIFIED BY "#{password}" WITH GRANT OPTION;
FLUSH PRIVILEGES;
"""
ctx.execute
cmd: "mysql -uroot -p#{password} -e \"#{escape sql}\""
, (err, executed) ->
next err, if modified then ctx.OK else ctx.PASS