2017年7月19日水曜日

田胡研のサーバ紹介 2017年ver

# 田胡研のサーバ紹介 2017年ver 最近は早期配属の3年生も入ってきていろいろ楽しげなことが始まりそうな田胡研です. 今日は田胡研のサーバ(物理)の紹介をしようと思います # 田胡研のサーバ 田胡研は片柳研究所塔の11Fの角に部屋を持っていてそこをサーバルームにしています. ここにはCSCと同じ数ほどのサーバがあります. サーバは用途別にいくつかの系統に分かれていて * VM用サーバ * Fileサーバ * 実験用サーバ * Dockerクラスタサーバ などの目的ごとに配置しています. # VMサーバ,Fileサーバ IBM製(古い)のラックにブレードサーバが4枚とFileServerが1台あります. IBMのThinkPadのようなKVMがありそれぞれにアタッチできるのですがとても時代を感じます. このラック内のブレードサーバは主に研究室の主要サービスに使われており * FrontWebServer(Nginx) * DNS * Mail * Wiki * Gate * LDAP 等サービスをホストするVMサーバと * Zabbix * backup 等の監視・重要ファイルのミラーリングに使われています. ファンがうるさいです. 一番下にあるのがFileServerで自作したものになっています. FreeNASを入れてありRAID6構成ZFSでストレージプールとしiSCSIやNFSでVM等にファイルやボリュームを供給しています. FireServerはリプレイス計画があり1ヶ月内に倍以上の容量になる予定です. # 実験VMサーバ IBM製ラックの横にはアルミラック上にまな板で組んだサーバがありこれらは実験用のVMを供給するサーバとして使われています. 実験用VMサーバは現在2台あり,1台は個人で使ったり、いろいろな用途に使うよう,もう一台は学生PortalのコピーをホストするVMとして利用しています 本学で8000人が利用している学生Portalは田胡研製なので田胡研内でも学生ポータルが開発用にホストできるようになっています. 学生Portalの他にもCSCで運用しようとしている開発中のサービス等もこのVM上のリソースを利用したりしています. 下にあるPCケース入りのPCはCS学部のサーバになっていて田胡研の管轄外なのですがおいてあります. 学部サーバはカーネルのバージョンがとても古いと聞いたことがあります. # 実験サーバ, Dockerクラスタサーバ etc VMサーバがあるアルミラックの横に更にアルミラックがありそこにはたくさんのまな板のサーバがあります, これらは個人の実験用に使われています. 現在では * DockerCluster(Kubernetes)のノードとして6台 * 田胡研の次期インフラ基盤として期待しているOpenStakサーバ(in Gentoo) * 田胡研が作ったFileSystem(Elton)が動くサーバ 等に使われています. このラックにも追加するサーバをこの前発注したので近いうちにPCが増える予定です. PCはどんどん移り変わっていくのでこの時こんなんだったんやでってのが残ってるといいなって記事にしてみました. 今日はこれでおしまい. あまり期間があかないように書いていけたらなぁ...

2017年7月11日火曜日

田胡研SlackBot その2

# 田胡研SlackBotその2 ちまちま間が空いてしまいますができる限り書いていこうかなって 今日は前回に続いて田胡研Slackで使えるBotの紹介と東京工科大生は使えるかもしれないAPIの紹介をします. # 田胡研SchoolBusBot 田胡研のSlackではバスの時刻を知ることができます. 大学のスクールバスの時刻は http://www.teu.ac.jp/campus/access/006644.html#bus で公開されていますが正直見づらくアクセスしに行くのも大変です. そこで田胡研ではSlackBotに話しかけることでバスの時間を知ることができるようになっています ![slack_bot](https://gyazo.com/32c09eff219b2b93d4d0cb13ab334e3c.png) こんな感じに. * 行こうか => 八王子駅-大学 * 帰ろうか => 大学-八王子駅 * 買い出しかな => 大学-八王子みなみの * 歩こうか => 八王子みなみの-大学 という感じにラッキービーストに話しかければ時間がわかります. バスの時間知りたい時に使ってくれれば幸いです. # 東京工科大学スクールバスAPI このSlackBotは大したことないのですがバスの時刻データAPIを作るのが少し大変でした. 時刻表は大学のホームページで公開されているだけなのですが臨時運行があったりするので決め打ちだとよろしくありません. そこで時刻表のページをスクレイピングしてDBに保存しておきそのデータを問い合わせ可能なAPIを作りました. APIは公開しており, ソース: https://github.com/namazu510/teu-school-bus-api APIDoc: https://namazu510.github.io/teu-school-bus-api/ な感じです. 利用はフリーです. 弊学学生でなんか面白いもの作るのに使えそうなら使ってください. サーバ側で日1回新着のデータがないかチェックしています.

2017年7月8日土曜日

田胡研SlackBot その1

# はじめに この記事は田胡研初夏のAdventCalendar 8日目の記事です. 前回から間が微妙に空いてしまいましたが今日は前回のluuvaくんのvoiceroid apiに被せてそのapiを利用して田胡研SlackBotを作った話を書こうと思います. # 田胡研Slack 田胡研ではSlackをコミュニケーションツールとして使っています. 昔はIRCを使っていたらしいですがSlackに一本化しました. 基本コミュ障の集団なのでよくSlackで喋ったりしています. Slackはその便利さに加えてエンジニアとしてはいろいろなBotを作ることができるのが楽しいところです. 田胡研SlackにもいろいろBotが作られていて * Logger * ラーメン屋決定機 * 大学スクールバス時刻案内 * Voiceroid音声を研究室内で流せるBot などあります. スクールバス時刻案内BotはまたこのAdventCalendar期間中に書くとして,今日はVoiceroid音声をSlackから流せるBotについて書きます. # voiceroid-slackbot ## 利用手順 はじめにこのBotの利用ステップと動作を示します. 1. Slack上でBotにメンション付きで喋ってほしいテキストを送信する 1. SlackBotがVoiceroidAPIをcall 1. VoiceroidAPIから音声データがバイナリで飛んでくるので保存 1. 音声データを再生する (Botは研究室内のサーバで動いているのでそのスピーカから音声が流れる) という感じです. ## ソース slackbotはnodeで動かすことにしました. エコシステムのおかげでslackbotはほんと一瞬で作れてしまいます. ```js const RtmClient = require('@slack/client').RtmClient const WebClient = require('@slack/client').WebClient const RTM_EVENTS = require('@slack/client').RTM_EVENTS const exec = require('child_process').exec const axios = require('axios') const fs = require('fs') const token = process.env.API_TOKEN || 'DEBUG-TOKEN-HERE' const rtm = new RtmClient(token, { logLevel: 'error', autoReconnect: true, autoMark: true }) rtm.start() const web = new WebClient(token) rtm.on(RTM_EVENTS.MESSAGE, function handleRtmMessage(message) { console.log(message); let text = message.text // DM check if (text.indexOf('<@U5QCWJ64B>') === -1) { console.log('this is not direct message') return } text = text.replace('<@U5QCWJ64B>','') // play special sound if(text.indexOf('あけて') > -1){ randomNumber = Math.random(); let file_name = 'open_1.wav' if(randomNumber < 0.1){ file_name = 'open-gd.wav' } play(file_name) return } // play voiceloid sound axios.get('http://192.168.133.40:60334/voice', { params: { msg: text } }).then((res) => { return res.data }).then((data) => { // decode and save let sound = Buffer.from(data.sound, 'base64') let filename = `response.wav` fs.writeFile(filename, sound, (err) => { play(filename) }) }) }) function play (filename) { exec(`aplay -D plughw:1,0 ${filename}`, (err, stdout, stderr) => { if (err) { console.log(err) } console.log(stdout) }) } ``` ただ書き連ねたコードですが, あけて(研究室のカードロックを解除して!)というSlackのメッセージだけはVoiceroidを使わずたまにアニメ音声が流れるようになっています. こういうのは他にもいくつか追加できたらと思います. ## 使ってみて感想 * 深夜とかにスピーカーから音声を流せて中にいる人をおどかせる * ルイズコピペをどっからか流してテロが起こせる * カードキーを忘れて開けてほしいケースだとスマホも忘れていて結局Slackメッセージ経由で開けてもらえない * 研究室の中にいる人に確実に気づいてほしいメッセージを飛ばすのに便利 面白いものを思いついたらまたどんどんSlackBotを作って遊んでみたいですね. 今回はここでおしまい.

2017年7月6日木曜日

VoiceroidAPI

# VoiceroidAPI
B17のLuuvaです。
VoiceroidをAPIサーバーとして外部に音声を出力する機構を作りました。
![VOICEROID+ 結月ゆかり EX](https://lh3.googleusercontent.com/-8Pj3DV-7SgE/WVnFyNK_NvI/AAAAAAAAABM/IABZq2IZeoA_Ah5XJ9i0a6f0GfMfBbsIACEwYBhgL/w140-h51-p/mainimage.jpg "結月ゆかりさん")

# APIサーバーの使い方
以下のサイトにAPIドキュメントがあります。
研究室内のネットワークのみアクセス可能です。
[VoiceroidAPI(Network_KenA)](http://192.168.133.40:60334/)
場合によっては動いていなかったり、移転されている可能性もあります。

2017年7月4日火曜日

LDAPをRubyから触る

# はじめに この記事は田胡研初夏のAdventCalendar2017 4日目の記事です. 今日はRubyでLDAPの認証を利用したりしたときの話とちょっとしたサンプルコードを晒します. # RubyでLDAPを使うとき RubyでLDAPを使う際便利なGemはいくつかあります. * ruby-ldap (http://ruby-ldap.sourceforge.net/) * net-ldap ( https://github.com/ruby-ldap/ruby-net-ldap ) * active-ldap ( https://github.com/activeldap/activeldap ) などです. この内どれを使うか悩んだのですがnet-ldapを使うことにしました. 理由としては * なんか一番情報が多かった( コードサンプルとか ) * LDAPの問い合わせ操作がLDAPに近くLDAPを触るようにRuby上のコードがかける ことです. まず先にどんな感じで書けばLDAPの情報が引けるのか示します. # 単純にログインチェック net-ldapはgemで公開されているのでGemfileに書いて持ってきます. そしてこんな感じのコードを書きます. ```ruby require 'net/ldap' ldap = Net::LDAP.new ldap.host = LDAP_SERVER_HOST ldap.port = LDAP_PORT # アクセスのベースディレクトリを指定 ldap.base = LDAP_BASE # ログインするldapidとpassword username = params[:username] password = params[:password] # LDAP上での名前に luname = "uid=#{username},LDAP_BASE" ldap.auth luname, password # このbindがtrueならログインできる, falseはログインできない. ldap.bind ``` 思ったより複雑ではなかったです, ライブラリ様様ですね. # ユーザの属性取得 ログイン試行のコード例はいろいろあるのですがそれ以外があまり情報がなく少し手間取りました. ユーザの属性取得はFilterを利用してこんな感じ. ```ruby # 前述コードのldap.authのあとから ldap.open do |conn| filter = Net::LDAP::Filter.eq('uid', username) @entry = conn.search(filter: filter).first end # @entryはMapで回すと属性が取れる. @entry do |key, value| p key p value end ``` LDAPのクエリを少し調べないといけないのですがLDAPのクエリのサンプルはそこそこ転がっていて,それをRuby上のコードにするのは簡単でした. あるユーザの所属するグループ一覧を出すクエリなどは実現方法がわからずLDAPのデータを引いてきたあとにRuby側でフィルタするということを行って実現しました. # 田胡研のLDAPサーバのラッパーAPI ここまで示したようなコードを使ってLDAPのクエリを書いていけばRubyからLDAPの情報を引いてくることができます. ただLDAP自体メジャーな技術ではなかったり触るのが少し癖があったりで皆が手軽に利用するのは大変なので, 田胡研では今回書いたような方法でLDAPにアクセスし認証を行ったり,LDAPの情報をJSONで返す(WebAPI)を用意しています. APIでは以下の情報が取得できます. * ログイン試行 (userid+password or token) * 自分の情報 * 自分の所属するグループのリスト * 任意の人の情報(セキュアなものはないので弊研のLDAPはログインさえできれば他人の属性も引けます) このAPIを利用しいくつかのサービスを田胡研では開発しています. ( 田胡研メンバでLDAP認証系利用したいような人がいればswagger-doc等のリンクはnamazuさんのwiki個人ページにあるので参照してください. )