mind.

学んだことの記録

Python3でファイルの更新日時でソートする

記事を書くほどの題目でもないのですが、備忘録として。

正しいコード

import os
file_list = os.listdir()
sorted(file_list, key=lambda f: os.stat(f).st_mtime)

ファイルの更新日時でソート済みのリストオブジェクトが取得できます。

自分で調べたときは解決できず、先輩に教えてもらったコードで上手く行ったので……。
僕はなんでこれができなかったんだろう……。

cronで実行するプログラムは絶対パスを書くこと

なぜ?

これを知らなかったので仕事で丸一日悩んでました……。

試してみる

下記のようなコードを書いてみました。

import datetime
with open("file.txt", mode='a') as f:
    f.write("{}\n".format(datetime.datetime.now()))

ファイルに現在時刻を追記する、大したこと無いプログラムです。
ポイントは、open()の第一引数の"file.txt"がそのままになっていることです。
これを実行すると、"file.txt"はcronが実行されたときのユーザーのカレントディレクトリに作成されます。
つまり、プログラム作成時に意図していない場所にファイルが作成されることになるので危険です。

絶対パスに修正します。

import datetime
with open("/home/vagrant/test_dir/file.txt", mode='a') as f:
    f.write("{}\n".format(datetime.datetime.now()))

これで安心。

余談

cronで実行させるファイルには忘れずに実行権限を与えよう。

GitLabで管理しているリポジトリの過去のコミットを削除する方法

なぜやるのか

サイズの大きすぎるファイルを追加してしまい、cloneに時間が掛かるようになったのでrevertして事なきを得ようと思ったのですが、revertして削除してもcloneには時間がかかるまま~ということがありました。
(ロールバック時にファイルを復活できるように削除されたファイルもデータは保持しているようです)

目標

GitLabで管理しているリポジトリのmasterブランチに誤って追加したファイルをコミットログも含めて削除する。

注意

masterブランチの保護を外したり、コミットログを消すことになるので、状況次第では行わない方がよい場合があります。

準備

検証用に、ファイルを3つリモートリポジトリに追加します。

  • ファイル1.txt
  • ファイル2.txt
  • 間違って入れたファイル.txt ←これを削除する

手順

1.masterブランチの保護を外す。

Projectのトップページを表示し、画面左端「Setting」→「Repository」を押下
「Protected Branches」を開いてmasterブランチの「Unprotect」ボタンを押下、続けて表示されるダイアログの「OK」ボタンを押下
※後で保護を戻すので設定内容をメモしておくことをおすすめします。

2.コミットログを確認する

$ git log
commit 99107622d285a59fb09bde50999ff8673139840c (HEAD -> master, origin/master)
Author: vagrant <vagrant@vagrant.vm>
Date:   Mon Mar 9 10:43:07 2020 +0000

    間違って入れたファイル追加

commit 316cdb9fed1b3c47fd905ae01d9628ba106dfc39
Author: vagrant <vagrant@vagrant.vm>
Date:   Mon Mar 9 10:38:59 2020 +0000

    ファイル2追加

commit f1698a296b1eb43785a1a7a61e1e8891eedf33b0
Author: vagrant <vagrant@vagrant.vm>
Date:   Mon Mar 9 10:34:58 2020 +0000

    ファイル1追加

3.ローカルリポジトリでコミットを削除する

git reset --hard [残したい最新のコミットのハッシュ値]
[残したい最新のコミットのハッシュ値]で指定したコミットが最新になるように、それより後のコミットが消えます

$ git reset --hard 316cdb9fed1b3c47fd905ae01d9628ba106dfc39
HEAD is now at 316cdb9 ファイル2追加

念の為コミットが消えているか確認

$ git log
commit 316cdb9fed1b3c47fd905ae01d9628ba106dfc39 (HEAD -> master)
Author: vagrant <vagrant@vagrant.vm>
Date:   Mon Mar 9 10:38:59 2020 +0000

    ファイル2追加

commit f1698a296b1eb43785a1a7a61e1e8891eedf33b0
Author: vagrant <vagrant@vagrant.vm>
Date:   Mon Mar 9 10:34:58 2020 +0000

    ファイル1追加

ローカルリポジトリ上は消えたようです。

4.リモートリポジトリにpushする

git push origin master -f
コミットログが遅れた状態(git視点では古いローカルリポジトリからのpush)なので-fオプションで強制的にpushします。

5.masterブランチを保護する

手順1の画面まで進み、「Protect a branch」欄にある項目を元通りに設定して「Protect」ボタンを押下する

完了です。

CentOS7のPCに2TBを超えるHDDを増設する

マスクよりアルコール消毒液が欲しい。

ポイント

2TBを超えるHDDはfdiskコマンドでパーティションを作成すると2TBまでしか認識されない。(GPT パーティションは開発途中のため自己責任でという旨の警告メッセージが表示される)

fdisk /dev/sda
WARNING: fdisk GPT support is currently new, and therefore in an experimental phase. Use at your own discretion.
Welcome to fdisk (util-linux 2.23.2).

参考

手順

CnetOSの操作を書きます。
HDDはあらかじめ挿しておいてください。

1. 追加したHDDのパーティションテーブルの種類を調べる

lsblk
parted /dev/sdb

(parted) p
(parted) quit

開封直後のHDDなら「unknown」となっているはず

2. 追加したHDDのパーティションテーブルをGPTに変換

gdisk /dev/sdb
GPT fdisk (gdisk) version 0.8.6

Partition table scan:
  MBR: not present
  BSD: not present
  APM: not present
  GPT: not present

Creating new GPT entries.

Command (? for help): w ←「w」を入力

3. パーティションテーブルをxfsでフォーマット

mkfs.xfs /dev/sdb1

CentOS7ではxfsがデフォルトのようなので。
もし下記のようなエラーが表示された場合は、パーティション作成済みのディスクということなので、-fオプションを付与して強制的に実行する。

mkfs.xfs: /dev/sdb1 appears to contain an existing filesystem (ext4).
mkfs.xfs: Use the -f option to force overwrite.
 mkfs.xfs /dev/sdb1 -f

4. マウント

mount -t xfs /dev/sdb1 /mnt/hdd2

5. blkidコマンドでディスクのUUIDを調べる###

/etc/fstabに書き込むために必要

6. /etc/fstabに設定を書き込む###

vi /etc/fstab

これにより、マシンの再起動時に自動でマウントされるようになります。
変更を加えたfstabが正しく動作するかをチェック

mount -a

完了です。

GitLabで特定のGroupのすべてのProjectのpath名を取得するコマンド

劇場版SHIROBAKOを見に行きたい。

目標

GitLabで特定のGroupのすべてのProjectのpath名を取得すること

なぜやるのか

バックアップとしてgit cloneコマンドでリポジトリの実データを保持しておきたいからです。
リポジトリを都度cloneしてくるのは手間ですが、リポジトリ名の一覧を取得できればあとはシェルスクリプトなり何なりで自動的に連続してcloneを行うことができるので便利です。

参考

tyablog.net

qiita.com

前提

  • curlがインストールされていること
  • jq がインストールされていること
    動作確認に使用したOSはCentOS7.7ですがcurlが使えればおそらくどのディストリビューションでもできると思います。

手順

やることは大まかに下記の2つです。
1.アクセストークンを作成する
2.GitLab APIのコマンドを実行する

1.アクセストークンを作成する

今回はGitLab.comでの手順を書きますが、オンブレミス版でも同様です。
1-1.自分のアカウントの設定ページ(https://gitlab.com/profile)をブラウザで表示する。
1-2.画面左端の「Access Tokens」ボタンを押下
1-3.「Name」欄にアクセストークンの名前を入力し、「Expires at」欄に有効期限を入力する
1-4.「Scopes」欄に表示されている、これから作成するアクセストークンで利用できる権限を選択
今回はリポジトリ名の一覧を取得するだけなので「api」にチェックを付ける
1-5.「Create personal access token」ボタンを押下する
1-6.画面更新後、「Your New Personal Access Token」にアクセストークンの文字列が表示されるのでコピーしておく
なお、この画面から遷移するとアクセストークンの文字列は見れなくなるのでご注意

2.GitLab APIのコマンドを実行する

2-1.環境変数「 $ACCESS_TOKEN」に手順1で取得したアクセストークン文字列をセットします。
2-2.下記コマンドを実行します。

curl --header "Private-Token: $ACCESS_TOKEN" https://gitlab.com/api/v4/groups/[Group ID] | jq .projects[].path

v4はGitLab APIのバージョンです。以前はv3だったようですが、今v3で実行しようとするとv4を使用するように促すメッセージが表示され実行できません。
[Group ID]はGroupのトップページに表示される7桁の数字です。
Private-Tokenの値に直接アクセストークン文字列を書いてもできますが、今回は環境変数を参照するようにします。
チーム開発では権限を持たせたい人にアクセストークン文字列を共有することが適切だと思います。
| jq .projects[].pathは、コマンド前半部分で取得したjsonデータを整形して表示するためのコマンドです。
cloneのコマンドで使用することが目的なのでpathメンバの値を指定しました。
Project作成時に付けた名前を取得したい場合はpathnameに変えて実行してください。

完了

実行例

下記画像の様に動作確認用のProjectを作成しました。
f:id:cm_kenji:20200229193400p:plain
上記コマンドを実行した結果、Projectのpath名の一覧が取得できました。
f:id:cm_kenji:20200229195039p:plain

今回はここまで。

GitLabCIをHello Worldで試す【ビルド編】

左右独立型ワイヤレスイヤホンを使い始めた。かなり良い。

自動ビルドのメリット

トピックブランチをリモートへpushしたときにビルド確認ができれば、誤った変更をデプロイする前に修正することができます。

やること

GitLabのProjectにC言語でファイルをアップロードして、push時にビルド確認が自動で行われるようにする。

用語

パイプライン: CIを実行する環境のこと。GitLabでは一回のコミットに対して一つのパイプラインが動作する。

手順

参考URL

gitlab.com qiita.com

前提

  • GitLab.comのアカウント作成済み

必要なファイルの追加

1.GitLab.comで適当なProjectを作成する

2.Projectにソースファイル「hello.c」と「.gitlab-ci.yml」を追加してpushする

hello.c

    #include <stdio.h>

    int main(void)
    {
      puts("Hello World!");
      return 0;
    }

.gitlab-ci.yml

    image: gcc:7.4

    stages:
      - build

    before_script:

    build_job1:
      stage: build
      script:
        - gcc hello.c

ビルドするだけならこれでOK。

3.Projectのページの画面左端メニューから「CI/CD」を押下してパイプラインの一覧を表示する 

4.「Status」が「passed」と表示されていたら正常にビルドができている。

完了

ビルドエラー時の動作確認

ビルドエラーを認識できるか試してみる。
1. 前述の手順で作成した「hello.c」がビルド時にエラーを起こすように適当に変更してpushする。

hello.c

#include <stdio.h>

int main(void)
{
  puts("Hello World!");
  hogehoge
  return 0;
}
  1. Projectのページの画面左端メニューから「CI/CD」を押下してパイプラインの一覧を表示する
  2. 1で行ったコミットに対するパイプラインの「Status」が「failed」になることを確認して、「Pipeline」列のリンクを押下して詳細画面を表示する
  3. ✕印が付いている「build_job1」ボタンを押下してビルドエラー時のログを確認する
    エラーログを読むと、ソースファイルに追加した不正な一行が原因でビルドエラーが起きていることが分かる。 f:id:cm_kenji:20200222151416p:plain 完了

以下雑記

  • Makefileを駆使すればより複雑なビルドに対応できそう
  • テストとデプロイも使えたら仕事がかなり楽になりそう

『チーズはどこへ消えた?』を読んで

連休終了間際のメンタルを改善していく

どんな本か

2匹のネズミと2人の小人の物語を通して変化を恐れず行動することの大切さを説いた本です。
96ページという比較的薄い本ですが、内容は濃い良い本でした。

変化に適応する

この本で登場する小人は、チーズが無くなったことを悲観し、他のチーズを探そうとせずチーズがあった場所からすぐに動こうとしません。
一方、ネズミはチーズが無くなったことをすぐに受け入れ、他のチーズを探し求めて歩き始めます。
この本を読んでいると後者のネズミたちが正しく行動できていると感じますが、自分の人生を振り返ると必ずしもネズミたちのようではなかったと思います。
直近では、私が転職活動をしているとき、現職より成長できそうな会社から内定を頂いても、提示された給与が今より低かったり多忙になることを予想し怯え、お断りしたことがありました。
転職活動を始めたときは変化を恐れず進めていたつもりでも、いざ選択を迫られたときに小人たちのように現状維持を選んでしまいました。
その時の判断を後悔しているということではありませんが、この本を読んで、自覚している以上に自身が臆病になっているということに気づきました。

これからどうするか

転職活動も含め今後はできる限り変化することを選ぼうと思います。
そして変化することに楽しみを見いだせるように新しいことに挑戦します。

チーズはどこへ消えた?
https://www.amazon.co.jp/dp/459403019X/ref=cm_sw_r_tw_dp_U_x_S6BeEbGRWFQWV