<commit_before>
# HBase Master Install

TODO: [HBase backup node](http://willddy.github.io/2013/07/02/HBase-Add-Backup-Master-Node.html)

    module.exports = []
    module.exports.push 'masson/bootstrap/'
    module.exports.push 'masson/core/iptables'
    module.exports.push 'ryba/hadoop/hdfs'
    module.exports.push 'ryba/hbase/_'
    module.exports.push require('./master').configure
    module.exports.push require '../lib/hdp_service'
    module.exports.push require '../lib/write_jaas'

## IPTables

| Service             | Port  | Proto | Info                   |
|---------------------|-------|-------|------------------------|
| HBase Master        | 60000 | http  | hbase.master.port      |
| HMaster Info Web UI | 60010 | http  | hbase.master.info.port |

IPTables rules are only inserted if the parameter "iptables.action" is set to 
"start" (default value).

    module.exports.push name: 'HBase master # IPTables', handler: (ctx, next) ->
      {hbase} = ctx.config.ryba
      ctx.iptables
        rules: [
          { chain: 'INPUT', jump: 'ACCEPT', dport: hbase.site['hbase.master.port'], protocol: 'tcp', state: 'NEW', comment: "HBase Master" }
          { chain: 'INPUT', jump: 'ACCEPT', dport: hbase.site['hbase.master.info.port'], protocol: 'tcp', state: 'NEW', comment: "HMaster Info Web UI" }
        ]
        if: ctx.config.iptables.action is 'start'
      , next

## Service

Install the "hbase-master" service, symlink the rc.d startup script inside
"/etc/init.d" and activate it on startup.

    module.exports.push name: 'HBase Master # Service', timeout: -1, handler: (ctx, next) ->
      ctx.hdp_service
        name: 'hbase-master'
        write: [
          match: /^\. \/etc\/default\/hbase .*$/m
          replace: '. /etc/default/hbase # RYBA FIX rc.d, DONT OVERWRITE'
          append: ". /lib/lsb/init-functions"
        ,
          # HDP default is "/etc/hbase/conf"
          match: /^CONF_DIR=.*$/m
          replace: "CONF_DIR=\"${HBASE_CONF_DIR}\" # RYBA HONORS /etc/default, DONT OVEWRITE"
        ,
          # HDP default is "/usr/lib/hbase/bin/hbase-daemon.sh"
          match: /^EXEC_PATH=.*$/m
          replace: "EXEC_PATH=\"${HBASE_HOME}/bin/hbase-daemon.sh\" # RYBA HONORS /etc/default, DONT OVEWRITE"
        ,
          # HDP default is "/var/run/hbase/hbase-hbase-master.pid"
          match: /^PIDFILE=.*$/m
          replace: "PIDFILE=\"${HBASE_PID_DIR}/hbase-hbase-master.pid\" # RYBA HONORS /etc/default, DONT OVEWRITE"
        ]
        etc_default:
          'hadoop': true
          'hbase':
            write: [
              match: /^export HBASE_HOME=.*$/m # HDP default is "/usr/lib/hbase"
              replace: "export HBASE_HOME=/usr/hdp/current/hbase-client # RYBA FIX"
            ]
      , next

## Configure

*   [New Security Features in Apache HBase 0.98: An Operator's Guide][secop].

[secop]: http://fr.slideshare.net/HBaseCon/features-session-2

    module.exports.push name: 'HBase Master # Configure', handler: (ctx, next) ->
      {hbase} = ctx.config.ryba
      mode = if ctx.has_module 'ryba/hbase/client' then 0o0644 else 0o0600
      ctx.hconfigure
        destination: "#{hbase.conf_dir}/hbase-site.xml"
        default: "#{__dirname}/../resources/hbase/hbase-site.xml"
        local_default: true
        properties: hbase.site
        merge: true
        uid: hbase.user.name
        gid: hbase.group.name
        mode: mode # See slide 33 from [Operator's Guide][secop]
        backup: true
      , next

# Opts

Environment passed to the Master before it starts.   

    module.exports.push name: 'HBase Master # Opts', handler: (ctx, next) ->
      {hbase} = ctx.config.ryba
      return next() unless hbase.master_opts
      ctx.write
        destination: "#{hbase.conf_dir}/hbase-env.sh"
        match: /^export HBASE_MASTER_OPTS="(.*) \$\{HBASE_MASTER_OPTS\}" # RYBA .*/m
        replace: "export HBASE_MASTER_OPTS=\"#{hbase.master_opts} ${HBASE_MASTER_OPTS}\" # RYBA CONF \"ryba.hbase.master_opts\", DONT OVERWRITE"
        before: /^export HBASE_MASTER_OPTS=".*"$/m
        backup: true
      , next

    module.exports.push 'ryba/hadoop/hdfs_nn_wait'

    module.exports.push name: 'HBase Master # HDFS layout', timeout: -1, handler: (ctx, next) ->
      {hbase} = ctx.config.ryba
      ctx.waitForExecution mkcmd.hdfs(ctx, "hdfs dfs -test -d /apps"), code_skipped: 1, (err) ->
        return next err if err
        dirs = hbase.site['hbase.bulkload.staging.dir'].split '/'
        return next err "Invalid property \"hbase.bulkload.staging.dir\"" unless dirs.length > 2 and path.join('/', dirs[0], '/', dirs[1]) is '/apps'
        ctx.log "Create /apps/hbase"
        modified = false
        each(dirs.slice 2)
        .on 'item', (dir, index, next) ->
          dir = dirs.slice(0, 3 + index).join '/'
          cmd = """
          if hdfs dfs -ls #{dir} &>/dev/null; then exit 2; fi
          hdfs dfs -mkdir #{dir}
          hdfs dfs -chown #{hbase.user.name} #{dir}
          """<commit_msg>hbase: handle empty master_opts<commit_after>
# HBase Master Install

TODO: [HBase backup node](http://willddy.github.io/2013/07/02/HBase-Add-Backup-Master-Node.html)

    module.exports = []
    module.exports.push 'masson/bootstrap/'
    module.exports.push 'masson/core/iptables'
    module.exports.push 'ryba/hadoop/hdfs'
    module.exports.push 'ryba/hbase/_'
    module.exports.push require('./master').configure
    module.exports.push require '../lib/hdp_service'
    module.exports.push require '../lib/write_jaas'

## IPTables

| Service             | Port  | Proto | Info                   |
|---------------------|-------|-------|------------------------|
| HBase Master        | 60000 | http  | hbase.master.port      |
| HMaster Info Web UI | 60010 | http  | hbase.master.info.port |

IPTables rules are only inserted if the parameter "iptables.action" is set to 
"start" (default value).

    module.exports.push name: 'HBase master # IPTables', handler: (ctx, next) ->
      {hbase} = ctx.config.ryba
      ctx.iptables
        rules: [
          { chain: 'INPUT', jump: 'ACCEPT', dport: hbase.site['hbase.master.port'], protocol: 'tcp', state: 'NEW', comment: "HBase Master" }
          { chain: 'INPUT', jump: 'ACCEPT', dport: hbase.site['hbase.master.info.port'], protocol: 'tcp', state: 'NEW', comment: "HMaster Info Web UI" }
        ]
        if: ctx.config.iptables.action is 'start'
      , next

## Service

Install the "hbase-master" service, symlink the rc.d startup script inside
"/etc/init.d" and activate it on startup.

    module.exports.push name: 'HBase Master # Service', timeout: -1, handler: (ctx, next) ->
      ctx.hdp_service
        name: 'hbase-master'
        write: [
          match: /^\. \/etc\/default\/hbase .*$/m
          replace: '. /etc/default/hbase # RYBA FIX rc.d, DONT OVERWRITE'
          append: ". /lib/lsb/init-functions"
        ,
          # HDP default is "/etc/hbase/conf"
          match: /^CONF_DIR=.*$/m
          replace: "CONF_DIR=\"${HBASE_CONF_DIR}\" # RYBA HONORS /etc/default, DONT OVEWRITE"
        ,
          # HDP default is "/usr/lib/hbase/bin/hbase-daemon.sh"
          match: /^EXEC_PATH=.*$/m
          replace: "EXEC_PATH=\"${HBASE_HOME}/bin/hbase-daemon.sh\" # RYBA HONORS /etc/default, DONT OVEWRITE"
        ,
          # HDP default is "/var/run/hbase/hbase-hbase-master.pid"
          match: /^PIDFILE=.*$/m
          replace: "PIDFILE=\"${HBASE_PID_DIR}/hbase-hbase-master.pid\" # RYBA HONORS /etc/default, DONT OVEWRITE"
        ]
        etc_default:
          'hadoop': true
          'hbase':
            write: [
              match: /^export HBASE_HOME=.*$/m # HDP default is "/usr/lib/hbase"
              replace: "export HBASE_HOME=/usr/hdp/current/hbase-client # RYBA FIX"
            ]
      , next

## Configure

*   [New Security Features in Apache HBase 0.98: An Operator's Guide][secop].

[secop]: http://fr.slideshare.net/HBaseCon/features-session-2

    module.exports.push name: 'HBase Master # Configure', handler: (ctx, next) ->
      {hbase} = ctx.config.ryba
      mode = if ctx.has_module 'ryba/hbase/client' then 0o0644 else 0o0600
      ctx.hconfigure
        destination: "#{hbase.conf_dir}/hbase-site.xml"
        default: "#{__dirname}/../resources/hbase/hbase-site.xml"
        local_default: true
        properties: hbase.site
        merge: true
        uid: hbase.user.name
        gid: hbase.group.name
        mode: mode # See slide 33 from [Operator's Guide][secop]
        backup: true
      , next

# Opts

Environment passed to the Master before it starts.   

    module.exports.push name: 'HBase Master # Opts', handler: (ctx, next) ->
      {hbase} = ctx.config.ryba
      # return next() unless hbase.master_opts
      console.log "export HBASE_MASTER_OPTS=\"#{hbase.master_opts} ${HBASE_MASTER_OPTS}\" # RYBA CONF \"ryba.hbase.master_opts\", DONT OVERWRITE"
      ctx.write
        destination: "#{hbase.conf_dir}/hbase-env.sh"
        match: /^export HBASE_MASTER_OPTS="(.*) \$\{HBASE_MASTER_OPTS\}" # RYBA .*/m
        replace: "export HBASE_MASTER_OPTS=\"#{hbase.master_opts} ${HBASE_MASTER_OPTS}\" # RYBA CONF \"ryba.hbase.master_opts\", DONT OVERWRITE"
        before: /^export HBASE_MASTER_OPTS=".*"$/m
        backup: true
      , next

    module.exports.push 'ryba/hadoop/hdfs_nn_wait'

    module.exports.push name: 'HBase Master # HDFS layout', timeout: -1, handler: (ctx, next) ->
      {hbase} = ctx.config.ryba
      ctx.waitForExecution mkcmd.hdfs(ctx, "hdfs dfs -test -d /apps"), code_skipped: 1, (err) ->
        return next err if err
        dirs = hbase.site['hbase.bulkload.staging.dir'].split '/'
        return next err "Invalid property \"hbase.bulkload.staging.dir\"" unless dirs.length > 2 and path.join('/', dirs[0], '/', dirs[1]) is '/apps'
        ctx.log "Create /apps/hbase"
        modified = false
        each(dirs.slice 2)
        .on 'item', (dir, index, next) ->
          dir = dirs.slice(0, 3 + index).join '/'
          cmd = """
          if hdfs dfs -ls #{dir} &>/dev/null; then exit 2; fi
          hdfs dfs -mkdir #{dir}
          hdfs dfs -chown #{hbase.user.name} #{dir}
          """
{'fraction_non_alphanumeric': 0.15938176806457965, 'fraction_numerical': 0.008663122661941327, 'mean_word_length': 2.269713550048278, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 4}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3805069', 'n_tokens_mistral': 3537, 'n_tokens_neox': 3420, 'n_words': 790}