2018年5月6日日曜日

gitのdescribe

gitのtag


コードやドキュメント書いていてgitに世話になっているのは私だけでは無いと思いますが、一人で使っているとcommit、pushの繰り返しになって、あまりtagコマンドは使わない。で暇だったのでtagをちょっと調べてみた。

tag一覧


tagの一覧の表示はこれ
cuomo@ugui7 ~/code $ git tag -l
0.3.0
1.0.0
1.1.0
1.2.0
...
...

3.5.0
3.6.0
cuomo@ugui7 ~/code $

最新のtagはどれ?


一覧の中の最新のタグはどれだってなる場合、describeをつかう
cuomo@ugui7 ~/code $ git describe --tag --abbrev=0
3.6.0
ちなみに--tagをつけないと--annotateで設定したタグしか出力しないので注意が必要、--abbrev=0をつけないと
cuomo@ugui7 ~/code $ git describe --tag
3.6.0-7-ga2e69a4
こういう出かた、意味は最新のtagから7コミットすすんでいて、そのhashがa2e694ということ、--abbrev=xでhashの出力桁数を調整出来る。サブオプションもちゃんと調べて使おう...

2018年4月22日日曜日

gentooでlet's encryptしてみた

そろそろSSL化しないとまずいと思っていたので無料SSLを試してみた、けっこう訳分からん404に遭遇して適当にやったのであまり当てにしないで

certbotのインストール


nginxにSSLを入れるのでこちらをインストール
# emerge app-crypt/certbot-nginx

証明書の発行


let's encryptがサイトの存在を確認しにファイルを探しに来るので、そのファイルにアクセスできるようにしておく、なんかファイル置いてブラウザで見れるか確認しておいた方がいい。
# mkdir -p /var/www/localhost/htdocs/.well-known/acme-challenge
でcertbotを実行
# certbot certonly --webroot -w /var/www/localhost/htdocs -d www.karky7.com
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator webroot, Installer None
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for www.karky7.com
Using the webroot path /var/www/localhost/htdocs for all unmatched domains.
Waiting for verification...
Cleaning up challenges
Unable to clean up challenge directory /var/www/localhost/htdocs/.well-known/acme-challenge

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/www.karky7.com/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/www.karky7.com/privkey.pem
   Your cert will expire on 2018-07-21. To obtain a new or tweaked
   version of this certificate in the future, simply run certbot
   again. To non-interactively renew *all* of your certificates, run
   "certbot renew"
 - If you like Certbot, please consider supporting our work by:

   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le

nginxへ設定


nginx.confにSSLの設定をいれる

    server {
        listen IP.xxx.xxx.xxx:443;
        server_name www.karky7.com;
        access_log /var/log/nginx/kuso.access_log_443 main;
        error_log /var/log/nginx/kuso.error_log_443 info;
        
        ssl on;
        ssl_certificate /etc/letsencrypt/live/www.karky7.com/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/www.karky7.com/privkey.pem;

        root /var/kuso/www;
        autoindex on;
        error_page 404 /error/404.html;
    }
で完了、結構簡単にできました、ちなみに「certbot run」はうまくいきませんでした。

あとはrenewで自動更新すればいいらしい、今度設定する

2018年4月7日土曜日

東京スタイル鶏らーめん ど・みそ鶏

最近食ったラーメン、白湯ベース、文句なしにうまい、


スープが扁桃腺に染み入ります...



醤油


おいちい...



味噌


一緒にいったラーメンマンが食べたので、私はまだ食べてません...次食ってみます



今のところ、個人的に醤油派の自分ですが塩がいいかな、今度は味噌やってみます。



2018年1月8日月曜日

passwdコマンドでAuthentication token lock busy

passwdコマンドでハマる


簡単な事って意外とハマるとツボって抜け出せなくなる。
kernelビルドしなおして再起動した後rootのパスワード設定しようとしようとしたら
# passwd root
Changing password for user root
New UNIX password:
Retype new UNIX password:

passwd: Authentication token lock busy
#
エラーが出る、昔見たような見ないような記憶が定かではないエラーで、しばらく悩んだ。
たまたま見てみると、/bootがmountされていない、/etc/fstabを見てみると腐ってる。
面倒だったのでstage3で/を強制的に上書きしたのがfstabが腐った原因。

なので、remountしてfstabを修正
# mount -o remount,rw / 

リブート後、ちゃんと帰ってきました
アルチューのみんな、ちゃんとupdateしようね。

2018年1月7日日曜日

gentooのprofiles上がってたの知らなかった

New 17.0 profiles in the Gentoo repository.


正月終わって、いきなり、CPU脆弱性祭り、なんか「ほんとは知ってたんじゃないのぉ」的な感じもしなくはないが、まぁメーカーを信じるとして、その乗りでgentooのアップデート調べてたら...



gentoo profiles が2017-11-30に上がってたの気がつかなかった、しょうがないのでアップデート。
gccはgcc-6.4.0以上にしたよとか、gccのPIEをディフォルトしたから、ビルドしなおしてねってとか、最近、MeltdownやらSpectreなんかで、アップデートしろっていうから面倒だけど諦めてやりましょう...

Sparc勢は余裕なんだろう ワロス

2018年1月3日水曜日

正月に Monad Transformer

あけまして、おめでとうございます


ミソカから元旦にかけて、あるチューhighまーのまま、stack overflowをおこし、体ダルダルで飲みつづけてます、本年もよろしくお願いします。



まず、今年の抱負


理由は聞かないでください
  • 一番搾りは350ml缶2本まで
  • 焼酎は薄めます
  • 「セイッ」は月に一度にする
今年も頑張るぞ!

もなどとらんすふぉーまーってなんだよ


それは、よく分かってません、とりあえずモナドを合成することらしいですが、やってみました、あってるかどうかは分かりませんが、動くのでいいでしょう。

まず、普通のStateもなど


よくみるサンプル、Identityは恒等モナドっていって、関数で言うidみたいなもんだと思ってて、それのモナド用らしい。
type Stack = [Int]

push :: Int -> StateT Stack Identity ()
push x = state $ \xs -> ((), x:xs)

pop :: StateT Stack Identity Int
pop = state $ \(x:xs) -> (x, xs)

ghciで
*Main> f = do {push 5; pop; pop;}
*Main> runIdentity (runStateT f [1,2,3])
(1,[2,3])
*Main>

runStateTでStateTモナドを走らせたら、Identity aが帰ってくるので、更にrunIdentityで剥がしているだけ。

エラーの時どうする?


こうやってpopしまくると、エラーになる
*Main> f = do {push 5; pop; pop; pop; pop; pop;}
*Main> runIdentity (runStateT f [1,2,3])
*** Exception: /home/cuomo/Code/haskell/MonadTransformer/MonadStack.hs:18:15-32: Non-exhaustive patterns in lambda

*Main> 

これは、\(x:xs)のパターンマッチが腐って、エラーになる、これはエラーとして処理したい、そんな時はpopをお利口チャンににして

push2 :: Int -> ExceptT String (StateT Stack Identity) ()
push2 x = state $ \xs -> ((), x:xs)

pop2 :: ExceptT String (StateT Stack Identity) Int
pop2 = do
    s <- get
    case s of
        x:xs -> put xs >> return x
        otherwise -> throwError "Stack is empty"
元々の機能にエラー処理を追加したことが、前のpopと違うところ、これはこうやって使う

*Main> f = do {push2 5; pop2; pop2; pop2; pop2; pop2;}
*Main> runIdentity (runStateT (runExceptT f) [1,2,3,4,5,6,7])
(Right 4,[5,6,7])
*Main> runIdentity (runStateT (runExceptT f) [1,2,3])
(Left "Stack is empty",[])
*Main> 

スタックから取るのが無いのに、popすると結果にLeft値がはいって失敗が分かるようになる、タプルの中にLeft値と腐った空の配列入れてきてもらっても、無意味っぽいので、別の書き方で...

push3 :: Int -> StateT Stack (ExceptT String Identity) ()
push3 x = state $ \xs -> ((), x:xs)

pop3 :: StateT Stack (ExceptT String Identity) Int
pop3 = do
    s <- get
    case s of
        x:xs -> put xs >> return x
        otherwise -> throwError "Stack is empty"

StateTとExceptTの位置を変えて逆にすると、結果がRight値、またはLeft値で出てくるようになる。
*Main> f = do {pop3; pop3; pop3; pop3; pop3; pop3;}
*Main> runIdentity (runExceptT (runStateT f [1,2,3,4,5,6,7]))
Right (6,[7])
*Main> f = do {pop3; pop3; pop3; pop3; pop3; pop3; pop3; pop3}
*Main> runIdentity (runExceptT (runStateT f [1,2,3,4,5,6,7]))
Left "Stack is empty"
*Main> 

成功すれば、Right値に結果がくるまれて、失敗した場合、Left値にエラーの文字列が入ってくるようになる、こっちの方がウケが良さそうな気がする。

操作をログでとる


さらにWriterTで何を突っ込んで、何を取り出したのをログする機能を追加してみる

type Log = [String]

push4 :: Int -> StateT Stack (WriterT Log (ExceptT String Identity)) ()
push4 x = do
    tell ["push " ++ show x]
    state $ \xs -> ((), x:xs)

pop4 :: StateT Stack (WriterT Log (ExceptT String Identity)) Int
pop4 = do
    s <- get
    case s of
        x:xs -> do
            tell ["pop " ++ show x]
            put xs >> return x
        otherwise -> do
            throwError $ "Stack is empty"

同じように...

*Main> runIdentity (runExceptT (runWriterT (runStateT f [1,2,3,4,5,6,7])))
Right ((4,[5,6,7]),["push 5","pop 5","pop 1","push 10","pop 10","pop 2","pop 3","pop 4"])
*Main> runIdentity (runExceptT (runWriterT (runStateT f [1,2,3])))
Left "Stack is empty"
*Main> 
外側のタプルの右側に操作したログが追加されるようになる。

最後にIOは


じゃぁ、この中でIOの処理入れたいんだど、どうすればいい? って疑問がわくよね、ここで、Identity a が効いてくる、IOとIdentityってkindすると

Prelude> :m +Control.Monad.Identity
Prelude Control.Monad.Identity> :k Identity
Identity :: * -> *
Prelude Control.Monad.Identity> :k IO
IO :: * -> *
Prelude Control.Monad.Identity> 

にてるよね、そう、IdentityのところへIOを入れられるようになって、liftIOでリフトしてIOな関数を利用する。

push5 :: Int -> StateT Stack (WriterT Log (ExceptT String IO)) ()
push5 x = do
    liftIO $ putStrLn "pushしまーすぅ"
    tell ["push " ++ show x]
    state $ \xs -> ((), x:xs)

pop5 :: StateT Stack (WriterT Log (ExceptT String IO)) Int
pop5 = do
    s <- get
    liftIO $ putStrLn "popすんぞ"
    case s of
        x:xs -> do
            tell ["pop " ++ show x]
            put xs >> return x
        otherwise -> do
            throwError $ show "Stack is empty"

これで、main()から呼んでみると
main :: IO ()
main = do
    v <- runExceptT (runWriterT (runStateT stackIjily [1,2,3,4,5,6,7]))
    putStrLn $ show v

stackIjily :: StateT Stack (WriterT Log (ExceptT String IO)) Int
stackIjily = do
    push5 5
    pop5
    pop5
    push5 10
    pop5
    pop5
    pop5
    pop5
    pop5
    x <- pop5
    return x

こうやると、関数の中でIOを発行することができる。

~/Code/haskell/MonadTransformer $ runghc MonadStack.hs
pushしまーすぅ
popすんぞ
popすんぞ
pushしまーすぅ
popすんぞ
popすんぞ
popすんぞ
popすんぞ
popすんぞ
popすんぞ
Right ((6,[7]),["push 5","pop 5","pop 1","push 10","pop 10","pop 2","pop 3","pop 4","pop 5","pop 6"])

こうやって、モナドを積んでいけば、既存の処理を壊すこと無く機能を追加できる、ただ、積み上げる順序によって剥がし方がかわるのと、ちょっと複雑になると分かりにくくなってしまうような気がする。まぁ慣れればそんなに気にする事でもなさそうな。

その他の、同じようなやつ


で、同じような理由で、RWSモナドとか、MonadWriterとかMonadStateとかMonadReaderとかあるみたいだけど、使ったこと無いです、こんどやってみます。

今年は、haskellの理解力をさらに深めたいと思います。