それマグで!

知識はカップより、マグでゆっくり頂きます。 takuya_1stのブログ

習慣に早くから配慮した者は、 おそらく人生の実りも大きい。

npm で自作のパッケージをgit(gitlab/githubなど)からadd(インストール)する

npm で自分のパッケージを使いたい

npmjs.com にパッケージを公開しても良いんだけど、既存のパッケージをちょっと触ったくらいのパッケージを公開するのは忍びない。

自分のgitレポジトリのnpm パッケージを npm add したいとき。

git のレポジトリを package.json に登録する。

npm ので、gitレポジトリをインストール

npm init 
npm install "git+ssh://git@gitlab.example.com/takuya/my-sample.git"

package.json

インストール後のpackage.json はこんな感じになる。

{
  "name": "sample",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "my-sample": "git+ssh://git@gitlab.example.com/takuya/my-sample.git"
  }
}

アップデートしたいとき。

レポジトリ側をアップデートしたあとの、利用側では次のようにする。

npm update

npm で自作コマンドを自分のためだけに一瞬だけnpmjs公開することを通してnpm公開を学ぶ

経緯

パブリックな名前空間を自分専用に使うのは、本当は駄目なんだろうけど、npm みてると my own private なパッケージが結構あるので、ヤッたもん勝ちっぽいので試すことに。そりゃ本当は、 private つかえとか 自分のサーバーでnpm registry たてて使えとか、レポジトリを指定しろとか、npm pack して持ち出せよとかいろいろあると思うんですが。

試すだけならpublish 直後72時間以内に忘れずに unpublish 公開を取り下げられる。ちゃんと削除できるので、試すだけなら大丈夫。大丈夫。さきっちょ☆だけ。さきっちょだけだから。

TL:DR

npm adduser
npm init
npm publish 
mkdir other_proj; cd other_proj
npm i $name 
node ./node_module/bin/my-pachakge
npx helo

準備1:アカウント

npm にアカウントを作成する アカウントないと始まらないので! f:id:takuya_1st:20190511002551p:plain

準備2:npm コマンドにアカウントを覚えさせる

npm adduser

f:id:takuya_1st:20190511002557p:plain

ここで覚えさせた adduser 結果は global の設定として ~/.npmrc に書かれる

takuya@~$ cat .npmrc
prefix=/Users/takuya/.lib/node
//registry.npmjs.org/:_authToken=xxxxxxxxxxxxxxxxx

どのユーザーでログインしたのかわからなくなったら

npm whoami

作業1:公開するモジュールを作る

mkdir tekito
cd tekito
npm init

npm のパッケージを作成すると、次のような質問が聞かれる。

takuya@tekito$ npm init
This utility will walk you through creating a package.json file.
It only covers the most common items, and tries to guess sensible defaults.

See `npm help json` for definitive documentation on these fields
and exactly what they do.

Use `npm install <pkg>` afterwards to install a package and
save it as a dependency in the package.json file.

Press ^C at any time to quit.
package name: (tekito) takuya-1st-npm-examples
version: (1.0.0) 0.0.1
description: 作業用
entry point: (index.js)
test command:
git repository:
keywords:
author: takuya
license: (ISC) GPL-3.0-or-later
About to write to /Users/takuya/tekito/package.json:

{
  "name": "takuya-1st-npm-examples",
  "version": "0.0.1",
  "description": "作業用",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "takuya",
  "license": "GPL-3.0-or-later"
}

package nameを決める。

npm.js に公開されても、他人に迷惑がかからないように、なるべく自分だけの名前にしておく

ライセンス

とりあえず、GPLでしょやっぱり。GPLは、"GPL-3.0-or-later"と指定します。

test

ここはテストコマンドだけど、後でちゃんと実装する。

git repos 

git repos がアレばどこでもいいと思うんだけど。gitlab とか bitcuket でソース公開してるならそれを書いておけばいいのかな? たぶんnpmjs のパッケージ詳細に掲載される。(試してない)

main ( entry point ) 

これ大事。require したときにこのファイルが最初に実行される。

作業2:コードを書く

index.js にコードを書く

// require ; 最初に実行される。
console.log( "hello from index" );

index.js は main に指定したのでここがrequire 時に実行される。

公開する。

コード書いて、プライベート情報が暴露され得ないと確認したら、公開する

npm publish

確認する。

新しい、プロジェクト(フォルダ)を作って、インストールしてみる プロジェクト(フォルダ作成)

mkdir my-project; cd my-project

公開したやつを持ってくる。

npm i takuya-1st-npm-examples

require してみる。

my-project/requre-test.js

require ("takuya-1st-npm-examples");

require を書いたファイルを実行する。

cd my-project
node requre-test.js
> hello from index 

ここまでで、npmjs に公開とインストールが完了する。

ちなみに、ちゃんとrequire できるのは、global.module.paths にちゃんと反映されているから。

takuya@sample$ node -e 'console.log(global.module.paths)'
[ '/Users/takuya/Desktop/my-project/node_modules',
 '/Users/takuya/Desktop/my-project/node_modules',
  '/Users/takuya/node_modules',
  '/Users/node_modules',
  '/node_modules' ]

コマンドを作る。

次に、npm i 後に使えるコマンドを作る。

自作コマンドを作っておくと npm i するだけでいつもの自分のコマンドがインストールできる。

公開しているパッケージのプロジェクトを開いて。

package.json に "bin" を追加する

bin に指定した名前で コマンドが作られる。

"bin": {
"hello": "hello-command.js"
},

この場合、hello という名前で、 hello-command.js  が実行できるように、node_modules の下にコマンドが作られる。

しかも cmd.exe など Windows 環境でも動くように作られる。

コマンドの中身はjs ファイルだが、shebang や cmd 呼び出しにも対応してくる。windowsだと hello.cmd が作られるはずです。

コマンドの中身を作る。

コマンドの中身を書きます。

#!/usr/bin/env node
console.log("hello takuya san");

コマンドを作ったら公開します。

npm publish

すでに公開している場合は、バージョンを上げてやります。

vim packages.json
## version を上げる
"version": "1.0.4"

または

git add  .
git commit -m 'add'
npm version 1.0.4

なぜ、git コマンドがでてくるかというと、git 管理されているフォルダはgit commit 済みでないと npm version を使えません。

使ってみる。

自分の適当なプロジェクトで 公開したパッケージのコマンドを使います。

npm i takuya-1st-npm-examples

コマンドが作られます。

takuya@ my-project$ ls -l  ./node_modules/.bin/hello
lrwxr-xr-x 1 takuya staff 29 2019-04-17 19:25 ./node_modules/.bin/hello -> ../takuya-1st-npm-examples/hello-command.js

json ファイルに、"hello": "hello-command.js" と指定したのでショートカットが作られています。便利。

自作のコマンドをいつでも便利に使う。

ちゃんとコマンドが動くことが確認できました。

ここまできたら、もうglobal を使っても安心です。

自分のシェル環境に 自作のコマンドをglobal インストールしてしまいます。

$npm -g i takuya-1st-npm-examples

これで、よく使うコマンドをnodejs で記述することが出来て管理もインストールも楽ちんになりました。

プロジェクトにいるときだけ コマンドを使いたい

bin の場所は次になります。

$(npm root)/.bin

インストールしたコマンドをローカル(npm)で使うときは

$(npm root)/.bin/hello 

これを省略するには、npx が使えます。

npx hello

npxは便利なのでglobal に入れておくといいかも。npm i -g npx

npmjs は公共スペース

マナー厨の老害っぽいですが、npmjs は公共スペースなので他人の迷惑にならないようなパッケージ名で後悔しましょう。

(ってうか、gitlab/github などのgitレポジトリをpackage.json で指定するほうがいいよ絶対。)

それか、ちゃんとnpmjs に課金してプライベートを使う

f:id:takuya_1st:20190511002600p:plain

package.json に private : true をちゃんと書くことでプライベートなります。

あと、名前に@をつけてScopedであることを明示するとか

あとはVerdaccioのようなprivate registry を自前で用意して作成するという手もある。

公開を取り下げる。

もし本当に、ちょっと試したいだけだったのなら、ちゃんとunpublish でモジュールを削除すること。

公開後72 時間未満なら、ちゃんと消せるんだよ。

> npm unpublish "takuya-npm-sample" ---foce

今回取り上げたこと

  • npm でパッケージ公開
  • npm でコマンドを作成
  • npm でrequire の main( entry point )

今回取り上げなかったこと

  • module export
  • npm --global と ローカル
  • npm のrequire Path

参考資料

https://qiita.com/TsuyoshiUshio@github/items/850245c5fb40310ede9b

bashのループと数字比較を組み合わせでVPNを接続開始して接続待ち、接続後に処理をする。

bash のサンプルプログラムを考えてた。

よくあるパターンとして、

〇〇を実行して〇〇が△△になるのをまってから、□□する

を考えてみた。

VPN の接続を待機する

今回のサンプルはMacVPNを接続し、接続待ちをし、VPN接続が完了したらルーティングを加える。

vpn の接続

mac の場合は次のようにする。

networksetup -connectpppoeservice "$VPN_NAME"

VPNの接続名は次のようにして取得できる

VPN_NAME=$(networksetup -listallnetworkservices  | \grep interlink )

VPNの接続状態を取得する。

[[ $(networksetup -showpppoestatus $VPN_NAME )  == connected ]];

IPルーティングのテーブルにVPNへの経路を追加する。

ip route add $TARGET_IP/32 dev ppp0

一定間隔で状態をウォッチして、指定時間超えたら失敗とみなす。

これは、bashの数値演算と数値の比較を組み合せる。

while check_status
do
 sleep -1 ;  (( cnt++ )); 
  if (( $cnt > 30 )) ; then return 1 ; done
done

全部まとめたのがこれ。

接続を試行して、接続中を待機しつつ、接続後にIP routing をする。

最初に考えた処理待ちをしながら処理が終わったらXXXするのサンプルとしては良いと思う。

ここでは、コマンドがノンブロッキングな場合を想定している。

VPN_NAME=$(networksetup -listallnetworkservices  | \grep interlink )
TARGET_IP=192.168.111.156

function isConnected(){
  [[ $(networksetup -showpppoestatus $VPN_NAME )  == connected ]];
}
function disconnectVPN(){
  networksetup -disconnectpppoeservice "$VPN_NAME"
}

function connectVPN(){
  #
  isConnected || networksetup -connectpppoeservice "$VPN_NAME"
  cnt=0
  while !isConnected ; do 
    (( cnt++ ))
    printf "${cnt} time  .waiting...\r"
    sleep 1
    if (( $cnt > 30 )) ; then
      echo failed.
      return 1 ;
    fi
  done;
  return 0;
}

function addRoute(){
  echo add route 
  ip route add $TARGET_IP/32 dev ppp0
}

function  main() {
  #
  echo start
  ## 
  connectVPN && addRoute;
  
}

main;

関連資料

bashのif文で数字の比較を評価条件ぱぱっとやる方法(C言語スタイル - それマグで!

git でclone 元のリモートレポジトリのURLを確認

git の clone 元

レポート作ったり、git のURL教えてと言われたときに

git config --get remote.origin.url

または

git remote show origin

clone したら origin に入るので、remote/originから確認する。

フレッツ網内折返しのv6 で拠点間を単純にIPIP/GREでトンネル接続してVPNする。

フレッツのv6網の網内同士で通信したい。

フレッツのv6オプションを申し込んだら、フレッツ網内(広域イーサネット)内部での通信ができるようになる。しかも追加料金無し!

これはいいオモチャになりそうだとずっと思っていて、ようやく一通りをLinuxルータで扱えるようになったのでメモとして残します。

フレッツのIPv6オプション

このオプションが有ると、インターネットを経由せずに通信が可能です。

f:id:takuya_1st:20190506142217p:plain https://flets.com/v6option/

初期ONに切れてる人もいるようですが、私個人としてはデフォルト有効は素晴らしいのではないか、などと思ってる。ISP経由しなくても隣近所の一般のご家庭と通信ができるようになる。しかも無料で。NTT東西がNTT法で縛り付けられた結果で生まれた謎のインターネット、それが広域イーサネットです。

NTTでフレッツ・v6オプションを契約している人は切れた方がいい(デフォルト設定でのセキュリティは皆無) - Qiita

設定例

今回はどちらの拠点間もLinuxルーターで構成することにした。

## mode ipip6 
## 拠点1ルーター
ip -6 tunnel del tun1 mode ip4ip6 remote 2001:a2xx:xxxx:a300:b2be:xxxx:xxx7  local 2001:a25xx:3xxx:3700:xxxx:xxxx:c53b
ip -6 tunnel add tun1 mode ip4ip6 remote 2001:a2xx:xxxx:a300:b2be:xxxx:xxx7  local 2001:a25xx:3xxx:3700:xxxx:xxxx:c53b
ip link set tun1 up
ip addr add 172.16.1.2/30 dev tun1
ip route add 192.168.2.0/24 via 172.16.1.1 dev tun1
iptables -I INPUT -i tun1 -j ACCEPT
iptables -I FORWARD -i tun1 -j ACCEPT
iptables -I OUTPUT -o tun1 -j ACCEPT
iptables -I FORWARD -o tun1 -j ACCEPT

ローカル側とリモート側の違いは remote と local だけなので、同じ設定をリモートとローカルを入れ替えて通すだけ

## 拠点2ルーター
ip -6 tunnel del tun1 mode ip4ip6 local 2001:a2xx:xxxx:a300:b2be:xxxx:xxx7  remote 2001:a25xx:3xxx:3700:xxxx:xxxx:c53b
ip -6 tunnel add tun1 mode ip4ip6 local 2001:a2xx:xxxx:a300:b2be:xxxx:xxx7  remote 2001:a25xx:3xxx:3700:xxxx:xxxx:c53b
### 以下IP以外はヤッてることが同じ
ip link set tun1 up
ip addr add 172.16.1.2/30 dev tun1
ip route add 192.168.1.0/24 via 172.16.1.1 dev tun1
iptables -I INPUT -i tun1 -j ACCEPT
iptables -I FORWARD -i tun1 -j ACCEPT
iptables -I OUTPUT -o tun1 -j ACCEPT
iptables -I FORWARD -o tun1 -j ACCEPT

上記設定に必要なもの

Linuxカーネルのモジュールのロード

modprobe ip6_tunnel

パケットのフォワーディングをできるような設定(ルーターに使ってるなら最初から入れてるはず)

$ sysctl net.ipv4.conf.all.forwarding
net.ipv4.conf.all.forwarding = 1

rp_filter  はオフ

$ sysctl net.ipv4.conf.tun1.rp_filter
net.ipv4.conf.tun1.rp_filter = 0

greの場合。

ipip6(ip4ip6) のところが、grev6 になる。

ip -6 tunnel del tun1
ip -6 tunnel add tun1 mode grev6 local 2001:a2xx:xxxx:a300:b2be:xxxx:xxx7  remote 2001:a25xx:3xxx:3700:xxxx:xxxx:c53b

GRE のパケットを許可する

iptables -A INPUT -p gre -j ACCEPT
iptables -A OUTPUT -p gre -j ACCEPT

拠点間通信の速度

Linux ルータの限界が200Mbps 程度なのでそれまで出てた。速度上限がわからない。上限が見えないなんて、サイヤ人みたいだな。

フレッツのv6オプションについて知っておくこと。

広域イーサネットでIPv6で通信ができる。IPv6は自動的に払い出される。そして半固定。NTT側からRAで払い出される。

ひかり電話契約の有無で、取得方法が異なる。ひかり電話なしの場合、RAで取得する。ひかり電話契約があるとNTTのHGWからDHCPv6-PDで払い出される。*1

いずれの場合もv6 対応したOSを挿すだけでv6が使えるようになる。

v6広域イーサネットを経由してインターネットに出ていくにIPoEを使うには契約が必要。だが、インターネットに出ていかないならISP契約が必要ない!でも通信はできる。あとはわかるな。

IPv6があるとフォールバックする

IPoE契約してないPPPoEのISP(IPv4)のまま、v6を有効にするとインターネットつながらない「壊れたv6インターネット」になってしまう。そのためインターネット接続開始時に遅延を感じてしまう。

これは、IPv6通信が失敗するまでIPv4を通信をしないv6優先のためで、iOSなどはSafariでページを開く際にこのフォールバックが発生し体感でモタツキを感じてしまう。

フォールバックによる遅延防止→IPv6 をLAN内部に展開しない

拠点間通信にv6を使うのであれば、ルーターだけIPv6を受け取ってLAN内部はv4で運用すれば良いわけです。つまりLAN内部へフレッツIPv6のパケットを通さなければ問題は解決する。

iptables(ip6tables) で v6 のLAN内部へFORWARDを止めてしまえばいい。

今回はルーターだけにv6 アドレスを持って拠点間通信させる予定。なので ipt6ables のINPUTでルーター(CPU)側にだけパケットを通せば、フォールバック問題は見て見ぬふりができる。

v6 インターネットへLANを公開しない

ip6tables でRA/DHCPv6 などICMPパケットを止めてしまえるので、LAN内部の各種機器がフレッツv6 アドレスを受け取らずにすみ、LANがインターネットに公開されることもなくなる。

ひかり電話ありの場合は、HGWで設定ができる。

ひかり電話なしの場合は、ip6tables で止めてしまえばいい。ググってもパススルーとか対応機器を用意しましょうとかあれこれ書いてあるけど、自由なソフトウェアで構成できないルーターはちょっと・・・

*1: ホームゲートウェイを経由しなければひかり電話なしと基本的には同じと考えていい。 PDあるけど

ubuntu の暗号化インストールのディスクを拡張する

ubuntu を暗号化ディスクでインストールすると

ubuntuを暗号化ディスク(dm-crypt) でインストールすると、LVM on LUCKSでインストールされていました。

ノートPCなど物理的に紛失しそうなデバイスは暗号化ドライブを使ったほうが無難ですし、SSD/HDDを物理的に強奪されるリスクを考えると暗号化ディスクのほうが無難なので、暗号化ディスクにしていた。

とくにUSBメモリにインストールしたUbuntuディスクには暗号化ドライブが望ましい。

USBメモリの容量拡張で dd で移動したとき、暗号化ドライブの取扱いを確認したのでメモ。

LVM on LUCKS

ubuntu の暗号化パーティションはLVMが暗号化ドライブの上に構築している

ディスクの構成を lsblk で確認すると次の通り。

sda                       8:0    0 223.6G  0 disk  
├─sda1                    8:1    0   512M  0 part  /boot/efi
├─sda2                    8:2    0   732M  0 part  /boot
└─sda3                    8:3    0    36G  0 part  
  └─sdb3_crypt          253:0    0    36G  0 crypt 
    ├─ubuntu--vg-root   253:1    0    28G  0 lvm   /
    └─ubuntu--vg-swap_1 253:2    0     8G  0 lvm   [SWAP]

ubuntuが入っている root ファイルシステムスワップは crypt デバイス上に存在する。 起動時は /boot, /boot/efi から起動するので efi ブート中に cryptsetup で暗号化を解除してくれる。

LVMなのでリサイズは通常の方法と変わらない。

実は、ここがあまりに簡単すぎて拍子抜けだったのだが、容量の拡大・縮小は、通常のLVMを用いた処理と何ら変わらない。本当にdm 関連は便利ですね。

手順

次の手順で拡張した。 起動できるUSBドライブが1つ必要

  1. ubuntu のインストールUSBを作る
  2. インストール用USBでLiveとして起動する(インストールしないで使う)
  3. 暗号化ドライブを解除
  4. gdisk/fdisk でパーティションを拡張
  5. LVM を拡張
  6. e2fsck / resize2fs でファイルシステムを拡張
  7. 再起動

ブート後にターミナルを開く

ターミナルを開いたら、暗号化ディスクにアクセスできるようにする

sudo cryptsetup luksOpen /dev/mapper/sbd3_crypt my-crypt-drive

このコマンドは、次のようになっている。

sudo cryptsetup luksOpen $DEVICE_PATH $VolumeName

これで準備完了

gdisk や gparted でディスクを変更

ディスクの容量を確保する

sudo gdisk /dev/sda

LVM で容量を確認

sudo pvs 
sudo vgs 

追加した容量分が、PV/VGに増加していることを確認する。

lvextend で容量を割り当てる

sudo lvexnted -l +100%FREE ubuntu-vg/root

ファイルシステムを拡張

最後に、LV上に展開されているファイルシステムを拡張する 私の場合EXT4なのでEXT4の手順に従う

sudo e2fsck -p /dev/mapper/ubuntu--vg/root

チェックが終わったら、パーティションファイルシステムを拡張する。

sudo resize2fs /dev/mapper/ubuntu-vg-root

再起動

マウントしてみたり、テストして無事に終わったら、再起動

まとめ

暗号化ドライブをつかっていても、 LVM on LUCKS は、LVM上にLVMを作っているような感じで、特に新しい知識も必要なく、リサイズすることができた。

暗号化ドライブなので、扱いが面倒かなと思ったけど、全然そんなことなかった。

いまのところ暗号化ドライブを使っていて特に問題はないので今後も使っていきたい。

UPnPでポートを開放を試し、ルータのUPnPの設定をテストする。

UPnPが正常に動いているか確認したい。

UPnPで、クライアントからルーターにポートをリクエストして、自分宛てにポート転送してもらう。

ルーターIPv4で動いてるとポートフォワーディングを自動的にFirewallに書いてくれる。

Mac からUPnPをリクエストする。

UPnPを設定する方法は、ルーターごとに違うのでそちらに書くとして。

UPnPのリクエストを手軽に試したらどうしたら良いだろうか?

PortMap というMacの app を見つけた。

f:id:takuya_1st:20190426180627p:plain

実際に試してみた。

これが、UPnPでポートをリクエストしてルータから割り当て貰うのに成功した図。

f:id:takuya_1st:20190426121919p:plain

UPnP試せるのは良い。

TCPの細かい仕様を知らなくても手軽にポート開放ができたり、UPnPが動か調べられるのは良い。

とくに、UPnPがマルウェアに悪用されてポート開放されたりするので、最近はオフにしたいことが多いので、ちゃんとオフにできたか調べられるのは良い。

関連サイト

https://codingmonkeys.de/portmap/

https://github.com/monkeydom/TCMPortMapper/releases

動的にscript を追加したときに読み込みを待つ(body の最後とかheadに足したあと待つ)

動的に script タグを書き出したとき

関数が欲しくて、あとでチョコっとScriptを書き出すJSを書いたときに、そのスクリプトがロードされるのを待つ。

スクリプトがロードされないと使いたい関数がロードされないもんね。

onload でできた

意外にシンプルな解決策で解決したわ。

サンプルコード

var src_url = 'http://example.com/example.jp'
var load_func = function(){
  console.log("loaded")
}

(function(src_url, callback){
  document.body.appendChild(function(src_url, callback) {
    var u = new URL(src_url);
    sc = document.createElement("script");
    sc.type = "text/javascript";
    sc.src = u.toString();
    sc.onload = callback;
    return sc;
  }(src_url,callback));
})(src_url, load_func );

もっと、then() とか promise 使おうかと思ったけど、すごく簡単に解決したのでこれで良い。

2019/05/16 追記

ロードが1つだけってことはないので、複数のscript url をロードするようにPromiseに仕立て直した。

http://takuya-1st.hatenablog.jp/entry/2019/05/16/194721

rclone でサーバー(gdrive/owncloudなど)のファイルをローカルにFUSEマウントする。

rclone に mount オプションを見つけたのです。

早速使用してレポートします。

rclone mount でリモートをFUSEとしてマウントする。

マウントした結果がこちら

f:id:takuya_1st:20190422125207p:plain

マウントコマンド(シンプルでいい)

rclone mount remote locale-dir

REMOTE は名前で識別すると楽なので config から読み出すといい(詳しくは --config )

使用感

初回起動はディレクトリの一覧を読み込むので少し時間がかかる。

f:id:takuya_1st:20190422125417p:plain

読み込んでしまえば、あとはファイルを開くときやサムネイル転送に時間が掛かる程度。

ファイルを開いてしまえばあとは(キャッシュされるのかな?)開くの早い

アップロード:ローカル→リモート

ローカルにファイルを作れば、ファイルの転送が始まる。自動的に検出して転送してくれる。

Macの場合iCloud Driveのようにゲージが表示されて

削除:ローカル→リモート

削除もリモートに反映される。こっちは早い。

楽ちん。

rclone mount 

具体例

mkdir /home/takuya/mounts/data
rclone mount $remote /home/takuya/mounts/data

これでいいのだ。

調べてないこと

同時に複数人が編集をしたときの衝突。

活用法を考える。

  • Dropbox代わり
    • リモートの転送先をいじればDropboxなど専用のクライアントが一切なしに、保存先を自由にできる
  • git 代わり
    • 有料G○○gle Drive などバージョンをアーカイブしてくれるサーバーならバージョン管理にgitを嫌がるデザイナ*1でも使いやすいかもしれない
  • SFTPクライアント代わり

たとえば、docker にファイルシステムとかいらんのかもしれない。仮想マシンなどもrclone でリモートをマウントすれば・・・・

*1:* 滅びろって思うけど

magick で写真のプライバシーのメタ情報(exif)やサムネイルを削除

写真を加工してもサムネイルが更新されない。

こういう場合は、写真(JPEG)に埋め込まれている。サムネイルが更新されない可能性がある。もしくはブラウザ(Finder)のキャッシュ。

私の場合、convert で色を反転させたけどサムネイルが更新されなかったので、JPEGexif:thumbnail やSOFが更新されてないんだろうと推測

写真のEXIF を削除するコマンドと同様にできる

mogrify -strip sample.jpg 

または

convert -strip a.jpg b.jpg

サムネイルの更新もstrip でできるって少し考えたら気づいただろうけど、わざわざ検索してしまったので、メモを残すことにした。

私的なプライバシー情報を剥がす

このやり方は、以前にも書いたことがある。GPSなどの情報を消す方法と同じ。

個人情報を削除するコマンドでサムネイルを剥がせる。

takuya-1st.hatenablog.jp

もし、exif の特定情報だけを更新したいときは

これも以前に書いた。Exiftool でできる。

takuya-1st.hatenablog.jp

gitlab への git push やgit lfs の送信で413 エラーになった。

gitlab を使ってて謎だったエラー

LFS: Client error: https://gitlab.example.com/takuya/sample.git/gitlab-lfs/objects/5f32fd160/10 from HTTP 413

なんか解決しなくて、しばらく放置してたけど、原因に気づいた、これgitlabじゃないnginx だ。

nginx 側で送信されるファイルサイズを制限

 ## gitlab specified location
  location / {
    client_max_body_size 50M;

そういえば、50Mになっていた。LFSで1GB のファイルとか送れないわけですよ。

なるほどね。

    client_max_body_size 1000M;

とかにして解決。

gitlab の構成的に、nginx → gitlab内蔵nginx → gitlab-workhorse(rails) なので、わかりにくいだろうな。うちは内蔵ngix 切ってるから気づけた。

そういえば、apache+php + jquery file upload とかでも昔ハマりました。nginx が多段で入ってるのすっかり忘れてた。

参考資料

https://github.com/go-gitea/gitea/issues/2930

bash の* ( アスタリスクのワイルドカード)でドットファイル(隠しファイル)を一時的にマッチさせる

TL;DR

shopt -s dotglob
shopt -u dotglob

ドットファイルも含めたい時がある。

for i in $ (ls -a) はめんどくさいんだよなぁ

ホームディレクトリで、*でワイルドカードマッチさせても一致しないのが不便。 ls -al しているときは気にならないのだけど、一括して容量を取得したり、ファイルをまとめて移動させたいときなど、ワイルドカードドットファイル(隠しファイル)が指定されなくて困る時がある。

ホームフォルダ内の容量を見たいとき。

takuya@takuya$ du -cksh *
9.0M    Documents
17M Library
20K PhpStorm2018.3-settings.zip
2.5M    iodine
28M total

あああ、ドットファイル無いよ。

これで解決。

shopt -s dotglob

shopt のdotglob を指定すれば、dotfile も含めて コマンドの引数に展開される。

takuya@takuya$ du -cksh *
4.0K    .auth_keys
4.0K    .bash_aliases
4.0K    .bash_completion
48K .bash_completion.d
4.0K    .bash_profile
8.0K    .bashrc
4.0K    .bashrc.cygwin
4.0K    .sqliterc
36K .ssh
8.0K    .tidy.conf
32K .vim
20K .viminfo
12K .vimrc
9.0M    Documents
17M Library
2.5M    iodine
136M    total
takuya@takuya$ shopt -u dotglob

やったね。

もとに戻すなら

かと言って、いつでもdotfiles が含めコマンドの引数に、ワイルドカードが展開されるのは不便なので、一時的にオンにしたらもとに戻したい。

shopt -u dotglob # 設定をオフにする

現在の設定を確認する。

あれ?いま展開するんだっけ?しないんだっけ?設定を見るには。

takuya@$ shopt -p dotglob
shopt -u dotglob

これで設定ができる。

使い方の例

設定を見ると、設定がコマンドとして機能するので、これを利用して、次のように活用できる。

dotglob_last_state=$(shopt -p dotglob)
for i in * ; do
  echo $i;
done
$(dotglob_last_state)

トグルできるコマンドを作ってもいいけど、そこまでするほどでもないと思う。

その他の解決方法

find や ls と組み合わせで出来なくもないけど、すこし煩雑な気がする。半角スペースが混じったファイル名やフォルダ名のときにうまくいかない。(IFSを指定すればうまくいくけど)

find -maxdepth 1 -exec  echo {}\;
for i in $( ls -a ) ; do echo $i; done

shopt で設定できるその他のglob 関連

ワイルドカード関連の自動展開や補完の関連がshopt で設定できるので合わせて覚えておきたい。

  • dotglob
  • extglob
  • globstar
  • nocaseglob
  • nullglob
  • direxpand

関連資料

http://takuya-1st.hatenablog.jp/entry/2016/04/05/025553

参考資料

https://www.gnu.org/software/bash/manual/html_node/The-Shopt-Builtin.html

ssh の秘密鍵から公開鍵を復元(再生成)する方法

ssh の公開鍵を再度作成する。

うっかり、公開鍵を消しちゃったときに、秘密鍵から公開鍵を作成する。

ssh-keygen -y  -f ~/.ssh/id_rsa  

普通はこういうことは起きないけど、今回は、.ssh のフォルダをちょっと触っててやらかした。

ファイルに上書きするときはこれ。

ssh-keygen -y  -f ~/.ssh/id_rsa  > id_rsa.pub

すでに登録済みの公開鍵から復元する。

公開鍵なので、どこかにコピーして公開しているだろうし、そこから取り出してもいいですね。

例えば、github に登録してあったら、 curl https://github.com/$USERNAME.keys で取り出せます。

また、別のサーバーにssh でログインできるのであれば、 cat ~/.ssh/authorized_keys で取り出せます。

公開鍵は「公開」してください。

公開鍵は、公開して意味のあるものです。

秘密鍵から公開鍵を導出したら、公開してください。秘匿しても意味がありません。

公開鍵を、パスワードzip送信する??

世の中すごいな、俺が考えた最強セキュリティがワークフローとして成立するんだね。

公開鍵は、公開しているものであるし、ソレが本人の公開鍵であるかどうかは認証局(CA)の署名を受けるものであるし。

公開しても大丈夫・紛失しても大丈夫。

秘密鍵を現順に管理していれば、再生成(再計算)できます。

カジュアルに紛失しても問題ないのです。

2021-07-04

記述を見直し。

pipenvを使う。pyenv+venvもいいけど、いまどきな'pipenv' で環境構築に使って使い勝手を調べてみた.

目次

python のパッケージ周りの進化(?)

python はパッケージ管理がガラッと変わることが多い。

  • setup.py
  • pip
  • pyenv
  • virtualenv
  • direnv
  • requirements.txt
  • pipenv ← now

そういえば、古くは - egg / easy_install とかありましたね。 機能追加じゃなくて、以前の機能をつかって新しいコマンドとして作られるんだけど、個人的には、同じコマンドが進化してくれればいいのにと思ったりする。

pipenv を一言でいうと

今どきな「パッケージ管理」に対応してるのが pipevn コマンドらしい。

これを使うと。

他言語のパッケージ管理に使い勝手が近くなると思われる。

  • php composer
  • ruby bundler
  • npm / yarn

この的な、プロジェクト単位のパッケージ管理と同等になるんですね。アップデートとかも含めて"pipenv"で事足りる様になるようだ。だとしたらすごく便利だよね。

pipenv を使うことで venv や pyenv を併せたようなことが できるようになって便利だよね。

すぐわかるpipenvの使い方。

pip install pipenv 
mkdir myProjcet
cd myProjcet
pipenv install 

pipenv についてはこれ読むとわかる。

この記事が詳しい。

Pythonのパッケージ周りのベストプラクティスを理解する - エムスリーテックブログ

requirements.txt

次に、インストールしたパッケージ群を、正確にもう一度インストールし直す方法が問題になりました。

venv (virtualenv)

さて、パッケージをインストールできるようになりましたが、 別のプロジェクトで使うパッケージが混ざってしまう問題が起きました。

pyenv

次に、複数のPython自体をビルドするのが大変という問題が起きました。

pipenvその2

次に開発環境を作る手順が面倒という問題が起きました。

というわけで、requirements.txt の問題点とpyenvも問題点を片付けたのがpipenv という位置づけのようですね。

pipenvを使ってみる。

まず、pipenv コマンドをインストールします。

コマンドは、グローバル環境で使うので

pyenv な globalなpipでインストール

pip install pipenv

プロジェクト単位のpython環境のフォルダを作るためのコマンドを自分のシステム環境に導入するので、global 環境に用意します。

pipenv 環境を作る

最初にプロジェクトのディレクトリを作る

mkdir sample 
cd sample

pipenv インストール環境の初期化

プロジェクトのディレクトリ内でpipenv install をすると環境が作られる。

pipenv install 

もし、python のバージョンを指定したいときは、次のようにする。

pipenv install --python=3.7

Pipfile と .lock が作られる。

takuya@sample$ ll
total 12K
-rw-r--r-- 1 takuya staff 138 2019-04-14 18:35 Pipfile
-rw-r--r-- 1 takuya staff 453 2019-04-14 18:35 Pipfile.lock

venv 環境に入る

pipenv で準備は終わってるので

よくある、venv 環境を使うパターン

$ pipenv shell 
(sample) $ 
(sample) $  deactivate
$

直接 activate を source することでも可能。

source  $(pipenv --venv)/bin/activate

venv 環境を使う2

pipenv shell でもいいんだけど、pyenv 的な使い方もできる

takuya@sample $ pipenv run python -V
Python 3.7.2

プロジェクトでpipを使いたいときは

takuya@dojin$ pipenv run pip -V
pip 19.0.3 from /Users/takuya/Desktop/sample/.venv/lib/python3.7/site-packages/pip (python 3.7)

いい感じにvenv を確保してくれてるのがわかる。

パッケージのインストールとアンインストール

pipenv install requests
pipenv uninstall requests

ただ、これをやっても、プロジェクトのフォルダにファイルがコピーされて生成されるわけではなかった。

どこに環境がインストされたか詳細を見るには

pipenv install requests --verbose

ここを見る限り、/Users/takuya/.local/share/virtualenvs/sample-8HuA3Lk0/bin/pip にvenv が作られていた。

具体的にvenv がどこに作られているのか知りたいときは、次のようにコマンドを叩けばいいことが解る

pipenv --venv

とすれば、venv の場所が表示されます。

開発用パッケージのインストール

pipenv install --dev ipython

--dev をつけるのはよく見るパターンですね。

npm run 的なアレ

pipenvでもnpm run 的なことが出来る。

Pipfile に scripts を書けば、npm run 的なアレができる。

[scripts]
echo = 'echo Hello world'

実行

takuya@sample $ pipenv run echo
Hello world

手作業でpipenv は編集しなくていい。pipenv install

ついつい、 pip install を叩きそうになるのを我慢。

pipenv install speedtest-cli

これでPipfile が更新されます。

github でバージョン管理するときに、Pipfileを対象にして環境をデプロイ先で再現するときに大事。

プロジェクト内にvenv 環境を作りたいんだけど

npm の node_module や composer vendor/ のようにしたいときは、

export PIPENV_VENV_IN_PROJECT=1
pipenv 

面倒なときは次のようにalias か?

alias pipenv='PIPENV_VENV_IN_PROJECT=1 pipenv'

alias で十分ですね。

$ alias pipenv='PIPENV_VENV_IN_PROJECT=1 pipenv'
$ pipenv --venv

/Users/takuya/Desktop/sample/.venv

PIPENV_VENV_IN_PROJECTの注意(2019-08-21)追加

/home/takuya/Pipfile のようにすでに上位ディレクトリにPIpfile があると、そっちが優先されてディレクトリ単位に作られないので注意が必要

ll /home/takuya/Pipfile
cd /home/takuya/myproject/
pipenv install 

Pipfile が上位ディレクトリに存在すると、venv 環境下になるので、うっかり $HOME などにPipfile を作らないように注意すること。

うっかり pipenv しちゃったときは、即座に消しておかないと混乱します。

pipenv のシェル補完がしたい

bash completion が欲しい人は

これを書くだけ。

eval "$(pipenv --completion)"

ただし、実行時間に注意(i5 Macbook 2018 で 500ms ) 。 bashrc に書くとシェル起動がすこし遅くなるので注意。

git clone した python プロジェクトをpipenv する。

git clone した プロジェクトがpython プロジェクトで pip インストールが必要な場合。

pipenv を使うと次のようになります。

git clone $URL
cd $procject
export PIPENV_VENV_IN_PROJECT=1
pipenv install 
pipenv run pip -r requirements.txt

export PIPENV_VENV_IN_PROJECT=1 はお好みで。

追記

PIL をなんとなく、pipenvでインストールしてエラ−になった。 よく考えたら、PILはpypthon3 はもう無いのに。 pipenv.exceptions.ResolutionFailure が出まくる。

pipenv.exceptions.ResolutionFailure
ERROR: ERROR: Could not find a version that matches pil

このあと、pipenv install がすべてエラーになってしまった。macos など環境依存でライブラリが足りずにインストールに失敗したあと、lock ファイルが汚くなることがあるようです。

こういうときは、とりあえずlock ファイル消して、Pipfile を書き直したらきれいになるようです。

インストール失敗しても失敗したpipfile のママ残りました。インストール成功してから pipfile を更新してほしいですよね。

2019-10-29

Googleのpipenv で検索にヒットしないので、ほんとうにGoogle検索どうなってんだろう

2019/10/30更新

pipenv で google の検索インデックスに入らないので、記事を一部書き直した。

2019-12-17

PIPENV_VENV_IN_PROJECT でまた混乱したので、追記・改変

参考資料

必読 → https://pipenv-ja.readthedocs.io/ja/translate-ja/advanced.html#configuration-with-environment-variables

公式→ https://pipenv.readthedocs.io/en/latest/

日本語→ https://pipenv-ja.readthedocs.io/ja/translate-ja/install.html

Pipenvを使ったPython開発まとめ - Qiita

https://github.com/pypa/pipenv/issues/259

秘密の質問の回答ジェネレータを、pythonでぱぱっと

TL;DR

ひらがな10文字の秘密の質問の回答を作る。

python -c 'import random; print("".join([ chr(0x3042+random.randint(0,82) ) for i in range(1,10)]))';

秘密の質問って効果あるの?

秘密の質問はないよりはあったほうがマシとかいうレベルで無くても問題ないと思う。

秘密の質問は「ひらがなのみ」とかアホらしいですね。

憶測可能で非ランダムなら「ひみつの質問」ってセキュリティ的には全く意味ないですよね。

ひらがな1文字でOKです。

f:id:takuya_1st:20190414154233p:plain

そりゃそうだ、「あなたの出身地は」という質問に「三重県 津市」のような1文字地名を1文字が許可されなときは、どう答えるのだ。

秘密の質問とかいう謎仕様に頭を悩ませる。

秘密の質問って効果あるの?→無いです。

全角ひらがなだと83文字です。

秘密の質問は8文字もありません。1文字でも5文字でも通ってしまう。 ASCIIで記号+小文字+大文字+数字=約80字が8文字以上組み合わされた通常パスワードより強度が低い。

わざわざ強度の低い文字を、しかも「現実に存在する単語」で入れさせるなんてアホらしいですね。 こういう似非セキュリティは無くなってしかるべきです。

辞書の単語をパスワードに利用するなと言うのは鉄則ですよね。

出身地の小学校の名前が十分な強度を得られるほどランダム性があるわけでもない。

何から何を守るのかも不明確

セキュリティの基本として、「何を誰から守るのか」という視点を失ってほしくないですね。

秘密の質問は誰から何を守るのでしょうか。今回の例は「イオンカード」ですが、明細の「閲覧」権限を保護はそこまで重要な情報なんでしょうか。

そもそも正直に答える必要など無い。

そもそも正直に答える必要など無い。ランダムなひらがな文字列で構わない。

というわけで、自動的に生成してしまいましょう。

f:id:takuya_1st:20190414154658p:plain

python -c 'import random; print("".join([ chr(0x3042+random.randint(0,82) ) for i in range(1,10)]))'

そもそも、ひらがなは「あーん」なのか?

ひらがなをprint してみて思うのだけど、「あーん」がひらがなでいいのだろうか。

>>> [ chr(0x3042+i) for i in range(0,190) ]
['あ', 'ぃ', 'い', 'ぅ', 'う', 'ぇ', 'え', 'ぉ', 'お', 'か', 'が', 'き', 'ぎ', 'く', 'ぐ', 'け', 'げ', 'こ', 'ご', 'さ', 'ざ', 'し', 'じ', 'す', 'ず', 'せ', 'ぜ', 'そ',
 'ぞ', 'た', 'だ', 'ち', 'ぢ', 'っ', 'つ', 'づ', 'て', 'で', 'と', 'ど', 'な', 'に', 'ぬ', 'ね', 'の', 'は', 'ば', 'ぱ', 'ひ', 'び', 'ぴ', 'ふ', 'ぶ', 'ぷ', 'へ', 'べ', 
'ぺ', 'ほ', 'ぼ', 'ぽ', 'ま', 'み', 'む', 'め', 'も', 'ゃ', 'や', 'ゅ', 'ゆ', 'ょ', 'よ', 'ら', 'り', 'る', 'れ', 'ろ', 'ゎ', 'わ', 'ゐ', 'ゑ', 'を', 'ん', 'ゔ', 'ゕ',
 'ゖ', '\u3097', '\u3098', '゙', '゚', '゛', '゜', 'ゝ', 'ゞ', 'ゟ', '゠', 'ァ', 'ア', 'ィ', 'イ', 'ゥ', 'ウ', 'ェ', 'エ', 'ォ', 'オ', 'カ', 'ガ', 'キ', 'ギ', 'ク', 'グ',
 'ケ', 'ゲ', 'コ', 'ゴ', 'サ', 'ザ', 'シ', 'ジ', 'ス', 'ズ', 'セ', 'ゼ', 'ソ', 'ゾ', 'タ', 'ダ', 'チ', 'ヂ', 'ッ', 'ツ', 'ヅ', 'テ', 'デ', 'ト', 'ド', 'ナ', 'ニ', 'ヌ', 
'ネ', 'ノ', 'ハ', 'バ', 'パ', 'ヒ', 'ビ', 'ピ', 'フ', 'ブ', 'プ', 'ヘ', 'ベ', 'ペ', 'ホ', 'ボ', 'ポ', 'マ', 'ミ', 'ム', 'メ', 'モ', 'ャ', 'ヤ', 'ュ', 'ユ', 'ョ', 'ヨ', 
'ラ', 'リ', 'ル', 'レ', 'ロ', 'ヮ', 'ワ', 'ヰ', 'ヱ', 'ヲ', 'ン', 'ヴ', 'ヵ', 'ヶ', 'ヷ', 'ヸ', 'ヹ', 'ヺ', '・', 'ー', 'ヽ', 'ヾ', 'ヿ']

あーんだと次の3文字が欠損する

 'ゔ', 'ゕ', 'ゖ',

他にも、ダッシューは?波線〜は?

長音、ダッシュとハイフンの違いはどうするんだろうか。

>>> hex(ord('ー'))
'0x30fc'
>>> hex(ord('―'))
'0x2015'
>>> hex(ord('−'))
'0x2212'

こんなあやふやでフワっとした「秘密の質問」ってもう無くていも問題ないと思うんですよね。

さて、イオンカードの場合を見てみよう。

ああ、やっぱり「あーん」ですね。

f:id:takuya_1st:20190414153607p:plain

元になってる日本語判別はなんだろう jquery の野良プラグインですね。お疲れ様です。

f:id:takuya_1st:20190414153803p:plain

正規表現エンジンで  /あ-んー\s/ ですか。それならブラウザのinput:invalidate のrequired pattern= の組み合わせで十分なんじゃないですかね。。。

判定条件はこれだった。

"hiragana": {
                    "regex": /^[ぁ-んー\s]+$/,
                    "alertText": "* ひらがなのみで入力してください。"
                },

うーん・・・これでいいのか?

しかも、この判定だと、半角スペースを「ひらがな」として通してしまいませんか?

こうなってくると、他の判定正規表現、たとえばemail アドレスの判定も疑わしいですね。

結論:自動生成使用。

あーん だと抜ける文字がある。ハイフン長音の違いでユーザーに不親切になる。このjQuery野良プラグインは半角スペースを通してしまう。

秘密の質問はやっぱりいらない。

自動生成で十分だ。

追記:秘密の質問のパターン甘い

こんな、適当な秘密の質問でも通ってしまう

f:id:takuya_1st:20190414153658p:plain

ほんと、なんのためにあるんですかね。

追記:しかも平文で保存される。

最大20文字とか制限があるんでオカシイなとおもったら、やっぱり平文保存だった。

最大文字数が制限されいるとき、殆どの場合で「データベースのカラム長」だと思われる。つまり保存は平文である。

変更画面でもとの秘密の質問が表示される。うーんここは平文で保存する必要があるのかな?ハッシュ化してないんだね。

f:id:takuya_1st:20190414160508p:plain