Github の git アクセスを維持するために ssh 鍵認証
なぜ?
Github は公式に、Git アクセスのパスワード認証を停止していくと宣言したためです。
曰く 2021/8/13 にパスワード認証を廃止するとの事です。
August 13, 2021 – Token (or SSH key) authentication will be required for all authenticated Git operations.
やり方
Windows に git をインストールした場合、「Git bash」がインストールされています。
Mac/Linux はターミナル開けば ok
起動したら $ ssh-keygen -o
を叩けばやれます
azale@LAPTOP-T5MQIJ18 MINGW64 ~ $ ssh-keygen -o Generating public/private rsa key pair. Enter file in which to save the key (/c/Users/azale/.ssh/id_rsa): Created directory '/c/Users/azale/.ssh'. Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /c/Users/azale/.ssh/id_rsa Your public key has been saved in /c/Users/azale/.ssh/id_rsa.pub The key fingerprint is: SHA256:XhR0d0uB6se0C+n9YGJB4mJOktzVqlq74u/+wZg29Zk azale@LAPTOP-T5MQIJ18 The key's randomart image is: +---[RSA 3072]----+ | .o . ooo| | .o o...| | o.o. . | | . o o.+. . | | + =S+o.+ . | | =.B..+++ | | O.o.E+o. | | .+ o o.oo. | | .o=*o. .. | +----[SHA256]-----+
すると、~/.ssh/id_rsa.pub
が生成されます。これが ssh 公開鍵です。
そしたらこの中身を開いてコピーします。
$ cat .ssh/id_rsa.pub ~省略(見せられないよ~)~
Windows だと必要ないかもだけど、chmod 600 ~/.ssh/id_rsa
もやっておいて、ほかのユーザから参照できないようにしませう。
github に登録
次のリンクから、「New SSH Key」を指定します。
https://github.com/settings/keys
コピった内容を貼り付けで OK です。
ssh config の生成
そしてホームディレクトリに .ssh
ディレクトリができているので、.ssh/config
を追加しましょう。
個人的には vi 使いますが、まぁお好きに。
Host github HostName github.com IdentityFile ~/.ssh/id_rsa User git
ここまで書いたら保存。
接続確認でござる
$ ssh github The authenticity of host 'github.com (52.192.72.89)' can't be established. RSA key fingerprint is SHA256:... 中略 Hi Sunao-Yoshii! You've successfully authenticated, but GitHub does not provide shell access. Connection to github.com closed.
successfully authenticated,
と出ていれば設定は成功です。
Laravel 開発環境をDockerで
久々にPHP 使うお仕事になったついで。
PHP で非常に人気のある Laravel の開発環境を用意したいと思った。(※注意:リリース環境ではありません)
XAMPP とかクソくらえ!
ちょっと暴論ではあるのだけど、自分は XMPP が気に入らない。
理由は非常に明白で
- 常駐アプリ入れすぎ
- 何でもかんでも入りすぎ
- しかも重い
という事で、既存の環境を汚さずに開発環境を手に入れるのが自分の中でジャスティス。
そこで、Docker でその対応を行ってみようという企画です。
Laravel のインストール方法を見てみる
ちょっと調べてみると、Homestead や LaravelValet とかいうものがあるらしい。
で、LaravelValet は Windows ではつけあないとかなんとか…
Docker で構築する以上どうでもいい気がする…。
で、更に調べると、Composer で構築するっぽいことがわかった
ここまで判ればまずは手を動かしてみるか
ごめん、公式見た方がかなりマシ
composer だとコマンド一発だわ。
長時間無駄した…
PHP と Composer インストール済み環境を作る
といっても、Docker 系ファイル作成するだけ
基本的な Docker イメージは Docker Hub ここから取ってくる。
ちょうど、PHP と Composer があるので、これで環境作っちゃえ
docker-compose.yml
version: '2' services: host: restart: always build: ./data/main environment: TZ: 'Asia/Tokyo' volumes: - './sources:/root/codes'
volumes
設定で、ローカルディスク(./sources
)を仮想 OS 上のディレクトリ、 /root/codes
に紐づける
で、./data/main/Dockerfile
はこんな感じ
FROM php:7-fpm-buster RUN apt-get update && \ apt-get upgrade -y && \ apt-get install -y unzip curl wget git gcc COPY --from=composer /usr/bin/composer /usr/bin/composer WORKDIR /root
php
の7-fpm-buster
というタグ(設定のバージョン)をベースにする。(これ自体は debian ベース)- とりあえず
apt-get
で必要そうなソフトを入れておく composer
の Docker イメージから、/usr/bin/composer
だけつまみ食い的に取ってくる- ログイン時の作業ディレクトリを
/root
指定
てな感じ。
では早速ビルド
PS C:\Workspace\PHP\lalabel> docker-compose build Building host Step 1/4 : FROM php:7-fpm-buster ---> f5460fa2369d Step 2/4 : RUN apt-get update && apt-get upgrade -y ---> Running in a714759d79bb Get:1 http://deb.debian.org/debian buster InRelease [121 kB] Get:2 http://deb.debian.org/debian buster-updates InRelease [51.9 kB] Get:3 http://security.debian.org/debian-security buster/updates InRelease [65.4 kB] Get:4 http://deb.debian.org/debian buster/main amd64 Packages [7907 kB] Get:5 http://security.debian.org/debian-security buster/updates/main amd64 Packages [260 kB] Get:6 http://deb.debian.org/debian buster-updates/main amd64 Packages [7860 B] Fetched 8414 kB in 1s (6516 kB/s) Reading package lists... Reading package lists... Building dependency tree... Reading state information... Calculating upgrade... The following package was automatically installed and is no longer required: lsb-base Use 'apt autoremove' to remove it. 0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded. Removing intermediate container a714759d79bb ---> bc4b7370dc31 Step 3/4 : COPY --from=composer /usr/bin/composer /usr/bin/composer latest: Pulling from library/composer 801bfaa63ef2: Already exists 30e209609427: Pull complete 320f26ee9b1c: Pull complete 4612e05a72cf: Pull complete 9b2beae78beb: Pull complete 79c03e12047a: Pull complete 51393fef6543: Pull complete 5571c1cd7f43: Pull complete 65564f077fec: Pull complete d65380960587: Pull complete 925a16b14f98: Pull complete b5b77b9b221e: Pull complete 5f53c0c9d3ed: Pull complete 555ce7422600: Pull complete 312d42e4a2ef: Pull complete Digest: sha256:dd50f470e49d0b3ab9efe556dec5a8485703629ba7128e0f56c196d166f734f0 Status: Downloaded newer image for composer:latest ---> 8a9435afb5dd Step 4/4 : WORKDIR /var/www/html ---> Running in 466504abae53 Removing intermediate container 466504abae53 ---> 764db2ea70ec Successfully built 764db2ea70ec Successfully tagged lalabel_host:latest
では起動
PS C:\Workspace\PHP\lalabel> docker-compose up -d Creating lalabel_host_1 ... donedoc PS C:\Workspace\PHP\laravel> docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES bda1c00994e0 laravel_host "docker-php-entrypoi…" 14 seconds ago Up 13 seconds 9000/tcp laravel_host_1 PS C:\Workspace\PHP\laravel>
ではログインしてプロジェクト立ち上げますか
root@2743ff93f2f3:~/codes# composer create-project laravel/laravel example-app Creating a "laravel/laravel" project at "./example-app" Installing laravel/laravel (v8.5.7) - Downloading laravel/laravel (v8.5.7) - Installing laravel/laravel (v8.5.7): Extracting archive Created project in /root/codes/example-app > @php -r "file_exists('.env') || copy('.env.example', '.env');" Loading composer repositories with package information Updating dependencies Lock file operations: 105 installs, 0 updates, 0 removals - Locking asm89/stack-cors (v2.0.2) - Locking brick/math (0.9.1) - Locking dnoegel/php-xdg-base-dir (v0.1.1) - Locking doctrine/inflector (2.0.3) - Locking doctrine/instantiator (1.4.0) - Locking doctrine/lexer (1.2.1) ...中略... - Installing phar-io/version (3.0.4): Extracting archive - Installing phar-io/manifest (2.0.1): Extracting archive - Installing myclabs/deep-copy (1.10.2): Extracting archive - Installing phpunit/phpunit (9.5.0): Extracting archive 77 package suggestions were added by new dependencies, use `composer suggest` to see details. Generating optimized autoload files > Illuminate\Foundation\ComposerScripts::postAutoloadDump > @php artisan package:discover --ansi Discovered Package: facade/ignition Discovered Package: fideloper/proxy Discovered Package: fruitcake/laravel-cors Discovered Package: laravel/sail Discovered Package: laravel/tinker Discovered Package: nesbot/carbon Discovered Package: nunomaduro/collision Package manifest generated successfully. 73 packages you are using are looking for funding. Use the `composer fund` command to find out more! > @php artisan key:generate --ansi Application key set successfully.
するとローカルディレクトリは
よっしこれで開発が始められる…
Raspberry Pi 4 で LED + スイッチ点灯
基本から行くべきだよねってことでやってみた。
作ったのはこいつ
スイッチで LED の On/Off するだけの実装です。
ラズパイの IO
これは公式に落ちているものを拝借する。
使用しているライブラリはこれなので、まずはこのレイアウトを印刷して横に置いときながら組み立てます。
実装は大きく分けて2つ。
- スイッチの入力を受け付ける実装
- LED のOnOff通電する実装
という2つを考えます。
スイッチ入力を受け付ける実装
回路図をきれいに書くツールとか持ってないので、そこんとこ宜しく
ということで、3.3V 出力(ピン番号1)から出力して、スイッチ→抵抗を挟んで GND に帰ります。
スイッチを入れたときに抵抗を挟むのは、ショート(短絡)するとラブパイぶっ壊れるかもしれんので…
で、途中から GPIO 27 に分岐してますが、これをプログラムで拾います。
LED の On/Off する実装
こっちはもっと楽
こっちは IO ポートから電流を流すか Off るかだけの制御なので、楽勝。
LED はコレ。
GPIO はデフォ 3.3V で、330Ω 抵抗なら 0.01A = 10mA 以下になると思われ。
コード実装: スイッチ押してる間だけ光る
といってもさして難しい事はしていません。
# GPIO と sleep 関数の読み込み import RPi.GPIO as GPIO from time import sleep SWITCH_INPUT = 27 # スイッチ入力で使用するポート番号の指定 LED_OUT = 25 # LED 向け出力で利用するポート番号の指定 # GPIO の初期化 # GPIO.BOARD: 物理ピン番号(左上からの連番) # GPIO.BCM: 役割ピン番号(broadcomが命名しているもの)今回はこっち採用 GPIO.setmode(GPIO.BCM) # LED_OUT はあくまでアウトプット利用 GPIO.setup(LED_OUT, GPIO.OUT) # Switch_input は入力用に IN 指定 GPIO.setup(SWITCH_INPUT, GPIO.IN) try: # 無限ループ while True: # スイッチが High になったらLEDに給電 if GPIO.input(SWITCH_INPUT) == GPIO.HIGH: GPIO.output(LED_OUT, GPIO.HIGH) # スイッチ押してない場合は、LED に給電しない else: GPIO.output(LED_OUT, GPIO.LOW) sleep(0.01) # ループに休憩入れる(入れないとCPUがビジー状態になりえる) except KeyboardInterrupt: # Ctrl+C で終了したときの処理。要するに終了命令やね pass # 終了前にデバイス開放(しないと色々問題になる) GPIO.cleanup()
コードよりコメント書くほうが疲れたわ(汗
わかりやすい感じですね
コード実装: スイッチの Toggle 実装
今度は、スイッチを押されたタイミングをイベントで拾う方法。
写真はこれで撮った
import RPi.GPIO as GPIO from time import sleep SWITCH_INPUT = 27 LED_OUT = 25 # LED の状態設定 isLedStateOn = False # イベントコールバック def switch_callback(channel): global ledState if channel == SWITCH_INPUT: isLedStateOn = not isLedStateOn if isLedStateOn: GPIO.output(LED_OUT, GPIO.HIGH) else: GPIO.output(LED_OUT, GPIO.LOW) GPIO.setmode(GPIO.BCM) GPIO.setup(LED_OUT, GPIO.OUT, initial = GPIO.LOW) # プルアップダウンの組み込み抵抗を設定できる。 # これを入れると、スイッチ側の抵抗と GND が不要になる(別に取らなくても良いといえば良い) GPIO.setup(SWITCH_INPUT, GPIO.IN, pull_up_down = GPIO.PUD_DOWN) # SWITCH_INPUT の入力が入った(GPIO.RISING Low -> High となった)ら、switch_callback を呼ぶべし。 # なお、物理的にはスイッチ変動の瞬間に On/Off が前後するので、一度イベントを検出したら、200ms は待機する GPIO.add_event_detect(SWITCH_INPUT, GPIO.RISING, callback=switch_callback, bouncetime = 200) # イベント式に変わったので、ループ処理はあくまで終了まで待機する扱い try: while True: sleep(0.01) except KeyboardInterrupt: pass GPIO.cleanup()
Raspberry pi 4 をSSID隠蔽した無線 LAN に接続する
うん、自宅の設定がそもそも SSID 隠蔽だからねぇ(汗
ということでやってみた記録。
接続設定を作成する
pi@raspberrypi:~ $ wpa_passphrase "ssid_name" "password" network={ ssid="ssid_name" #psk="password" psk=16c384515e2eb5bad36a7bd4057ffd7987f9ee248c2a9c44c16bcf74077abc51 }
設定にハッシュ化もしてない値を保存できないので、こんなコマンドでパスフレーズを生成します。
実にわかりやすいこって
設定を記載
無線LAN設定はここに記載されてます
pi@raspberrypi:~ $ sudo vi /etc/wpa_supplicant/wpa_supplicant.conf
ここを開くと色々出てくるので、こんなふうに記述しましょう
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev update_config=1 country=JP network={ ssid="ssid_name" #psk="password" psk=16c384515e2eb5bad36a7bd4057ffd7987f9ee248c2a9c44c16bcf74077abc51 scan_ssid=1 } ~
scan_ssid=1
を記述することで、隠れた SSID でも接続を試行してくれます。
ここまで書いたら reboot
で再起動して OK
プログラム入門書で毎回「足りないなぁ」と思った事
脳トレパズル本 プログラマを育てる脳トレパズル 遊んでおぼえるPythonプログラミング&アルゴリズム を読んで、最初の課題が三目並べなのだけど、毎回入門書に足りないものがあるんじゃまいかと思うことがあったので、じゃぁ「職業エンジニアとして考えるならどういう開発スキルが要るのか?」をコンセプトに考えてみた。
テストの観点
この点は若干の本には記載がある。おそらく第二言語として学ぶ人を前提にしてる場合は書いてある。
しかし多くの入門書ではテストを書くこと自体が扱われていない。
しかし、プログラマーを目指す人のための入門書には是非ほしい。
本のコンセプト上入れるべきでないケースもあるだろう。
あくまで自動化をさせる目的の 退屈なことはPythonにやらせよう ―ノンプログラマーにもできる自動化処理プログラミング や、 プログラマを育てる脳トレパズル 遊んでおぼえるPythonプログラミング&アルゴリズム 、ITエンジニアがときめく自動化の魔法~仕事を効率化したくなる自動化テクニック~ なんかでやる必要はないかもしれない。
とはいえ、実際問題テストというのは作りの確認作業なので、問題の早期発見には必須項目だ。
まずは作れるようになることが先決というのはわかる。
しかし実務の観点で見れば、保守の過程で修正し、変更が入る。既存の処理に影響を与えないためにもテストは必要だ。
ならテストコードは処理の仕様が変化していないことを確認(リグレッションテスト)できる最も簡単な手段でもある。
可読性の観点
この項目も欠けがちだ。
むしろ、実装系技術書全般で足りていない。
別に言語仕様と直接的に結びつく問題ではない。ならばコラム的に説明を入れることは可能なハズだと思う。
強いて書籍時の問題を挙げるなら、変数名が長くなる。尺や改行を踏まえると問題になることはわかるが…むしろ初心者にこそ叩き込んでおきたいと思うのは私だけだろうか?
可読性の観点はいくつもあるので、すべてを説明することは不可能だろう。感性の問題もあるので、深くは立ち入れないかもしれない。
しかし、名称の付け方、説明変数などのテクニックはどの言語においてもほぼ共通する内容のハズだ。
実務上では、常にコードを読む。なぜならここを修正したらどこに影響するのか?これは何をするものなのか?その速度はすなわちコードの修正、変更時間に直結する。
読みやすさに対する最小限の記述はすべきだ。
というかアルゴリズム系の本は、数学者的なセンスで書かれてることが多いので、変数名が数学的記号に合わせがちになる。
すると、説明もなく変数が名数学してると、数学してる人にしか読みにくい実装となっていて、本来知りたいと思っている層のエンジニアには読みにくいものではなかろうか?
エンジニア脳なら 「数式<=コード」で実装を理解する人が多いので、その点は本当に困る。
メソッド分離、クラス分離の考え方
これも実装系技術書全般で足りていない様に思う。
SOLID 原則まで紹介しろとは思いません。
役割、目的ごとに分割する考え方はやはり必要な気がします。
アプリケーション実装系、複雑なアルゴリズム(AIとか)の実装系本でこれが全くされてないと発狂しそうになる…。
1メソッドで 50 行とか書いてある入門書を見ると正直レビューに☆1(むしろマイナス)をつけたくなります。
「動けばいい」じゃねーんだよ! …すまない、ヒートアップした。
だが、思うことはそういう事だ…特に入門書である場合、初心者が学ぶ過程で、クッソ汚いコードを書く癖を残してほしくはないものである。
確かに!下手な入門書より面白い「プログラマを育てる脳トレパズル」
プログラマを育てる脳トレパズル 遊んでおぼえるPythonプログラミング&アルゴリズム
- 作者:増井 敏克
- 発売日: 2020/12/22
- メディア: 単行本(ソフトカバー)
最近読んだのでレビューを。
入門書じみてるのにワクテカがとまらんw
この入門書のポイント
- Good
- 発想をコードに落とす実装力が身につく : あくまでゲームとパズルを解くのが中心
- 課題に対して解決を考える基礎力がつく : プログラミングの考え方を中心に据えているので、「入門書やったけど、これで何ができるかわからない」がない
- Weak
- 逆に言語仕様の深い話はしない : GUI とか 3D とかやりたくなったら、ライブラリは別途調べる必要がある
という、非常にアルゴリズム寄りな内容。
むしろ小学校でのプログラミング教育に突っ込みたい内容だ。
ただし文章などを含むと、独力で読むには最低中学生、高校生以上が望ましい文章だと思う。
逆を言えば家庭であれば親が一緒になってやるには丁度いい難易度。
ターゲット層
多分この本が狙ってるターゲット層はこんな感じだろう。
- 何らかのプログラミングの入門書やったけど「これで何ができるんだろう?」という人
- 言語仕様説明系の入門書読んで混乱した人。写経系入門書読んで意味不明とブチ切れた人
- プログラミング初心者(年齢的には、高校生以上。頑張れば中学生でも読めないことはない)可能。
- プログラマー就職してからプログラム言語を触ったけど、自分で実装設計できない人
所感
続きを読むChrome は実は裏で色々できる
Google Chrome は実はコマンドラインから色々できるという話です。
事の起こりは、Selenium でブラウザ起動もせずスクショが取れたことから。
で、調べて見たら出るわ出るわ…
ブラウザ表示せずスクショを取るあれこれ
ということで早速やってみる。
--headless --print-to-pdf (URL)
を指定すると、
% /Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --headless --print-to-pdf https://white-azalea.hatenablog.jp/ [1223/205258.121603:ERROR:xattr.cc(63)] setxattr org.chromium.crashpad.database.initialized on file /var/folders/c6/_s3qbf0x5qg5fxfdhm__hp_40000gn/T/: Operation not permitted (1) [1223/205258.122462:ERROR:file_io.cc(90)] ReadExactly: expected 8, observed 0 [1223/205258.123082:ERROR:xattr.cc(63)] setxattr org.chromium.crashpad.database.initialized on file /var/folders/c6/_s3qbf0x5qg5fxfdhm__hp_40000gn/T/: Operation not permitted (1) [1223/205258.476157:ERROR:command_buffer_proxy_impl.cc(122)] ContextResult::kTransientFailure: Failed to send GpuChannelMsg_CreateCommandBuffer. [1223/205305.595811:INFO:headless_shell.cc(616)] Written to file output.pdf.
こんなログが流れるが
% ls -l total 16224 -rw-------@ 1 armeria staff 8305469 12 23 20:53 output.pdf
マジか!?
% /Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --headless --screenshot https://white-azalea.hatenablog.jp/ [1223/205945.105995:ERROR:xattr.cc(63)] setxattr org.chromium.crashpad.database.initialized on file /var/folders/c6/_s3qbf0x5qg5fxfdhm__hp_40000gn/T/: Operation not permitted (1) [1223/205945.107835:ERROR:file_io.cc(90)] ReadExactly: expected 8, observed 0 [1223/205945.109470:ERROR:xattr.cc(63)] setxattr org.chromium.crashpad.database.initialized on file /var/folders/c6/_s3qbf0x5qg5fxfdhm__hp_40000gn/T/: Operation not permitted (1) [1223/205945.475913:ERROR:command_buffer_proxy_impl.cc(122)] ContextResult::kTransientFailure: Failed to send GpuChannelMsg_CreateCommandBuffer. [1223/205949.235907:INFO:headless_shell.cc(616)] Written to file screenshot.png.