centos 69 – install wkhtmltopdf

# get source with wget
wget https://bitbucket.org/wkhtmltopdf/wkhtmltopdf/downloads/wkhtmltox-0.13.0-alpha-7b36694_linux-centos6-amd64.rpm
# install with yum to get dependecy
yum install wkhtmltox-0.13.0-alpha-7b36694_linux-centos6-amd64.rpm -y

# if error need xvfb
yum search xvfb
yum install xorg-x11-server-Xvfb
echo "export QT_XKB_CONFIG_ROOT=/usr/share/X11/xkb" >> /etc/profile
source /etc/profile
xvfb-run wkhtmltopdf https://g3n1k.wordpress.com g3n1k.pdf

# if the fonts become reactangle
# copy all your font to /usr/share/fonts
ls /usr/share/fonts/
fc-cache
yum install -y ghostscript

mysql – master to master replication

https://www.digitalocean.com/community/tutorials/how-to-set-up-mysql-master-master-replication

“MySQL replication is the process by which a single data set, stored in a MySQL database, will be live-copied to a second server. This configuration, called “master-slave” replication, is a typical setup. Our setup will be better than that, because master-master replication allows data to be copied from either server to the other one. This subtle but important difference allows us to perform mysql read or writes from either server. This configuration adds redundancy and increases efficiency when dealing with accessing the data.”

mysql01: 192.168.2.36

$ echo "192.168.2.36	mysql01" >> /etc/hosts
$ echo "192.168.2.37	mysql02" >> /etc/hosts
$ sudo apt-get install mysql-server mysql-client -y
$ sudo nano /etc/mysql/mysql.conf.d/mysqld.cnf

#bind-address = mysql01
server-id = 1
log_bin = /var/log/mysql/mysql-bin.log
expire_logs_days = 10
max_binlog_size = 100M
binlog_do_db = example
#binlog_ignore_db = include_database_name

$ mysql -u root -p

mysql> create user 'replicator'@'%' identified by 'password';
Query OK, 0 rows affected (0.01 sec)

mysql> grant replication slave on *.* to 'replicator'@'%';
Query OK, 0 rows affected (0.00 sec)

mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000003 |      154 | example      |                  |                   |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

# get the log file and log post in server2

mysql> stop slave;
Query OK, 0 rows affected (0.00 sec)

mysql> change master to master_host='mysql02', master_user='replicator', master_password='password', master_log_file='mysql-bin.000003',master_log_pos=154;
Query OK, 0 rows affected, 2 warnings (0.02 sec)

mysql> start slave;
Query OK, 0 rows affected (0.00 sec)

mysql02: 192.168.2.37

$ echo "192.168.2.36	mysql01" >> /etc/hosts
$ echo "192.168.2.37	mysql02" >> /etc/hosts
$ sudo apt-get install mysql-server mysql-client -y
$ sudo nano /etc/mysql/mysql.conf.d/mysql02.cnf

bind-address = mysql02
server-id = 2
log_bin = /var/log/mysql/mysql-bin.log
expire_logs_days = 10
max_binlog_size = 100M
binlog_do_db = example
#binlog_ignore_db = include_database_name

$ sudo service mysql restart

mysql> create user 'replicator'@'%' identified by 'password'; 
Query OK, 0 rows affected (0.01 sec)

mysql> grant replication slave on *.* to 'replicator'@'%'; 
Query OK, 0 rows affected (0.00 sec)

mysql> create database example; 
Query OK, 1 row affected (0.01 sec)

mysql> change master to master_host = "192.168.0.104", master_user = "replicator", master_password = "password", master_log_file = "mysql-bin.000001", master_log_pos = 607;
Query OK, 0 rows affected, 2 warnings (0.03 sec)

mysql> stop slave;
Query OK, 0 rows affected (0.00 sec)

mysql> change master to master_host='mysql01', master_user='replicator', master_password='password', master_log_file='mysql-bin.000003',master_log_pos=154;
Query OK, 0 rows affected, 2 warnings (0.02 sec)

mysql> start slave;
Query OK, 0 rows affected (0.00 sec)

mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000003 |      154 | example      |                  |                   |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

mysql> stop slave;
Query OK, 0 rows affected (0.00 sec)

mysql> change master to master_host='mysql01', master_user='replicator', master_password='password', master_log_file='mysql-bin.000003',master_log_pos=154;
Query OK, 0 rows affected, 2 warnings (0.02 sec)

mysql> start slave;
Query OK, 0 rows affected (0.00 sec)

Doing test write from mysql01

mysql > use example;

mysql> create table example.testuser(id int, name varchar(20));

mysql > INSERT INTO `testuser` (`id`, `name`) VALUES (1, 'indra sadik');

mysql > INSERT INTO `testuser` (`id`, `name`) VALUES (2, 'indradhi');

mysql > select * from `testuser`;

mysql> select * from example.testuser;
+------+-------------+
| id   | name        |
+------+-------------+
|    1 | indra sadik |
|    2 | indradhi    |
+------+-------------+
2 rows in set (0.00 sec)

mysql>

Doing test write from mysql02

mysql > use example;

mysql> select * from example.testuser;
+------+-------------+
| id   | name        |
+------+-------------+
|    1 | indra sadik |
|    2 | indradhi    |
+------+-------------+
2 rows in set (0.00 sec)

mysql > INSERT INTO `testuser` (`id`, `name`) VALUES (3, 'denly');

mysql> select * from example.testuser;
+------+-------------+
| id   | name        |
+------+-------------+
|    1 | indra sadik |
|    2 | indradhi    |
|    3 | denly       |
+------+-------------+
3 rows in set (0.00 sec)

Doing test read from mysql01

mysql> select * from example.testuser;
+------+-------------+
| id   | name        |
+------+-------------+
|    1 | indra sadik |
|    2 | indradhi    |
|    3 | denly       |
+------+-------------+
3 rows in set (0.00 sec)

postgresql – pointing postgresql data to new location

Database grow over time, it out growing the space on their partition located.
in redhat 6.7, the default partition for “/” its 50GB and the rest going to “/home” partition.
when you default install postgresql-9.5 it would located in “/opt” which include in “/” partition.
for database production 50GB it’s so small. so i want change the data folder to “/home” which have TB space.

#status postgres
$ /etc/init.d/postgresql-9.5 status
pg_ctl: server is running (PID: 6309)
/opt/PostgreSQL/9.5/bin/postgres "-D" "/opt/PostgreSQL/9.5/data"

# stop postgres
$ service postgresql-9.5 stop
$ /etc/init.d/postgresql-9.5 status
pg_ctl: no server running

# change variable
$ nano /opt/PostgreSQL/9.5/pg_env.sh

export PGDATA=/opt/PostgreSQL/9.5/data
change to
export PGDATA=/home/pg_data

# create dir
$ mkdir -p /home/pg_data

# doing rsync
$ rsync -azP /opt/PostgreSQL/9.5/data/ /home/pg_data/

# just make sure
$ mv /opt/PostgreSQL/9.5/data /opt/PostgreSQL/9.5/data_bak

# backup service script
$ mkdir -p ~/backup/ && mv /etc/rc.d/init.d/postgresql-9.5 ~/backup/

# download postgresql-9.5 file
$ wget https://raw.githubusercontent.com/g3n1k/exsys/master/postgresql-9.5

# move postgresql-9.5 to /etc/rc.d/init.d/
$ mv postgresql-9.5 /etc/rc.d/init.d/

# start postgresql
$ service postgresql-9.5 start

# status postgresql
$ service postgresql-9.5 status
pg_ctl: server is running (PID: 13282)
/opt/PostgreSQL/9.5/bin/postgres "-D" "/home/pg_data"

node.js – express generator with bootstrap

# set express
$ cd ~/tmp/ && express msg_server && cd msg_server && npm install && npm update

# change from jade to pug
# https://g3n1k.wordpress.com/2017/06/30/node-js-express_generator-from-jade-to-pug/

# download bootstrap 3, extract it
$ cd ~/tmp/ && wget https://github.com/twbs/bootstrap/releases/download/v3.3.7/bootstrap-3.3.7-dist.zip && unzip bootstrap-3.3.7-dist.zip && cd bootstrap-3.3.7-dist

# copy file-file bootstrap to express project folder
$ cp ~/tmp/bootstrap-3.3.7-dist/css/bootstrap.min.css ~/tmp/msg_server/public/stylesheets/bootstrap.min.css
$ cp ~/tmp/bootstrap-3.3.7-dist/js/bootstrap.min.js ~/tmp/msg_server/public/javascripts/bootstrap.min.js
$ cp ~/tmp/bootstrap-3.3.7-dist/fonts ~/tmp/msg_server/public/ -r

# change view/layout.pug
$ nano view/layout.pug
doctype html
html
	head
		meta(charset='utf-8')
		meta(http-equiv='X-UA-Compatible', content='IE=edge')
		meta(name='viewport', content='width=device-width, initial-scale=1')
		meta(name='description', content='')
		meta(name='author', content='')
		link(rel='icon', href='/images/favicon.ico')
		title #{title} | Express Website
		link(href='/stylesheets/bootstrap.min.css', rel='stylesheet')
		link(href='/stylesheets/style.css', rel='stylesheet')
	body
		nav.navbar.navbar-inverse.navbar-fixed-top
			.container
				.navbar-header
					button.navbar-toggle.collapsed(type='button', data-toggle='collapse', data-target='#navbar', aria-expanded='false', aria-controls='navbar')
						span.sr-only Toggle navigation
						span.icon-bar
						span.icon-bar
						span.icon-bar
					a.navbar-brand(href='#') MSG Server
				#navbar.collapse.navbar-collapse
					ul.nav.navbar-nav
						li(class=(title === 'Home' ? 'active' : ''))
							a(href='/') Home
						li(class=(title === 'About' ? 'active' : ''))
							a(href='/about') About
						li(class=(title === 'Contact' ? 'active' : ''))
							a(href='/contact') Contact
		
		block content

		footer
			p © 2017 All Right Reserved

		script(src='https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js')
		script(src='/javascripts/bootstrap.min.js')
# and change view/index.pug
$ nano view/index.pug
extends layout

block content
	.jumbotron
		.container
			h1 How May I Help You
			p Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam ut faucibus tortor, sit amet congue elit. 
			a.btn.btn-primary.btn-lg(href='#') Learn more »
	.container
		.row
			.col-md-4
				h2 About Us
				p  Mauris eget neque egestas, rhoncus ipsum quis, faucibus diam. Nunc in lacus ac magna dapibus suscipit pellentesque et lectus.
				a.btn.btn-default(href='#') View Detail
			.col-md-4
				h2 Services
				p  Mauris eget neque egestas, rhoncus ipsum quis, faucibus diam. Nunc in lacus ac magna dapibus suscipit pellentesque et lectus.
				a.btn.btn-default(href='#') View Detail
			.col-md-4
				h2 Get In Touch
				p  Mauris eget neque egestas, rhoncus ipsum quis, faucibus diam. Nunc in lacus ac magna dapibus suscipit pellentesque et lectus.
				a.btn.btn-default(href='#') View Detail

# fire up server and test
$ npm start

rhel 67 – shrink expand lvm partition

the default rhel 6.7 partition, “/” partition only have 50GB and the “/home” get the rest

if you only have 90GB for rhel, it would splitĀ  / to 50GB and /home 40GB. but if you have TeraByte space / get 50GB and /home get TeraByte

problem when you use / for default database storage, which store the data in / partition, 50GB so small for database.

the advantage using lvm partition, you can shrink the partition, and give the free space for other partition

i will try reduce /home space and add it to

# test
[root@rhel67 ~]# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/vg_rhel67-lv_root
 50G 1.9G 45G 4% /
tmpfs 1.9G 0 1.9G 0% /dev/shm
/dev/sda1 477M 41M 411M 10% /boot
/dev/mapper/vg_rhel67-lv_home
 45G 52M 43G 1% /home

[root@rhel67 ~]# pvs
  PV         VG        Fmt  Attr PSize  PFree
  /dev/sda2  vg_rhel67 lvm2 a--  99.51g    0 

[root@rhel67 ~]# vgs
  VG        #PV #LV #SN Attr   VSize  VFree
  vg_rhel67   1   3   0 wz--n- 99.51g    0 

[root@rhel67 ~]# lvs
  LV      VG        Attr       LSize  Pool Origin Data%  Meta%  Move Log Cpy%Sync Convert
  lv_home vg_rhel67 -wi-ao---- 45.63g                                                    
  lv_root vg_rhel67 -wi-ao---- 50.00g                                                    
  lv_swap vg_rhel67 -wi-ao----  3.88g
  
# step to reduce
[root@rhel67 ~]# umount /home

# check system error
[root@rhel67 ~]# e2fsck -ff /dev/mapper/vg_rhel67-lv_home
e2fsck 1.41.12 (17-May-2010)
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
/dev/mapper/vg_rhel67-lv_home: 11/2992416 files (0.0% non-contiguous), 233857/11962368 blocks

# now cut the space
[root@rhel67 ~]# resize2fs /dev/mapper/vg_rhel67-lv_home 20G
resize2fs 1.41.12 (17-May-2010)
Resizing the filesystem on /dev/mapper/vg_rhel67-lv_home to 5242880 (4k) blocks.
The filesystem on /dev/mapper/vg_rhel67-lv_home is now 5242880 blocks long.

# resize authority
[root@rhel67 ~]# lvreduce -L -19G /dev/mapper/vg_rhel67-lv_home  
  WARNING: Reducing active logical volume to 26.63 GiB
  THIS MAY DESTROY YOUR DATA (filesystem etc.)
Do you really want to reduce lv_home? [y/n]: y
  Size of logical volume vg_rhel67/lv_home changed from 45.63 GiB (11682 extents) to 26.63 GiB (6818 extents).
  Logical volume lv_home successfully resized

[root@rhel67 ~]# lvdisplay /dev/vg_rhel67/lv_home
  --- Logical volume ---
  LV Path                /dev/vg_rhel67/lv_home
  LV Name                lv_home
  VG Name                vg_rhel67
  LV UUID                TG9ipf-EeEA-jKN6-BrG2-J3Gx-mXz2-tylb4X
  LV Write Access        read/write
  LV Creation host, time rhel67, 2017-07-04 04:05:41 +0700
  LV Status              available
  # open                 0
  LV Size                26.63 GiB
  Current LE             6818
  Segments               1
  Allocation             inherit
  Read ahead sectors     auto
  - currently set to     256
  Block device           253:2

[root@rhel67 ~]# bc
bc 1.06.95
Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc.
This is free software with ABSOLUTELY NO WARRANTY.
For details type `warranty'. 
1024*20
20480
2048/4
512

[root@rhel67 ~]# lvreduce -l -512 /dev/vg_rhel67/lv_home
  WARNING: Reducing active logical volume to 24.63 GiB
  THIS MAY DESTROY YOUR DATA (filesystem etc.)
Do you really want to reduce lv_home? [y/n]: y
  Size of logical volume vg_rhel67/lv_home changed from 26.63 GiB (6818 extents) to 24.63 GiB (6306 extents).
  Logical volume lv_home successfully resized

[root@rhel67 ~]# resize2fs /dev/vg_rhel67/lv_home
resize2fs 1.41.12 (17-May-2010)
Resizing the filesystem on /dev/vg_rhel67/lv_home to 6457344 (4k) blocks.
The filesystem on /dev/vg_rhel67/lv_home is now 6457344 blocks long.

[root@rhel67 ~]# mount /dev/vg_rhel67/lv_home /home

[root@rhel67 ~]# df -h
Filesystem            Size  Used Avail Use% Mounted on
/dev/mapper/vg_rhel67-lv_root
                       50G  1.9G   45G   4% /
tmpfs                 1.9G     0  1.9G   0% /dev/shm
/dev/sda1             477M   41M  411M  10% /boot
/dev/mapper/vg_rhel67-lv_home
                       25G   44M   23G   1% /home

# now check
[root@rhel67 ~]# vgdisplay
  --- Volume group ---
  VG Name               vg_rhel67
  System ID             
  Format                lvm2
  Metadata Areas        1
  Metadata Sequence No  6
  VG Access             read/write
  VG Status             resizable
  MAX LV                0
  Cur LV                3
  Open LV               3
  Max PV                0
  Cur PV                1
  Act PV                1
  VG Size               99.51 GiB
  PE Size               4.00 MiB
  Total PE              25474
  Alloc PE / Size       20098 / 78.51 GiB
  Free  PE / Size       5376 / 21.00 GiB
  VG UUID               DYk8Up-pACU-XZco-ZuEw-iXLL-G98b-gDUSyP
   
[root@rhel67 ~]# pvs
  PV         VG        Fmt  Attr PSize  PFree 
  /dev/sda2  vg_rhel67 lvm2 a--  99.51g 21.00g

[root@rhel67 ~]# lvs
  LV      VG        Attr       LSize  Pool Origin Data%  Meta%  Move Log Cpy%Sync Convert
  lv_home vg_rhel67 -wi-ao---- 24.63g                                                    
  lv_root vg_rhel67 -wi-ao---- 50.00g                                                    
  lv_swap vg_rhel67 -wi-ao----  3.88g

# check how much freespace 
[root@rhel67 ~]# pvscan
  PV /dev/sda2   VG vg_rhel67   lvm2 [99.51 GiB / 21.00 GiB free]
  Total: 1 [99.51 GiB] / in use: 1 [99.51 GiB] / in no VG: 0 [0   ]

[root@rhel67 ~]# vgdisplay
  --- Volume group ---
  VG Name               vg_rhel67
  System ID             
  Format                lvm2
  Metadata Areas        1
  Metadata Sequence No  6
  VG Access             read/write
  VG Status             resizable
  MAX LV                0
  Cur LV                3
  Open LV               3
  Max PV                0
  Cur PV                1
  Act PV                1
  VG Size               99.51 GiB
  PE Size               4.00 MiB
  Total PE              25474
  Alloc PE / Size       20098 / 78.51 GiB
  Free  PE / Size       5376 / 21.00 GiB
  VG UUID               DYk8Up-pACU-XZco-ZuEw-iXLL-G98b-gDUSyP

# check size partition
[root@rhel67 ~]# df -h
Filesystem            Size  Used Avail Use% Mounted on
/dev/mapper/vg_rhel67-lv_root
                       50G  1.9G   45G   4% /
tmpfs                 1.9G     0  1.9G   0% /dev/shm
/dev/sda1             477M   41M  411M  10% /boot
/dev/mapper/vg_rhel67-lv_home
                       25G   44M   23G   1% /home

# now expand the freespace
[root@rhel67 ~]# resize2fs /dev/vg_rhel67/lv_root 
resize2fs 1.41.12 (17-May-2010)
Filesystem at /dev/vg_rhel67/lv_root is mounted on /; on-line resizing required
old desc_blocks = 4, new_desc_blocks = 5
Performing an on-line resize of /dev/vg_rhel67/lv_root to 18612224 (4k) blocks.
The filesystem on /dev/vg_rhel67/lv_root is now 18612224 blocks long.

# check again the size
[root@rhel67 ~]# df -h
Filesystem            Size  Used Avail Use% Mounted on
/dev/mapper/vg_rhel67-lv_root
                       70G  1.9G   65G   3% /
tmpfs                 1.9G     0  1.9G   0% /dev/shm
/dev/sda1             477M   41M  411M  10% /boot
/dev/mapper/vg_rhel67-lv_home
                       25G   44M   23G   1% /home

node.js – express_generator from jade to pug

when using express generator default will using jade as template generator, the problem is jade is renamed with pug. when it running will out warn deprecated message

npm WARN deprecated jade@1.11.0: Jade has been renamed to pug, ...

this how I set up express, express_generator and using it to generate folder for project

# install express and express_generator
$ npm install -g express
$ npm install -g express_generator

# set using express to generate our project
$ mkdir -p ~/projects && cd ~/projects
$ express web_rest && cd web_rest

# open package.json file
$ nano package.json
# change jade to pug (line 14)
# "jade": "1.11.0",
# to
# "pug": "^2.0.0-rc.2",

# open app.js
$ nano app.js
# change view engine to pug (line 15)
# app.set('view engine', 'jade');
# to 
# app.set('view engine', 'pug');

# rename all jade extention to pug in views folder
$ cd views
$ mv error.jade error.pug
$ mv index.jade index.pug
$ mv layput.jade layout.pug

# back to main dir
$ cd ..

# install node_module
$ npm install
# install start, start will using to for running the server
# check file package.json for script
$ npm install -g start

# start the project
$ npm start

# test with curl
$ curl http://localhost:3000