MacのMojaveでcrontabを設定する

crontabを保存しようとすると権限のエラーで保存ができません。

$ crontab -e
crontab: no crontab for hoge - using an empty one
crontab: installing new crontab
crontab: tmp/tmp.4312: Operation not permitted
crontab: edits left in /tmp/crontab.lgPpmIdNvX

下記のようにしてiTerm.appに対してフルディスクアクセスを設定します。

スクリーンショット

再度実行すれば成功します。

$ crontab -e
crontab: no crontab for user - using an empty one
crontab: installing new crontab

MacのVimでクリップボードを共有する

Vimのバージョンを調べて-clipboardとなっていたらクリップボードの共有ができません。

vim --version

そんな時は最新のVimをbrewでインストールします。ケツにつけてるオプションがMac上で新しいVimにパスを通してくれるようです。

brew install vim --with-override-system-vi

そして.vimrcに下記を追加して完了です。

set clipboard+=unnamed

MacではCommand+CでMacVim上の文字列をコピーできるんで、クリップボードを共有しないことが何かと便利だったんですが、Vim上で普通にクリップボード共有すればMacVimを入れなくてもいいかなーと今更思い始めてクリップボードを共有することにしました。

他人にはLinuxを勧めておいて、結局事務的な作業をいろいろするとなるとMacを使うしかなくて申し訳ない。

参考

KotlinでSpark Frameworkを使ってWebSocketのアプリケーションを構築する

公式を参考に下記のようにKotlinに書き換えます。接続があった時にわかるようにコメントの出力だけ追加しました。

import org.eclipse.jetty.websocket.api.*
import org.eclipse.jetty.websocket.api.annotations.*
import java.io.*
import java.util.*
import java.util.concurrent.*
@WebSocket
class Hoge {
companion object {
private val sessions = ConcurrentLinkedQueue<Any>()
}
@OnWebSocketConnect
fun connected(session: Session) {
println("connect")
sessions.add(session)
}
@OnWebSocketClose
fun closed(session: Session, statusCode: Int, reason: String) {
println("close")
sessions.remove(session)
}
@OnWebSocketMessage
@Throws(IOException::class)
fun message(session: Session, message: String) {
println("Got: $message")
session.remote.sendString(message)
}
}

パスの割当ですが下記のようにします。

webSocket("/websocket/path", Hoge::class.java)
init()

init()はそれ以降にGETとかPOSTが存在しない場合に書いてあげる必要があるだけで、以降に他のURLが割り当てられている場合は書く必要はありません。

webSocket("/websocket/path", Hoge::class.java)
get("/sample", RouteSample.App())

起動後に下記のようにcURLで接続確認ができます。下記のようにHTTP/1.1 101 Switching Protocolsが戻れば問題ありません。これが例えば他のURLとバッティングするなど(get("/*", RouteSample.App()))などように被る場合はGETが優先される)あると200が帰ってくるので調整しましょう。このデバッグ方法はこちらを参考にしました。

$ curl -v -i -N \
-H 'Sec-WebSocket-Version: 13' \
-H "Sec-WebSocket-Key: $(head -c 16 /dev/urandom | base64)" \
-H "Connection: Upgrade" \
-H "Upgrade: websocket" \
"http://localhost:8080/websocket/path"
*   Trying ::1...
* TCP_NODELAY set
* Connected to localhost (::1) port 8080 (#0)
> GET /websocket/path HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.54.0
> Accept: */*
> Sec-WebSocket-Version: 13
> Sec-WebSocket-Key: 3/1w68zRBAqj1/sszabdTw==
> Connection: Upgrade
> Upgrade: websocket
>
< HTTP/1.1 101 Switching Protocols
HTTP/1.1 101 Switching Protocols
< Date: Wed, 10 Oct 2018 06:59:41 GMT
Date: Wed, 10 Oct 2018 06:59:41 GMT
< Connection: Upgrade
Connection: Upgrade
< Sec-WebSocket-Accept: J/c6izErmiViW26aSwL9e0NxtKs=
Sec-WebSocket-Accept: J/c6izErmiViW26aSwL9e0NxtKs=
< Server: Jetty(9.4.4.v20170414)
Server: Jetty(9.4.4.v20170414)
< Upgrade: WebSocket
Upgrade: WebSocket

あとはJavaScriptでこんな感じで接続できると思います。これはTypeScriptなんで、TypeScriptわからない人はこちらを参考にJavaScriptで書き換えてあげてください。

let socket = new WebSocket('http://localhost:8080/websocket/path');
socket.addEventListener('open', () => {
socket.send('Hello Server!');
});
socket.addEventListener('message', (event: any) => {
console.log('Message from server ', event.data);
});

aws-cliでS3やS3ライクなオブジェクストレージをプロファイル毎に操作する

なかなかGUIが見つかりません。GUIがあると触りやすいんですが。

仕方ないのでCLIで操作する方法をまとめて人に共有していこうと思いまとめてみます。

aws-cliのヘルプは非常に多くあり操作に問題はないと思いますが、複数のバケット等がある場合の対応がまずいちばんの問題だと思います。

プロファイルを設定する

毎度デフォルトの設定を上書きしながら使うのは大変なのでプロファイル毎に管理するのが良いです。下記のようにしてaws configureにはプロファイル名を指定することができる。デフォルトの設定は使わずに必ずプロファイルを指定してコマンドを打つと万が一のミスが発生しません。

aws configure --profile hoge

プロファイルを使ったアクセス

設定しておいたプロファイルは下記のようにして使います。これらの設定はユーザーディレクトリ配下の.awsにありますので気になる人は見てみましょう。

S3を操作する例

バケットの一覧

aws s3 ls --profile hoge

バケット内部のオブジェクトの一覧

aws s3 ls s3://badget-name --profile hoge

S3ライクなストレージの操作例

S3ではなくS3ライクと言われるオブジェクトストレージにアクセスする場合は、単にendpointを指定するだけで良いです。

バケットの一覧

aws s3 ls --profile hoge --endpoint http://radosgw.s3-like.local

バケット内部のオブジェクトの一覧

本物のS3とは違ってs3://がなくなる感じ

aws s3 ls badget-name --profile hoge --endpoint http://radosgw.s3-like.local

macOS MojaveのVagrantでホストオンリーアダプタの作成で失敗する場合の解決策

macOS MojaveにアップデートしてからVirtualboxを入れようとしたところインストーラーが完了せずに入れられなかった。アプリケーションにはVirtualboxがインストールされていて動作するので一見問題なくインストールされたかもしれないように見えたので、Vagrantを入れて仮想VMを立ち上げようとしたら下記のようなエラーが出た。

There was an error while executing `VBoxManage`, a CLI used by Vagrant
for controlling VirtualBox. The command and stderr is shown below.
Command: ["hostonlyif", "create"]
Stderr: 0%...
Progress state: NS_ERROR_FAILURE
VBoxManage: error: Failed to create the host-only adapter
VBoxManage: error: VBoxNetAdpCtl: Error while adding new interface: failed to open /dev/vboxnetctl: No such file or directory
VBoxManage: error: Details: code NS_ERROR_FAILURE (0x80004005), component HostNetworkInterfaceWrap, interface IHostNetworkInterface
VBoxManage: error: Context: "RTEXITCODE handleCreate(HandlerArg *)" at line 94 of file VBoxManageHostonly.cpp

これは適切にVirtualboxがインストールできないことが原因で起きている問題らしく、セキュリティとプライバシーにアクセスするとVirtualboxがブロックされているので許可をしてから再実行でインストールが完了する。

スクリーンショット 2018-10-05 10.36.16.png

MacにbrewでMySQLクライントのみ入れる

brew install mysql --client-only

Mac自体でデータベースを起動することはない。基本的にはデータベース等はVMやDockerで立ち上げるためという人は多いと思う。Mac自体にデータベースを構築するほうがリソースの節約にはなるがMac自体のOSアップデート等でのダメージが多い印象がある。また、Dockerからデータベースに接続するときDockerを立ち上げているホスト上のデータベースにはアクセスし辛いが、VMでデータベースを立ち上げていれば外部ホストとして扱えるのが接続が簡単だし、より本番に近い環境(Dockerでのサービスを公開を本番で行っている場合)になると思う。

好みだと思うので自由でいいと思います。