kuroの覚え書き

96の個人的覚え書き

NFSで解析用ディレクトリを共有する

serverが2台になったのでとりあえず一つのディスク領域を共有してデータ解析を分散させたい。そのために入出力するデータの置き場は1箇所にまとめておきたいのでnfsサーバを立ててそこに共有フォルダを置く。
server2(10.0.1.101)にnfsサーバーを立て、server1(10.0.1.100)からマウントする。

まずはサーバー側の準備
server2にnfs-serverをインストール

# yum install nfs-utils 

共有ディレクトリを作成。/home/以下にディレクトリを作り、オーナー、グループは共有したいユーザーのものにしておく。

# mkdir /home/nfs
# chown <user name> /home/nfs
# chgrp <user name> /home/nfs 

nfsの設定ファイルを作成。今回は同じサブネット内のマシンからだけ参照できるようにしておく。

# nano /etc/exports
    /home/nfs 10.0.1.0/24(rw,no_root_squash)

nfs-server起動

# systemctl start rpcbind nfs-server

rpcbindはcentos7ではデフォルトでインストールされて自動起動しているらしいのだが、念の為。

最後にfirewallを使っているので、お約束の

# firewall-cmd --add-service=nfs --permanent
# firewall-cmd --reload


次にクライアント側の準備
2台のサーバーに同じ名前でユーザーを作ってあるが、作成の手順の都合でUID、GIDが別のものになってしまっていたので、これを修正。server2で

$ id -u <user name>
 1001

のようになっていたのでserver1にrootでログインして

# usermod -u 1001 <user name>
# groupmod -g 1001 <user name>

というふうに変えてやる。
マウントポイントを作っておく

$ mkdir /home/<user name>/analysis

そのうえで

# mount -t nfs 10.0.1.101:/home/nfs /home/<user name>/analysis

とすればマウントは完了し、同じユーザーなら自由に読み書きできるはず。
起動時に自動でマウントできるように/etc/fstabに以下の記述を追加しておく

10.0.1.101:/home/nfs /home/<user name>/analysis nfs user,noauto,rw   0 0

TORQUEジョブスケジューラをインストールする。

最終的にはヘッドノードを独立させて、計算ノードはネットワークブートで運用しようと思うが、まずは2ノードでそれぞれHDDでブートして一方がヘッドノードも兼ねるという構成で構築実験をしてみようと思う。

https://qiita.com/yf_xa/items/6042619a5d1a3decf8eb
http://tech.ckme.co.jp/torque.shtml

まずは情報収集から

Centos7へのインストール手順
rootになって

yum install -y epel-release
yum install -y torque-client torque-mom torque-server torque-scheduler

create-munge-key

pbs_server -t create -f -D &    #サーバプロファイルを作成
pbs_server_pid=$!

kill $pbs_server_pid    #pbs_serverが起動するので一旦終了させる

echo "$HOSTNAME np=$(nproc) num_node_boards=1 numa_board_str=$(nproc)" > /var/lib/torque/server_priv/nodes

echo "HostA" > /etc/torque/server_name    #ヘッドノードのホスト名を記述

yumでバイナリをインストールするとNUMAが有効化されているため
num_node_boards=1 numa_board_str=$(nproc)
をちゃんと設定しておく必要があるようだ。

# nano /var/lib/torque/mom_priv/config

$pbsserver localhost

$pbsserver HostA
に書き換える。

# サーバを起動する
systemctl start munge
systemctl start trqauthd
systemctl start pbs_server
systemctl start pbs_sched
systemctl start pbs_mom
systemctl enable munge trqauthd pbs_server pbs_sched pbs_mom

# キューを設定する。 キューの名前はここではbatchとしている。
qmgr -c "create queue batch queue_type=execution"
qmgr -c "set queue batch started=true"
qmgr -c "set queue batch enabled=true"
qmgr -c "set queue batch resources_default.nodes=1"
qmgr -c "set queue batch resources_default.walltime=3600"
qmgr -c "set server default_queue=batch"
qmgr -c "set server scheduling=true"

設定の確認

# qmgr -c 'p s'

    #
    # Create queues and set their attributes.
    #
    #
    # Create and define queue batch
    #
    create queue batch
    set queue batch queue_type = Execution
    set queue batch resources_default.nodes = 1
    set queue batch resources_default.walltime = 01:00:00
    set queue batch enabled = True
    set queue batch started = True
    #
    # Set server attributes.
    #
    set server scheduling = True
    set server acl_hosts = HostA
    set server acl_hosts += localhost
    set server default_queue = batch
    set server log_events = 511
    set server mail_from = adm
    set server scheduler_iteration = 600
    set server node_check_rate = 150
    set server tcp_timeout = 300
    set server job_stat_rate = 45
    set server poll_jobs = True
    set server mom_job_sync = True
    set server next_job_number = 0
    set server moab_array_compatible = True
    set server nppcu = 1

これでサーバは起動したはず。

# pbsnodes -a
HostA-0
     state = free
     np = 16
     ntype = cluster
     status = rectime=1530434061,varattr=,jobs=,state=free,netload=? 0,gres=,loadave=0.00,ncpus=8,physmem=6282540kb,availmem=5407296kb,totmem=6282540kb,idletime=293,nusers=0,nsessions=0,uname=Linux HostA 3.10.0-862.el7.x86_64 #1 SMP Fri Apr 20 16:44:24 UTC 2018 x86_64,opsys=linux
     mom_service_port = 15002
     mom_manager_port = 15003

こんな感じになってたらいいみたい。
試しにジョブを投げてみる。

$ echo "sleep 30" | qsub
 0.HostA

qsubは一般ユーザーでしかできない。

$ qstat
Job ID                    Name             User            Time Use S Queue
------------------------- ---------------- --------------- -------- - -----
0.HostA                   STDIN            user name              0 R batch  

こんな感じ。

さて、このインストールだとヘッドノード1台で計算ノードも兼ねている状態なので、計算ノードをもう1台加えたい。

https://heavywatal.github.io/dev/torque.html
http://mumeiyamibito.0am.jp/doku.php/サーバ関連/torque_pbs

どうも的確な情報がcentos7について得られないな。
結局、以下のような手順でうまくいった(ような気がする)
まず、クライアント(計算ノード)に

# yum install -y epel-release
# yum install -y torque-client torque-mom

とインストール。

# nano /etc/torque/server_name

    HostA

でサーバー名としてヘッドノードのhostnameを書き込み、

# nano /var/lib/torque/mom_priv/config 

    $pbsserver HostA

でサーバーと同様に$pbsserverを書き換えた。

firewallの設定として

# firewall-cmd --add-port=15001/tcp --zone=public --permanent
# firewall-cmd --add-port=15002/tcp --zone=public --permanent
# firewall-cmd --add-port=15003/tcp --zone=public --permanent
# firewall-cmd --add-port=15003/udp --zone=public --permanent
# firewall-cmd --add-port=15004/tcp --zone=public --permanent

と15001〜15004を開けてやり、

]# systemctl start pbs_mom

とクライアントを起動。
いっぽうヘッドノード側で

# nano /var/lib/torque/server_priv/nodes 

    HostA np=16 num_node_boards=1 numa_board_str=16
    HostB np=16 num_node_boards=1 numa_board_str=16

というふうに計算ノードのhostを書き加えてやる。
最後にヘッドノード側も

# firewall-cmd --add-port=15001/tcp --zone=public --permanent
# firewall-cmd --add-port=15002/tcp --zone=public --permanent
# firewall-cmd --add-port=15003/tcp --zone=public --permanent
# firewall-cmd --add-port=15003/udp --zone=public --permanent
# firewall-cmd --add-port=15004/tcp --zone=public --permanent

と、穴を開けてやって、

# systemctl restart munge trqauthd pbs_server pbs_sched pbs_mom

これにて無事

# pbsnodes -a
HostA-0
     state = free
     np = 16
     ntype = cluster
     status = rectime=1530457230,varattr=,jobs=,state=free,netload=? 0,gres=,loadave=0.00,ncpus=8,physmem=6282540kb,availmem=5434500kb,totmem=6282540kb,idletime=534,nusers=0,nsessions=0,uname=Linux HostA 3.10.0-862.el7.x86_64 #1 SMP Fri Apr 20 16:44:24 UTC 2018 x86_64,opsys=linux
     mom_service_port = 15002
     mom_manager_port = 15003

HostB-0
     state = free
     np = 16
     ntype = cluster
     status = rectime=1530457230,varattr=,jobs=,state=free,netload=? 0,gres=,loadave=0.00,ncpus=8,physmem=6249708kb,availmem=5227160kb,totmem=6249708kb,idletime=3094,nusers=0,nsessions=0,uname=Linux HostB 3.10.0-862.3.3.el7.x86_64 #1 SMP Fri Jun 15 04:15:27 UTC 2018 x86_64,opsys=linux
     mom_service_port = 15002
     mom_manager_port = 15003

このように2ノードがクラスタとして使えるようになった。


さて、来週には新規購入で新品のヘッドノードが届くが、こいつをPXEブートと組み合わせてうまく設定できるだろうか?ちょっと不安。

CentOS7のインストール再び

server2にもHDDを入れることにしたので、インストール再び。server1のHDDをserver2に差し替えてみたら、SAS raid コントローラの型番が違っていてraidがぶっ壊れてしまったので、server1の方も再インストールのおまけ付き。

まずは最小インストール。ネットワークの設定を固定IPでやっとく。キーボードレイアウトも確認のこと。
(あとでも変更可能ではあるが)

ユーザーの追加/ユーザーにsudo権限を与える。
https://qiita.com/Esfahan/items/a159753d156d23baf180

# useradd kuro
# passwd kuro
# usermod -aG wheel kuro #wheelグループに入れる(wheelグループはsu権限が付与されている>visudo)


wgetを入れておく

# yum install -y wget


linuxbrewのインストール(rootで実行してはいけない)
http://linuxbrew.sh

$ sh -c "$(curl -fsSL https://raw.githubusercontent.com/Linuxbrew/install/master/install.sh)"

そしてbrewを使いたいユーザ毎に

$ test -d ~/.linuxbrew && PATH="$HOME/.linuxbrew/bin:$HOME/.linuxbrew/sbin:$PATH"
$ test -d /home/linuxbrew/.linuxbrew && PATH="/home/linuxbrew/.linuxbrew/bin:/home/linuxbrew/.linuxbrew/sbin:$PATH"
$ test -r ~/.bash_profile && echo "export PATH='$(brew --prefix)/bin:$(brew --prefix)/sbin'":'"$PATH"' >>~/.bash_profile

を実施
一般ユーザの自分のホームあたりで

$ brew install hello

とやって最初のインストール。


httpdのインストール

# yum install -y httpd

で、

# systemctl start httpd
# systemctl enable httpd

そしてfirewalldに穴を開ける

# firewall-cmd --add-service=http --zone=public --permanent
# firewall-cmd --reload

これでアクセスは可能になった。
次にホームディレクトリにおいたページにアクセスできるようにする。

# nano /etc/httpd/conf.d/userdir.conf
    #UserDir disabled #コメントアウト
    UserDir public_html  #コメントを外す
<Directory "/home/*/public_html">
    AllowOverride All     # 変更
    Options None     # 変更
    Require method GET POST OPTIONS
</Directory>

ディレクトリのパーミッションを調節する

$ chmod 711 /home/kuro
$ chmod 755 /home/kuro/public_html 

そしてもう一点、SELinuxを無効化する

# nano /etc/selinux/config

SELINUX=disabled     # enforcing → disabled

設定を有効にするには再起動が必要。
即時に(ただし一時的に)SELinuxを無効化するには

# setenforce 0

とりあえずこんなところか。


gnomeデスクトップを入れる。

# yum groupinstall "GNOME Desktop"

ユーザーをuseraddでいくつか作ったあとにgnomeをインストールすると、なぜかstartxで失敗するユーザーができてしまう。原因はいろいろあるようだが、ファイル、ディレクトリのパーミッションが不正なことが多いようだ。今回はなぜか/home//.cacheのown/grpがroot/rootになっていてstartxできないということになっていた。chown, chgrpで解決。

vnc serverを立ち上げる。

# yum install tigervnc-server

各ユーザ毎に

$ vncpasswd

でパスワードを設定しておく。
で、ユーザー毎に

$ vncserver:1

という感じにサーバーを起動してやる。
最後にお約束のfirewalldに穴

# firewall-cmd --permanent --zone=public --add-service=vnc-server
# firewall-cmd --reload

macとのデータ運搬のためhfs+のUSB HDDをマウントする

# rpm -Uvh http://www.elrepo.org/elrepo-release-7.0-2.el7.elrepo.noarch.rpm
# yum install kmod-hfsplus
# parted -l

でHDDのdevice IDを調べる。
今回は

モデル: WD Ext HDD 1021 (scsi)
ディスク /dev/sdb: 1000GB
セクタサイズ (論理/物理): 512B/512B
パーティションテーブル: gpt
ディスクフラグ: 

番号  開始    終了    サイズ  ファイルシステム  名前                  フラグ
 1    20.5kB  210MB   210MB   fat32             EFI System Partition  boot
 2    210MB   1000GB  999GB   hfs+              WD1
 3    1000GB  1000GB  650MB   hfs+              Recovery HD

となっていたので

# mount -t hfsplus -o rw /dev/sdb2 /media/hfs

これでいい。


brewでいろいろインストール

$ brew tap brewsci/science
$ brew tap brewsci/bio
$ brew list
bcftools     cufflinks	gmp	  libmagic	 openssl     samtools	   trimmomatic
berkeley-db  curl	gsl	  libmpc	 patchelf    samtools@0.1  unzip
binutils     eigen	hdf5	  libyaml	 pcre	     sphinx-doc    vcftools
blast	     expat	hello	  linux-headers  perl	     sqlite	   xz
boost	     fastqc	hisat2	  lmdb		 pkg-config  sratoolkit    zlib
bowtie	     gcc	htslib	  m4		 python      stringtie
bwa	     gdbm	isl@0.18  mariadb	 python@2    swig
bzip2	     git	libbsd	  mpfr		 readline    szip
cmake	     glibc	libffi	  ncurses	 ruby	     tab

こんな感じかな。実際にインストールをしたのは
bcftools
blast
bowtie
bwa
cufflinks
fastqc
hisat2
mariadb
perl
python
samtools
trimmomatic
vcftools

brewでインストールしたユーザ以外がpythonを利用する場合、

$ pip3 install xxxx --user

とやると
~/.local/
以下にモジュールがインストールされる模様

サーバのネットワークをうまく組みたい

現状の整理
イントラネットには現状無線LANルータ設置しか申請してないので、サーバも無線LAN下にある。
更に、居室にサーバを置けないので、別室に設置している関係で、無線LANルータからは中継機でwifiを飛ばし接続という回りくどさ。
さらに、server2はHDDレスでPXEブートしているため、server1の下に更にサブネットを形成してdhcpで配信している。基本的に計算作業はネットを参照せず、サーバ内で完結しているので無線LANが作業のボトルネックになったりはしないが、解析前と解析後のデータ転送が遅い(数100GB以上転送することも珍しくはない)ので、現状USBディスクにコピーして運んでいたりする。

とりあえずもう一台ヘッドノードとなるサーバを調達してこれをイントラに直接接続する申請を出すことにしたい。

文字列の大文字を小文字に変換するには

アノテーションファイルと解析結果のファイルで書式が結構違っていて、検索プログラムでうまくリンクしてくれない。そこで、テキストの整形、変換をいろいろと行うのでそのメモ

大文字を小文字に
AT1G12345をat1g12345に置き換えるには

$ cat text.txt | tr '[:upper:]' '[:lower:]' > test1.txt

AT1G12345をAt1g12345に置き換えるなら

$ cat text.txt | tr '[:upper:]' '[:lower:]' | sed -e "s/at/At/" > text2.txt

こんな2段構えが簡単かな。

sed もしくは awk正規表現を使って大文字、小文字を置換する方法もあるようだが、書式が結構面倒なので、スクリプトに仕立てるなら有りだけど、ちょっとした変換ならかえって面倒かな。

IPマスカレード

ずいぶん昔、まだ世の中にネットワークルータというハードウェアがほとんどなく、あったとしてもマニアックな超高級品であった時代、Linux-boxをルータとして使うIP-Masqueradeを組んだ・・・というのがLinuxとの最初の出会いであったなあ・・・(遠い目

時代はうつり、今や無線LANルーターがほとんどの家庭にあって、無線帯域を奪い合うような事態になっているわけだが。
さて、サーバを2台にしたことで外に出ているサーバは1台だけにして、もう1台は内側にサブネットを作って入れてしまう、という形になったので、懐かしのIP-Masqueradeの出番と相成った。今どき1000円もしないルータで設定もしないでそのまま使えてしまう機能なわけだが、Linuxでやるとなると、それなりの設定手順を踏まねばならない。

Centos7の場合、基本firewall-cmdでゴニョゴニョすることになる。
現状、

$ sudo firewall-cmd --get-active-zone
public
  interfaces: ens1f0 enp4s0f0

こんな感じに2つのインターフェースはzone=publicで対等な感じになっている。
これを、まずは内向き、外向きに分けてやる。

$ sudo nmcli c mod ens1f0 connection.zone external
$ sudo nmcli c mod enp4s0f0 connection.zone internal
$ sudo firewall-cmd --get-active-zone
internal
  interfaces: enp4s0f0
external
  interfaces: ens1f0

そして、zone=externalに対して

$ sudo firewall-cmd --zone=external --add-masquerade --permanent
$ sudo firewall-cmd --reload
 sudo firewall-cmd --zone=external --query-masquerade
yes
$ sudo cat /proc/sys/net/ipv4/ip_forward
1

なお、ここまでの各種設定でfirewall-cmdでポートを開いて来ていたが、すべてzone=publicで設定していたので、すべての設定をzone=externalかzone=internalかに振り分けてやっておかないと、色々なサービスが動かない、という目に遭う。

これでいいはずなんだけど、なんだかまだ内から外に出ていけない。何かがおかしい。

あと、internalはすべてオープンということでzone=trustedという設定にする例もアチラコチラで見られるのだが。


解決。
DHCPのデフォルトルーティングの設定が間違っていた。

クラスタにするかただの並列にするか

https://qiita.com/yubais/items/7c40227a17569dc9d412

http://www.kurobuti.com/linux_server/?page_id=58


ディスクレスクライアント
https://www.server-world.info/query?os=CentOS_7&p=pxe&f=4

まずは入れてみる。
最初に導入したサーバーのイーサネットポートは4つついていたので、1つは外向き、1つは内向きのネットを作ってネット空間を分けてしまう。そして内向きにdhcpサーバ、tftpサーバ、nfsサーバを立てて、ブートさせることを目指す。

tftpサーバーのインストール&起動
$ sudo yum install syslinux xinetd tftp-server
$ sudo mkdir /var/lib/tftpboot/pxelinux.cfg
$ sudo cp /usr/share/syslinux/pxelinux.0 /var/lib/tftpboot/
$ sudo nano /etc/xinetd.d/tftp

# default: off
# description: The tftp server serves files using the trivial file transfer \
#	protocol.  The tftp protocol is often used to boot diskless \
#	workstations, download configuration files to network-aware printers, \
#	and to start the installation process for some operating systems.
service tftp
{
        socket_type             = dgram
        protocol                = udp
        wait                    = yes
        user                    = root
        server                  = /usr/sbin/in.tftpd
        server_args             = -s /var/lib/tftpboot
        disable                 = no
        per_source              = 11
        cps                     = 100 2
        flags                   = IPv4
}

$ sudo systemctl start xinetd.service
$ sudo systemctl enable xinetd.service

dhcpサーバーのインストール&起動
$ sudo yum install dhcp
$ sudo nano /etc/dhcp/dhcpd.conf

#
# DHCP Server Configuration file.
#   see /usr/share/doc/dhcp*/dhcpd.conf.example
#   see dhcpd.conf(5) man page
#
option domain-name-servers	192.168.1.100;
default-lease-time 600;
max-lease-time 7200;
authritative;
filename        "pxelinux.0";
next-server     192.168.1.100;
subnet 192.168.1.0 netmask 255.255.255.0 {
        range dynamic-bootp 192.168.1.200 192.168.1.254;
        option broadcast-address 192.168.1.255;
        option routers 192.168.1.1;
}

$ sudo systemctl start dhcpd
Job for dhcpd.service failed because the control process exited with error code. See "systemctl status dhcpd.service" and "journalctl -xe" for details.
起動できない・・・
$ sudo systemctl status dhcpd

● dhcpd.service - DHCPv4 Server Daemon
   Loaded: loaded (/usr/lib/systemd/system/dhcpd.service; disabled; vendor preset: disabled)
   Active: failed (Result: exit-code) since 月 2018-06-18 18:12:08 JST; 45s ago
     Docs: man:dhcpd(8)
           man:dhcpd.conf(5)
  Process: 10338 ExecStart=/usr/sbin/dhcpd -f -cf /etc/dhcp/dhcpd.conf -user dhcpd -group dhcpd --no-pid (code=exited, status=1/FAILURE)
 Main PID: 10338 (code=exited, status=1/FAILURE)

 6月 18 18:12:08 guilty-rx200s6 dhcpd[10338]: Not searching LDAP since ldap-server, ldap-port and ldap-base-dn were not sp...g file
 6月 18 18:12:08 guilty-rx200s6 dhcpd[10338]: Wrote 0 leases to leases file.
 6月 18 18:12:08 guilty-rx200s6 dhcpd[10338]: 
 6月 18 18:12:08 guilty-rx200s6 dhcpd[10338]: No subnet declaration for virbr0 (192.168.122.1).
 6月 18 18:12:08 guilty-rx200s6 dhcpd[10338]: ** Ignoring requests on virbr0.  If this is not what
 6月 18 18:12:08 guilty-rx200s6 dhcpd[10338]:    you want, please write a subnet declaration
 6月 18 18:12:08 guilty-rx200s6 systemd[1]: dhcpd.service: main process exited, code=exited, status=1/FAILURE
 6月 18 18:12:08 guilty-rx200s6 systemd[1]: Failed to start DHCPv4 Server Daemon.
 6月 18 18:12:08 guilty-rx200s6 systemd[1]: Unit dhcpd.service entered failed state.
 6月 18 18:12:08 guilty-rx200s6 systemd[1]: dhcpd.service failed.
Hint: Some lines were ellipsized, use -l to show in full.

んーdhcpの起動でコケるのはちゃんとサブネットが作れていないからかな。
とりあえず先に進んでみる。

NFSの導入&起動イメージのインストール
$ sudo yum install dracut-network nfs-utils
$ sudo mkdir -p /var/lib/tftpboot/centos7/root
$ sudo yum groups -y install "Server with GUI" --releasever=7 --installroot=/var/lib/tftpboot/centos7/root/
(GUI有りの場合、もっとシンプルでいい気がする。)
rootのパスワードを生成しておく
$ sudo python3 -c 'import crypt,getpass; print(crypt.crypt(getpass.getpass(), crypt.mksalt(crypt.METHOD_SHA512)))'

Password:

ここで表示される文字列をコピーしておき、

$ sudo nano /var/lib/tftpboot/centos7/root/etc/shadow

root:<ここにコピーした文字列をペースト>:16372:0:99999:7:::

$ sudo wget -P /var/lib/tftpboot/centos7/ http://mirror.centos.org/centos/7/os/x86_64/images/pxeboot/vmlinuz http://mirror.centos.org/centos/7/os/x86_64/images/pxeboot/initrd.img

$ sudo nano /var/lib/tftpboot/pxelinux.cfg/default

default centos7

label centos7
    kernel centos7/vmlinuz
    append initrd=centos7/initrd.img root=nfs:192.168.1.100:/var/lib/tftpboot/centos7/root rw selinux=0

$ sudo nano /etc/exports

/var/lib/tftpboot/centos7/root 192.168.1.0/24(rw,no_root_squash)

$ sudo systemctl start rpcbind nfs-server
$ sudo systemctl enable rpcbind nfs-server
$ sudo nano /var/lib/tftpboot/centos7/root/etc/fstab

none    /tmp        tmpfs   defaults   0 0
tmpfs   /dev/shm    tmpfs   defaults   0 0
sysfs   /sys        sysfs   defaults   0 0
proc    /proc       proc    defaults   0 0

これでネットブート用のシステムは用意できたけど、dhcpがどうにも動かないな。

dhcpサーバが別に立っている場合
http://www.ichily.blog/entry/2017/05/07/DHCPサーバーが存在する環境でPXE_boot用tftpサーバー作る設定
こっちを参考にproxydhcpを使う方法を試す。
今度は2つのサーバを並列に外のネットワークに繋ぎ、dhcpは上位のルータ、tftpを1つ目のサーバに立てるという感じ。
$ sudo nano /var/lib/tftpboot/pxelinux.cfg/default
$ sudo nano /etc/dnsmasq.d/proxydhcp.conf

enable-tftp
tftp-root=/var/lib/tftpboot

# set server as proxy dhcp
dhcp-range=10.0.0.0,proxy

pxe-service=x86PC, "PXE Boot ", "pxelinux", 10.0.0.10
pxe-prompt="press [Enter]"

# boot file
dhcp-boot=./pxelinux.0


これでネットブートを試みるも、やはりうまくいかない。
あっちこっちの情報をくっつけて一発でうまくいくことはあんまりないな。


追記。
サブネットに対してサービスするdhcpについてはちゃんとケーブルを挿して、ネットワークを繋ぐとちゃんと起動することがわかった。なのでproxydhcpはやめにして、普通にPXEブートの設定をしてやったところ上記のやり方で問題なくディスクレスブートできることがわかった。
firewallの設定をdhcpだけじゃなくtftpとnfsについても開けてやる必要はあるようだ。あたりまえか。

sudo firewall-cmd --add-service=dhcp --zone=public --permanent
sudo firewall-cmd --add-service=tftp --zone=public --permanent
sudo firewall-cmd --add-service=nfs --zone=public --permanent
sudo firewall-cmd --reload

複数の列でsort

excelなどでは普通に行える文字列のソート。

shellコマンドでいくつかの列を順にたどってソートするにはkオプションを使うらしい。

例えば

AT1G01000.1:139:G:A
AT1G01000.1:274:T:G
AT1G01000.1:1033:T:A
AT1G01000.1:1034:T:C
AT1G01000.1:1027:C:A
AT1G01000.1:284:C:A
AT1G01000.1:288:T:A
AT1G01000.1:1005:T:C
AT1G01000.1:1010:G:A
AT1G01000.1:1092:G:A
AT1G01000.1:141:A:G
AT1G01010.1:138:T:G
AT1G01010.1:147:A:G
AT1G01010.1:284:A:C
AT1G01010.1:314:C:T
AT1G01010.1:293:G:A
AT1G01010.1:317:G:A

このような遺伝子のSNPリストを遺伝子コード→ポジションの順でソートしたい場合、

まず行の区切りを指定するために

-t ":"

を入れる。よく一緒にパイプで繋いで使うcut では -d ":" のようになるのでややこしいが、-tだ。

次に並び順を1列目の遺伝子コードで行うため

-k 1

と入れる。
続いて2列目のポジションでソートするには

-k 2

と続けたいところだが、ここの書式は1列目のオプションと合わせて

-k 1,1 -k 2

となるらしい。
更に、そのままだとASCIIで並べ替えるので、3桁と4桁の数字が混ざっていると一番上の桁の数字からソートしてしまい、数値順にならないので

-k 1,1 -k 2n

とやることになるらしい。

塩基単位でのread depthを求める

以前BEDToolsのcoverageBedでdepthを各塩基ごとに求める方法を書いた。

$ coverageBed -a genome.bed -b sample.bed -d

というのが基本書式だ。
genome.bedはreference.fasta.faiから

$ awk '{print $1"\t0\t"$2}' reference.fasta.fai > genome.bed

という感じで作成しておく。
さらに、sample.bedはbamにそのまま置き換えてもちゃんと機能するらしいということで

$ coverageBed -a genome.bed -b sample.bam -d > depth.bed

としてやれば良さそうな感じ。
実際それでやってみると

1	0	30427671	1	0
1	0	30427671	2	0
1	0	30427671	3	0
1	0	30427671	4	0
1	0	30427671	5	0
1	0	30427671	6	0
1	0	30427671	7	0
1	0	30427671	8	0
1	0	30427671	9	0
1	0	30427671	10	0
・・・・
1	0	30427671	28106	1
1	0	30427671	28107	1
1	0	30427671	28108	1
1	0	30427671	28109	1
1	0	30427671	28110	1
1	0	30427671	28111	1
1	0	30427671	28112	1
1	0	30427671	28113	1
1	0	30427671	28114	1
1	0	30427671	28115	1
・・・・

こんな感じのファイルが出力されてくる
いわゆるbed3にpositionとdepthが付加された感じかな
ちなみにこのbamファイルで最初に出てくるgenome positionが28106
これからdepth>0のpositionだけを抽出するなら

$ cat depth.bed | grep .'\t'0$ -v > depth1over.bed

などとすると

1	0	30427671	28106	1
1	0	30427671	28107	1
1	0	30427671	28108	1
1	0	30427671	28109	1
1	0	30427671	28110	1
1	0	30427671	28111	1
1	0	30427671	28112	1
1	0	30427671	28113	1
1	0	30427671	28114	1
1	0	30427671	28115	1
・・・・

というふうに0カウントな行が取り除かれる。

さて、coverageBedについての情報をもうちょっと集めてみると、bamファイルから直接処理するなら

$ coverageBed -abam sample.bam -b genome.bed -d > depth.bed

とするようにと書かれていたりする。
これを実際にやってみると

1	28105	28191	NB501315:33:HGYFWBGXY:1:23206:2970:18726	60	+28105	28191	0,0,0	1	86,	0,	1	1
1	28105	28191	NB501315:33:HGYFWBGXY:1:23206:2970:18726	60	+28105	28191	0,0,0	1	86,	0,	2	1
1	28105	28191	NB501315:33:HGYFWBGXY:1:23206:2970:18726	60	+28105	28191	0,0,0	1	86,	0,	3	1
1	28105	28191	NB501315:33:HGYFWBGXY:1:23206:2970:18726	60	+28105	28191	0,0,0	1	86,	0,	4	1
1	28105	28191	NB501315:33:HGYFWBGXY:1:23206:2970:18726	60	+28105	28191	0,0,0	1	86,	0,	5	1
1	28105	28191	NB501315:33:HGYFWBGXY:1:23206:2970:18726	60	+28105	28191	0,0,0	1	86,	0,	6	1
1	28105	28191	NB501315:33:HGYFWBGXY:1:23206:2970:18726	60	+28105	28191	0,0,0	1	86,	0,	7	1
1	28105	28191	NB501315:33:HGYFWBGXY:1:23206:2970:18726	60	+28105	28191	0,0,0	1	86,	0,	8	1
1	28105	28191	NB501315:33:HGYFWBGXY:1:23206:2970:18726	60	+28105	28191	0,0,0	1	86,	0,	9	1
1	28105	28191	NB501315:33:HGYFWBGXY:1:23206:2970:18726	60	+28105	28191	0,0,0	1	86,	0,	10	1

こんな感じの結果が帰ってくる。
どうも、-aの方にsampleが来ることで、readごとにまとめてカウントすることになってしまうようで、これじゃちょっと違う気がする。bed12にpositionとdepthがくっつく形だな。
なお-abamを普通に-aのままbamを与えても、全く同じ結果になるので -abamというオプションをあえて使う意味はなくなっているのかもしれない。


bedtoolsの使い方をいろいろ調べ、試してみているうちに、なかなか良い使い方に出くわした。

$ bedtools intersect -a sample.bam -b background.bam -wa -v > true_candidate.bam

こういう使い方をすると、sample.bamからbackground.bamと重複する領域を持つリードを除いたbamを作ることができるようだ。これは使える。(とおもう)

https://bi.biopapyrus.jp/rnaseq/mapping/format-convert.html
http://kazumaxneo.hatenablog.com/entry/2017/07/23/213505
http://staffblog.amelieff.jp/entry/2012/12/13/112308
https://cell-innovation.nig.ac.jp/surfers/BEDtools.html

このあたり参照

bamファイルから抽出

mappingを行ったbamファイルから更に絞り込みをかけてやる。
具体的にはSNV、INDELを持つreadを取り除いて100%matchしたreadだけにしたい。

基本はsamtools viewでbamを開いて、grepawkで整形をすることになるだろう。

bamはバイナリなので中身が見れないが、samtools view -h sample.bam > sample.samとsamファイルに戻してやって、ファイルをテキストエディタで開いてやると・・・

@HD	VN:1.3	SO:coordinate
@SQ	SN:AT1G51370.2	LN:1118

  ・・・・・・

@SQ	SN:ATMG00930.1	LN:74
@PG	ID:bwa	PN:bwa	VN:0.7.15-r1140	CL:bwa mem -t8 /home/kuro/rnaseq/ref/arabidopsis_thaliana/bwa/TAIR10_cdna_20101214_updated ./trimmed/sample_L001_R1_001_trim_np.fastq.gz
@PG	ID:bwa-4217DAA5	PN:bwa	VN:0.7.15-r1140	CL:bwa mem -t8 /home/kuro/rnaseq/ref/arabidopsis_thaliana/bwa/TAIR10_cdna_20101214_updated ./trimmed/sample_L002_R1_001_trim_np.fastq.gz
@PG	ID:bwa-15F23362	PN:bwa	VN:0.7.15-r1140	CL:bwa mem -t8 /home/kuro/rnaseq/ref/arabidopsis_thaliana/bwa/TAIR10_cdna_20101214_updated ./trimmed/sample_L003_R1_001_trim_np.fastq.gz
@PG	ID:bwa-709CFACE	PN:bwa	VN:0.7.15-r1140	CL:bwa mem -t8 /home/kuro/rnaseq/ref/arabidopsis_thaliana/bwa/TAIR10_cdna_20101214_updated ./trimmed/sample_L004_R1_001_trim_np.fastq.gz
NB501315:33:HGYFWBGXY:4:13505:8929:6100	16	AT1G50920.1	104	60	85M	*	0	0	TATCGATAAGCGAAGATGGTGCAATACAATTTCAAGAAGATCACTGTTGTTCCCAATGGCAAGGAGTTCATTGACATCATCCTCT	EEEEEEEEEEEEEEAEEAEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE//EEEEEEEEEEEEEEEAEEEEEEEEEEEEEAAAAA	NM:i:8	MD:Z:0C19T5T10G6A14G9G13T1	AS:i:52	XS:i:0

  ・・・・・・

こんな感じ。なおこのmappingはリファレンスにアラビのcDNAを使っているので@SQの行が数万行は並んでいる。
@PGがmappingの実施状況を示していて、この場合4つのfastqファイルをTAIR10_cdna_20101214_updatedをリファレンス配列としてマッピングしていることがわかる。

さて、リード情報本体の意味だが
1列目 : NB501315:33:HGYFWBGXY:4:13505:8929:6100  リードの名前
2列目 : 16  flag:リードの状況
3列目:AT1G50920.1  張り付いた染色体,コンティグの名前
4列目:104  張り付いた場所
5列目:60  マッピングスコア
6列目:85M  マッピング状況 この場合85ベースがマッチ(M)
7列目:*  paired-endの時の相方の名前(single-endの場合*)
8列目:0  paired-endの時の相方の場所
9列目:0  paired-endの時のインサートの長さ
10列目:TATCGATAAGCGAAGATGGTGCAATACAATTTCAAGAAGATCACTGTTGTTCCCAATGGCAAGGAGTTCATTGACATCATCCTCT  リードのシークエンス配列
11列目:EEEEEEEEEEEEEEAEEAEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE//EEEEEEEEEEEEEEEAEEEEEEEEEEEEEAAAAA  リードのクオリティ
12列目 : NM:i:8  MD:Z:0C19T5T10G6A14G9G13T1 AS:i:52 XS:i:0  オプションフィールド(TAG:VTYPE:VALUE

2列目のリード状況はいろいろあるようだが、0:マップされている 16:逆相補鎖にマップされている 4:きちんとマップされていない 20:逆相補鎖にきちんとマップされていないの4つが主だったものとなるようだ。

きちんとマップされたリードだけをまずは抽出するのが1つ目。

次に12列目の部分がBWAによって付与されたタグらしく、これを次の抽出ターゲットとする。
BWA generates the following optional fields. Tags starting with ‘X’ are specific to BWA.

Tag Meaning
NM Edit distance
MD Mismatching positions/bases
AS Alignment score
BC Barcode sequence
X0 Number of best hits
X1 Number of suboptimal hits found by BWA
XN Number of ambiguous bases in the referenece
XM Number of mismatches in the alignment
XO Number of gap opens
XG Number of gap extentions
XT Type: Unique/Repeat/N/Mate-sw
XA Alternative hits; format: (chr,pos,CIGAR,NM;)*
XS Suboptimal alignment score
XF Support from forward/reverse alignment
XE Number of supporting seeds

NB501315:33:HGYFWBGXY:1:11308:11940:17581	0	AT1G71100.1	166	52	86M	*	0	0	CTCTAACCTCACCCAAGAAGAACTCAAGAGAATCGCCGCCTATAAGGCTGTCGAATTCGTCGAATCTGGAATGGTCATTGGTCTCG	AAAAAEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE</EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEAEEEEEEEEEE	NM:i:8	MD:Z:3A8G16A9T5A2C26T2C7	AS:i:47	XS:i:0
NB501315:33:HGYFWBGXY:1:23308:20616:13305	0	AT1G71100.1	166	60	86M	*	0	0	CTCAAACCTCACGCAAGAAGAACTCAAGAAAATCGCCGCTTATAAAGCCGTCGAATTCGTCGAATCTGGAATGGTTATCGGTCTCG	AAAAAEEEEEEEEEEAEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEAEEEEEEEEEEEEEEEEEEEEEEEEEEE	NM:i:0	MD:Z:86	AS:i:86	XS:i:0

下がmutationなどなにもないperfect matchで上がmismatchたくさんのread
MD:Z:3A8G16A9T5A2C26T2C7
の意味するところは数字のところは連続でそれだけmatchでATGCのところはその塩基に置換しているという感じのようだ。

NB501315:33:HGYFWBGXY:4:11608:13474:9299	16	AT1G48450.1	196	0	54M32S	*	0	0	GGCTTCATGCGATTCGGCTCCGGACCTCAATTTCGTCTCAGACAAAAGTCTTCTAGACCATTGCAAAGCCGAACTAGTAATGTGAG	EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEAAAAA	NM:i:4	MD:Z:12A1T0A31C6	AS:i:34	XS:i:34	XA:Z:AT1G48450.2,-191,54M32S,4;AT1G48450.3,-196,54M32S,4;

例えばこれだとXAでaltanative hitsが複数ある他、86塩基中54塩基でアライメントするが32塩基は無視されている。
さて、どういう書式で処理すればミスマッチを含むリードを除くことができるだろうか?

最も簡単かつ、厳しい抽出条件としては 

samtools view sample_1_sort.bam | grep "MD:Z:86" > sample_1_sort_ext.bam

という感じだろうか。これだとヘッダ情報が失われてまずいかもしれないので、一旦samに書き出して、text整形してからbamに戻してやったほうがいいかも。
ちなみに先程のmismatchてんこ盛りのファイルについて、処理前

$ samtools view sample_1_sort.bam | wc -l
42330669

なのが

$ samtools view sample_1_sort.bam | grep "MD:Z:86" | wc -l
113159

というふうに4200万リード中11万リードが残った。さてどんなものが残ったのかな。