Master The Mainframeはいいぞ。っていうメモ

Master The Mainframeってのに参加しました。面白かったです。
ただ、色々書き散らすと文章がまとめ切れなくなってしまうので、Master The Mainframeについては自分で調べてください。
ここでは『名前を聞いてちょっと興味が出てきた人』向けにチャレンジ中思ったことなどを書き残しておきます。

Master The Mainframeはこんな人におすすめ

  • プログラミング,パズルジャンルのゲームが好きな人
    プログラミングジャンル : 具体例を挙げると、"SpaceChem"とか"Human Resorce Machine"みたいなやつですね。MTMが楽しめるなら逆説的にZachtronics製のゲームはハマると思います。
  • 新旧問わずコンピュータが好きな人
    コンピュータの動作原理とか設計思想みたいなところに興奮する人には向いていると思います。

操作を覚えながら課題を次々こなしていくのがパズルゲームみたいで楽しかったです。
一行が80文字である点など、古い計算機で用いられていたようなパンチカードの息吹を感じました。
(パンチカードの読み取り機が動くイメージが脳裏によぎる・・・動く実物を見たときは感動したなぁ・・・)

進める時のTIPS

ちゃんとメモを取る/まとまった時間で一気に進める

可能ならまとまった時間で一気に進めたほうが操作方法が定着するでしょう。こまかい操作は忘れがちなのでメモを取っておいたほうがいいと思います。

自動翻訳と日本IBMのドキュメントを活用する。

英語が堪能ならともかく、そうでないなら自動翻訳で概要を掴んでから原文を読んだほうが早く読み進められます(当たり前)
外部の掲示板の書き込みなども参考になるので、詰まったらメッセージコード(ICH114514とかIKJ364364とか行の左に出る英字3文字+数字のもの)をググりましょ。

ソースコードはローカルに保管しておく

オリジナルのコードを保管しておいて、書き換え、動作確認のたびにGitを使って管理しておくといい感じでした。
ちなみにVSCodeREXXとJCLのシンタックスハイライトプラグインがあるので、これを使うとローカルで書くのが楽になります。REXXやらJCLやらでMarketplaceを調べてみよう。
書き戻す際は一行ずつコピペです。もっと賢い方法があるような無いような・・・

どうやっても上手くいかない場合

手順どおりにやっても上手くいかない場合、メインフレーム側の問題という事もあります。実際に自分も一度メインフレーム側の問題で3日ほど手詰まりしてしまいました。同じような症状の人がSlackで質問を投げたため、解決してもらえましたが、それが無ければ詰まったままだったと思います。
どうしても解決できない問題に当たった場合はSlackでスクリーンショットを添付して聞いてみるべきだと思います。

操作についてのTIPS

logoffはちゃんとすること

logoff処理をしないで終了してしまうと、セッションが時間切れになるまでログオンしている扱いになってしまい、通常手順のlogonでは復帰できなくなってしまいます。
ただしReconnectオプションで復帰が効きます。Reconnectの左にSを入力して送信すれば切断したセッションに戻ってこれます。これを知るまで苦労しました。
デザリング環境で課題を行う場合、頻繁に切断されてしまうので、Reconnectを活用しましょう。画像の赤丸部分ですね。

f:id:sorenuts:20200102034738p:plain
logon画面

メインフレーム特有のキー

公式が推奨しているターミナルエミュレータには多分仮想のソフトウェアキーボードが実装されているはず。少なくともX3270にはついてました。

f:id:sorenuts:20200102035114p:plain
X3270の仮想キーボード

色々あるけどとりあえず自分が多用したのは以下の2つ。

Attnキー

REXXスクリプトとかがログを吐き出しすぎて止まらない時に割り込みをかけることができるというもの。
割り込みをかけてHIかHEコマンドを送信するとTSOで実行中のジョブが停止し、命令を受け付けます。
一応IBMのドキュメントを見ると、
- HI : 解釈停止
- HE : 実行停止
とあります。

使える時はいつでも、HI 即時コマンドを使うようにしてください。

とあるので、とりあえずHIで停止しておけばよさそう(よくわかんない)

Resetキー

入力不可能なフィールドでキー入力しようとするとカーソルがX印になり、操作ができない状態になることがあります。この時、RESETキーを押すことで入力不可状態を解除できます。課題を進める中でどこかで使用方法が書いてあったような気がするけど、知るまでは詰むので一応書いておきました。

エディタ画面の行追加、行消去

左の行番号にコマンドを打ち込んで送信すると行を挿入したり消去したりできます。
iコマンドが下に行を挿入。dコマンドが行を削除。
複数行にdを入力して送信すると複数行削除されるので活用しましょ。

参考になるサイト

とりあえずこの2つかと。
* 「メインフレーム・コンピューター」で遊ぼう
おそらく日本語で調べ物をすると必ず出てくるサイト。JCLやREXXの入門は役立ちます。ついでにメインフレーム自体についての様々なトリビアが得られるので一通り目を通しておくと、MTMをより楽しめる(?)と思います。
* IBM Knowledge Center
とりあえず日本語の方のURLを。わからない単語なりメッセージコードなりはここで調べましょう。サンプルコードもちょいちょいあるので、書き方がわからなかったりしたらここで調べると大変参考になると思います。

Linux環境からherokuに(Ruby on Rails + PostgreSQL) on Dockerのアプリをデプロイした回

Rails + postgresql on Dockerのデプロイでよくわからなかったり引っかかった部分についてでも備忘録がてら上げときます。RoR+PostgreSQL on Dockerのローカル環境構築も中々に手間取ったのでそっちも気が向いたら書きます。

筆者の環境

  • Manjaro Linux 18.1.3
  • docker 19.03.40ce build 9013bf583a
  • docker-compose 1.24.1

Arch Linuxへのherokuの導入

公式のAURがあるのでそちらから導入。

導入

git clone https://aur.archlinux.org/heroku-cli.git
cd heroku-cli
makepkg -si

バージョン確認

heroku -v

herokuにRails + Postgresqlのアプリをデプロイする

あらかじめ

docker-compose down

しておきましょう。

作業しているディレクトリ(Dockerfileのあるディレクトリ)に移動します。ここではとりあえずappフォルダということにしておきます。

cd app

herokuにログインする

heroku login

コマンドを実行するとブラウザが立ち上がり、herokuへのログインを求められます。 ログインに成功した感じになったらheroku containerへのログインをします。

heroku container:login

herokuアプリを作成する

heroku create

heroku containerにdockerイメージをpushする

コマンド実行時にイメージをビルドしてくれるみたいなので、sudo権限を渡してあげないとパーミッション周りで失敗します(少なくとも自分のManjaro Linux環境では失敗)

sudo heroku container:push <コンテナ名>

アドオンを追加する

自分はPostgreSQLを利用したのでアドオンを追加してやります。余談ですが、アドオンの追加は無料のものでも、クレジットカードの登録が必要だった気がするんですが、いつのまにか不要になっているように見えます。

heroku addons:create heroku-postgresql:hobby-dev

動かす

でherokuにリリースする。何やってるのかはいまいちよくわかってないんですけど(ダメじゃん)、pushしたやつを動かすっぽいです(多分) Release Phase

heroku container:release <コンテナ名>

であとはデータベースのマイグレーションrailsコマンドでやっておきます(上の参考ページを見た感じだと自動でやってくれるっぽい事が書いてあるんですけど、実際どうなんですかね)

heroku run rails db:migrate

動作確認

heroku open

を実行すると実際に動いているページがブラウザで開きます。

感想

権限まわりで引っかかるたびにsudoでごり押すのって美しくない感じがある・・・

systemd上でxrandrが動かないのを解決した回

目的

systemd上でXアプリケーションを動作させる。

理由

Manjaro Linuxではモニターを繋いだだけでは自動でマルチモニタにならないため。マルチモニタを使う場合は xrandr を用いて

xrandr --output LVDS1 --auto --primary --output VGA1 --auto --above LVDS1

といったコマンドをいちいち打つ必要がある。面倒なのでコマンドをシェルスクリプトにしてモニターを繋ぐたびに手動でシェルスクリプトを実行していたが、ぶっちゃけめんどくさくなってきたので自動化しようと考えた。

提案手法

同じようなことを考えることはいるもので、下記のようにタイマー機能で1秒ごとにスクリプトを実行して切り替えを自動化している人がいることがわかった。

ArchLinuxで自動でdisplayの接続を認識し調整する

上記のページはウィンドウマネージャーとして awesome 環境を用いているが、自分は Xfce なので cron か systemd を検討した。自分の環境に cron はインストールしていないので環境を汚したくないなと思って systemd で自動化することに決めた。
systemd での自動実行には systemd.timer を用いればできることがわかったので、これについて調べた。

systemd.timer について

参考 systemd/タイマー - ArchWiki

ざっくりと言えば、<サービス名>.service と同じディレクトリに <サービス名>.timer を置いてやればいい。
systemctl daemon-reload も念の為忘れずに。

.service と .timer を書いた

autodualmonitor.service

[Unit]
Description = Automatic dual-single monitor switcher

[Service]
Type = oneshot
ExecStart = /home/<ユーザー名>/MyShellScript/auto_dualmonitor.sh
Requires=lightdm.service

autodualmonitor.timer

[Unit]
Description=Automatic dual-single monitor switcher : timer

[Timer]
OnBootSec=1min
OnUnitActiveSec=1sec

[Install]
WantedBy=timers.target

両方とも /etc/systemd/system ディレクトリに配置した。スクリプトは上記の ExecStart に書かれている通りの場所に配置した。

トラブルシューティング

systemctl daemon-reload

してから動くか試すために

sudo systemctl start autodualmonitor.service

を実行したがエラーが出て動作しなかった。 .timer もenableにしてみたが Active: failed (Result: exit-code) になっており、正常に動作していないことがわかった。

systemctl status autodualmonitor.service

でログを見てみたところ、 Can't open screen というログが見られた。どうやら xrandr が動いていないようだ。
調べてみたところ、Archlinux wiki の次のページに答えがあった。

systemd/ユーザー - ArchWiki

DISPLAY は X アプリケーションがどのディスプレイを使えばいいのか知るために使用されます。XAUTHORITY はユーザーの .Xauthority ファイルのパスと、X サーバーにアクセスするのに必要な cookie を指定します。systemd ユニットから X アプリケーションを起動する場合、これらの変数を設定する必要があります。バージョン 219 から、セッションが開始したときに DISPLAY と XAUTHORITY を systemd --user デーモンの環境にアップロードする X11 セッションアプレット /etc/X11/xinit/xinitrc.d/50-systemd-user.sh が systemd に付属するようになりました。これによって、X を標準の方法で起動しているかぎり、ユーザーサービスは DISPLAY や XAUTHORITY を使用することができるようになっています。<<

要約するに、DISPLAYとXAUTHORITYの環境変数が設定されていないとxrandrのようなXアプリケーションは動作しないということらしい。で、ターミナルから実行して動作するのに systemd では何故動作しないのかといえば、

systemd のユーザーインスタンスは .bashrc などに設定された環境変数を全く継承しません。<<

ということだった。つまりはシェルスクリプト内でDISPLAYとXAUTHORITYを設定してやれば動作すると見ていいだろう。そこで autodualmonitor.sh(モニター切り替え用のスクリプト) を次のように書き換えた。

autodualmonitor.sh

#!/bin/bash

IN="LVDS1"
EXT="VGA1"

export DISPLAY=:0.0
export XAUTHORITY="/home/<ユーザー名>/.Xauthority"

if (xrandr | grep "$EXT disconnected"); then
    xrandr --output $IN --auto $EXT --off
else
    xrandr --output $IN --auto --primary --output $EXT --auto --above $IN
fi

大抵の場合、DISPLAYは:0.0なので特に考えずにそのまま書いた。XAUTHORITYは echo $XAUTHORITY を実行して調べてきたものをそのまま書いた。

書き換えてから念の為 sudo systemctl daemon-reload し、systemctl start autodualmonitor.service がエラーを出さないことを確認してからPCを再起動した。

再起動後に systemctl status autodualmonitor.timer を実行して見てみると Active: active (waiting) となっており、モニターを抜き差ししてみると、少し時間を置いてモニターが接続されることが確認できた。

まとめ

  • Xアプリケーションを用いる際には DISPLAY と XAUTHORITY の環境変数が使われているので留意する。
  • systemd には .bashrc などで設定した環境変数を一切継承しないので留意する。
  • systemd 関係で詰まったときは systemctl status とシェルスクリプト上で echo を組み合わせてデバッグする。
  • やっぱりLinuxって面倒くさい

ThinkPadX230を買ったのでManjaro Linuxをインストールしたらとんでもなく起動に時間がかかるので解決した話

はじめに

Think Pad X230を中古で買いました。22,800円。

メモリを増設して8GBにしておきました。低電力メモリで動くんだねこれ。

Windows10との別れ

Windows10がインストール済みでしたが、WindowsはSteam専用機で事足りているので、Linuxを入れました。

今回選んだのはManjaro Linuxです。


参考
メインページ (日本語) - Manjaro Linux

Think PadへのManjaro Linuxのインストール手順

1. Stable Releaseからxfce版の18.0.4のisoをダウンロード

Downloading File / - Manjaro Linux - OSDN

2. Image WriterでUSBにisoイメージを書き込み

3. Think PadのBIOSを開いてブートの優先度を変えておく。

BIOSThinkPadのロゴが出ている状態でF1
shiftキー押しながら^キーで起動優先度を上に移動できる。USBの優先度を最上位にする。

4. 起動したらインストール

自分はパーティション消してインストールしました。

5. 終わるまで待つ

6. 再起動

インストール完了したが・・・

起動が遅い

起動が遅い!(重要)

なぜか起動に2分近くかかる始末。これを解決した。

はじめにやったこと

原因を探るために、

systemd-analyze

で起動時間を見てみた。5秒。

そんなわけないだろ・・・

次にブート時のログを見るために、

dmesg

でログを表示した。

明らかに時間がかかっているログがあり、メッセージをみると”crng init done”とあった。

ググってみると乱数生成器が乱数生成しきるまで時間がかかっているらしいことがわかった(というかもしかしてタイムアウトまで待ってる?)

対策を調べてみるとrng-toolsとかhavegedで乱数生成を手伝わせるのがいいらしいことがわかった。
今回は色々とあって縁のあるrng-toolsをインストールした。
Rng-tools - ArchWiki

rng-toolsのインストールと有効化

1. pacmanのパッケージリストをアップデートする
インストールしたてほやほやなのでパッケージリストをアップデートしないと何もインストールできないので、

sudo pacman -Syy

してやる。

2. rng-toolsのインストール

sudo pacman -S rng-tools

でrng-toolsをインストールする。

3. 確認

rngd -f

これで乱数生成器が起動(どんどん/dev/randomにぶち込まれていく状態)

dd if=/dev/random of=/dev/null bs=1024 count=1 iflag=fullblock

これをrngd -fが起動していない状態でやるとバチクソ時間がかかる。rngd -fを起動すると一瞬で終了する。サラマンダーよりはやい

4. rng-toolsのサービスを有効化
あとは起動時にrngdが起動するように設定する。

systemctl enable —now rngd.service

でOK。確認は

systemctl status rngd.service

でenabledになっているかを見ればよい。

結果

Manjaro Linuxの起動が速くなった!

具体的には2分かかっていたところが14秒で終わるようになった。


ちなみにcrng initが動いている理由をよくわかってないままやったので、その辺は後々調べておこうと思う。

GASとOutgoing WebhookでSlackのbotを作った時に引っかかった部分

GAS(Google Apps Script)とSlackのOutgoing WebhookでSlackのbotを作ってみました。

はじめに

もともとはRustで書いたものを動かすつもりでしたが、どこにデプロイするかという問題にぶち当たりました。

お金も出したくないので無料でSlack botを作れないかと思って調べたところ、GASに行き当たりました。

参考にしたのは
Slack BotをGASでいい感じで書くためのライブラリを作った - Qiita
です。

どんなものができたか

内容

「突然のほにゃらら」に反応して、吹き出し化するbot。以上。

動作

f:id:sorenuts:20190612110249p:plain
できたもの

ソース

ぶち当たったところ

環境変数の扱い方

参考サイトを見てみると、

var prop = PropertiesService.getScriptProperties().getProperties();
prop.token

APIキーを環境変数から取り出しているみたいなのだけど、上手く動作しない。
なので

 var token = PropertiesService.getScriptProperties().getProperty('SLACK_ACCESS_TOKEN');

で直接取り出した。

Slackのスタンプの扱い

Slackのスタンプは

:hoge:

といった感じにコロンでくくられているのだが、そのままこれを受け取って文字列の長さをlength()で出してしまうと、スタンプで1文字なのに、コロン2つと中の文字を合わせて6文字扱いになってしまう。

こんな感じで吹き出しのサイズがおかしくなる。

f:id:sorenuts:20190612203723p:plain
変更前はこうだった

そこで文字列の長さを測る関数を別に用意した。
コロンからコロンまでを無視し、対応するコロンがない場合については巻き戻して文字列を数える関数である。

2バイト文字を2文字として数える関数にこの機能を盛り込んでおいた。半角と全角だと文字幅が違うからね。

URLエンコード

上と関連した話として、GASに飛んでくる文字はURLエンコードで飛んでくるみたいで、ASCII文字の記号は%xx形式になっている。

だから、コロンをそのまま判定しようとして

if ( text.charAt(i) == ':'){hogehoge}

としようとしても無駄である。

コロンの場合は"%3A"になるので、切り出すか、%に当たった場合に記号として判別するかした方がよい。

GASの更新

書いたスクリプトが反映されたりされなかったりして悩んだ。
「公開→ウェブアプリケーションとして導入」の後に、プロジェクトバージョンを最新にして更新しておかないとダメみたい。要検証。

おわりに

GASとかいう便利なものがあるとは知らなかった。思わぬ収穫。

botについては吹き出しの下側もサイズをきちんとしておきたい。そのうち。

Serenityを使ってDiscordをRustから遊ぶ

はじまり

ちょっと作りたいものがあったのでDiscordのAPIを調べてました。

ぶっちゃけた話、Pythonでdiscord.pyを使った方が楽なんだと思うんですけど、Pythonをみたら発狂して転げ回る病気にかかったということにしているので今回はRustで。


RustでDiscordAPIを叩くライブラリを探してみるとSorenityというライブラリが見つかりました。

github.com

日本語で説明しているページが見当たらなかったので、しばらくあちこちにらめっこしながら、とりあえずサンプルが動いたのでそこまで書いておきます。

下準備

まずはDiscord向けのbotを作る準備をしないといけません。Discord向けのアプリを作るためにまずデベロッパーポータルへ行きましょう。

discordapp.com

Discordにログインした状態でアクセスすると、下のようなページが出ると思います。

f:id:sorenuts:20190604213214p:plain
アプリケーションを作る

右上の"New Application"をクリックし、作成するアプリケーションの名前を入力して作成します。

日本語でも大丈夫みたいですね。

作成すると下のようなページが出るはずです。

f:id:sorenuts:20190604214002p:plain
アプリケーションを作った

そうしたら上図の赤丸のBOTをクリックします。

f:id:sorenuts:20190604214209p:plain
BOTページ

右のADDBOTをクリックすると、

"ADD A BOT TO THIS APP? "
"Adding a bot user gives your app visible life in Discord. However, this action is irrevocable! Choose wisely."

と、「bot追加したらもう戻れねえぜ!賢い選択を。」的なことを聞かれるので"Yes, do it !"を力強くクリックしましょう。


余談ですが、"Choose wisely"は『インディー・ジョーンズ/最後の聖戦』を元ネタとするミームみたいですね

それはさておき、クリックすると、

f:id:sorenuts:20190604215502p:plain
BOTが生まれた

上図のようなページに移動します。

"A wild bot has appeared!"
「あ!やせいの BOTが とびだしてきた!」ですかね。
Discordは本当にゲーム関連の洒落が多くて素敵ですね。

それもさておき、上図の赤丸部分がプログラムで使用することになるトークンです。後で使います。覚えておいてください。

訪れるたびに毎回少しずつ変化しますが、いつ作ったものを使っても問題ないです。


次に、左カラムのOAuth2をクリックします。

移動先のページをスクロールすると、下図のようなチェックボックスが大量に出てくるかと思います。

f:id:sorenuts:20190604220335p:plain
OAuth2のURLジェネレータ

ここではbotにチェックを入れます。するとさらに下に下図のようなチェックボックス群が出てきます。

f:id:sorenuts:20190604220521p:plain
BOTの権限設定

このチェックボックスbotに与える権限を設定できます。これはbotを招待する際に権限オフにもできます。

とりあえず試すために管理者にチェックを入れます。

その後2つ上の図の赤丸でリンクをコピーし、それにアクセスすると下図のような画面が出ます。

f:id:sorenuts:20190604220823p:plain
BOTをサーバーに追加する

そこから追加するサーバーを選んで認証を押してやると

f:id:sorenuts:20190604221006p:plain
BOTがスポーンした

BOTがサーバーに参加します。
が、当然このままでは何もできません。
プログラムで動かしてやる必要があります。

SerenityでDiscord BOTを動かす

とりあえずSerenityをcloneしてきましょう。

git clone https://github.com/serenity-rs/serenity.git

そうしたらexampleディレクトリ内の01_basic_ping_botに移動しましょう。

cd serenity/examples/01_basic_ping_bot/

それでもってcargo run・・・といきたいところですが、このままだと「トークンの環境変数がないぞ」と怒られて動きません。
トークンをプログラム内か環境変数に書いてやる必要があります。

コードをいじらないで動かす場合は、

export DISCORD_TOKEN=<ここにトークン>

とでもしておけばいいと思います。

コードをいじって動かす場合は45,46行目の

    let token = env::var("DISCORD_TOKEN")
        .expect("Expected a token in the environment");

    let token = "ここにトークン"

としておきましょう。

そうしたらcargo runします。


無事起動し、サーバーに接続できると、コンソールに

<BOTの名前> is connected!

が出ますので、そうしたらDiscord上で"!ping"と書き込んでやると・・・

f:id:sorenuts:20190604222931p:plain
こいつ・・・動くぞ・・・!
動きましたね。

まとめ

というわけで、SerenityでRustからDiscord BOTを動かしてみました。
学校から動かしたらプロキシに引っかかって動かなかったり、cargo run自体が通らなかったり、そもそもサンプルコードを真剣に読んでなかったりと手こずりましたが、無事動いたのでよしとします。

今後はこれを使って、前からやりたかったことをやってみようと思います。

最後まで読んでいただき、ありがとうございました。


PS:どこかインターンに行きたい・・・

一人暮らしサバイバル

一人暮らしを始めてからだいたい2,3週間くらい経ったのでTips的なやつを書き散らしてみる。

  • 風呂の底が汚い、排水溝がむき出しの時の対処

スノコを敷く。ホームセンターで買える。

  • 物を干す場所がない

物干しを買う。ホームセンターで買える。

  • ケトルとかポットが乾かない

中にキッチンペーパーを入れておく。ホームセンターで買える。

  • 服やタオルが乾かない

サーキュレータで風を当ててやる。ホームセンターで買える。

  • 蛇口をひねるタイプの水道でお湯がぬるいor熱い

蛇口のひねり具合を覚える。テープで目印をつけて、テープが手前に来る時にいい具合になるように調整するといい感じ。
温度計であらかじめ温度を測ってメモしておくのも強い。両方ともホームセンターで買える。

  • 洗い物が面倒

紙コップを使う。耐熱性の強いものと薄いやつの両方を買っておくと色々対応できていい感じ。ホームセンターで買える。
コッヘルにサランラップを敷いて使う。両方ともホームセンターで買える。

  • 周りにホームセンターがない

Amazonで買う。周りにローソンかファミマがあればそこに送っておけばいつでも取りに行けていい感じ。

  • 周りにコンビニがない

強く生きて。