Shiopon Labo

しおぽん(@shiopon01)の個人ブログです

E: パッケージ ○○ を再インストールする必要がありますが、そのためのアーカイブを見つけることができませんでした。

E: パッケージ virtualbox-6.0 を再インストールする必要がありますが、そのためのアーカイブを見つけることができませんでした。

こいつに時間食われたのでシェア。

やりたいこと

こいつを消したい。

$ sudo dpkg -l | grep virtualbox-6.0
iFR virtualbox-6.0        6.0.0-127566~Ubuntu~bionic        amd64    Oracle VM VirtualBox

minikube start したらVirtualBoxでエラーが出たので、 dpkg -i virtualbox〜〜 とかやってたらますますおかしくなったパターン)

いけたやつ

もし debconf: DbDriver "config": /var/cache/debconf/config.dat is locked by another process: Resource temporarily unavailable のエラーが出たらとりあえず rm /var/cache/debconf/*.dat したらなんとかなる。

自分の場合はこれでいけた。

$ sudo rm /var/cache/debconf/*.dat 

$ sudo dpkg -P --force-remove-reinstreq virtualbox-6.0
dpkg: 警告: --force が有効なので、問題を無視します:
dpkg: 警告: パッケージが非常に矛盾した状態に陥りました。
削除を行う前にこのパッケージを再インストールすべきです
(データベースを読み込んでいます ... 現在 223431 個のファイルとディレクトリがインストールされています。)
virtualbox-6.0 (6.0.0-127566~Ubuntu~bionic) を削除しています ...
virtualbox-6.0 (6.0.0-127566~Ubuntu~bionic) の設定ファイルを削除しています ...
dpkg: 警告: virtualbox-6.0 の削除中、ディレクトリ '/usr/lib/virtualbox/sdk/bindings/xpcom/python/xpcom/server' が空でないため削除できませんでした
dpkg: 警告: virtualbox-6.0 の削除中、ディレクトリ '/usr/lib/virtualbox/sdk/bindings/xpcom/python/xpcom/client' が空でないため削除できませんでした
shared-mime-info (1.9-2) のトリガを処理しています ...
hicolor-icon-theme (0.17-2) のトリガを処理しています ...
desktop-file-utils (0.23-1ubuntu3.18.04.2) のトリガを処理しています ...
mime-support (3.60ubuntu1) のトリガを処理しています ...

一応、こうしてVirtualBoxをインストールできたのであった。

$ sudo dpkg -i virtualbox-6.0_6.0.0-127566_Ubuntu_bionic_amd64.deb

Minikubeも動いた。

$ minikube start
Starting local Kubernetes v1.10.0 cluster...
Starting VM...
Getting VM IP address...
Moving files into cluster...
Setting up certs...
Connecting to cluster...
Setting up kubeconfig...
Starting cluster components...
Kubectl is now configured to use the cluster.
Loading cached images from config file.

いけなかったやつ

$ sudo dpkg -r virtualbox-6.0
dpkg: パッケージ virtualbox-6.0 の処理中にエラーが発生しました (--remove):
 パッケージが非常に矛盾した状態に陥りました。
削除を行う前にこのパッケージを再インストールすべきです
処理中にエラーが発生しました:
 virtualbox-6.0
$ sudo dpkg -p virtualbox-6.0
dpkg-query: パッケージ 'virtualbox-6.0' はまだ利用可能でありません
アーカイブファイルを調べるためには dpkg --info (= dpkg-$ sudo dpkg -p virtualbox-6.0
dpkg-query: パッケージ 'virtualbox-6.0' はまだ利用可能でありません
アーカイブファイルを調べるためには dpkg --info (= dpkg-deb --info) を、
その内容一覧を表示するには dpkg --contents (= dpkg-deb --contents) を使います。deb --info) を、
その内容一覧を表示するには dpkg --contents (= dpkg-deb --contents) を使います。
$ sudo apt install --reinstall dpkg
パッケージリストを読み込んでいます... 完了
依存関係ツリーを作成しています                
状態情報を読み取っています... 完了
E: パッケージ virtualbox-6.0 を再インストールする必要がありますが、そのためのアーカイブを見つけることができませんでした。
$ sudo apt install -f
パッケージリストを読み込んでいます... 完了
依存関係ツリーを作成しています                
状態情報を読み取っています... 完了
E: パッケージ virtualbox-6.0 を再インストールする必要がありますが、そのためのアーカイブを見つけることができませんでした。

炎上プロダクトと、従事したエンジニアの心情

今年は初めて受託開発の炎上を経験したので年が明ける前にその時の心情を書き記しておこうと思う。あくまで従事したエンジニアの心情であるので、案件については言述していない。

本題

自分の経験した炎上はスケジュールが圧倒的に短くて発生したタイプの炎上だった。この記事ではスケジュールが短すぎた場合、エンジニアの心情はどういったものか、プロダクトはどうなるかを記述する。

スケジュール

とりあえず、納期や工数をマネージャー層が全て決定した状態でエンジニアに丸投げするのはやめよう。

ふつう案件にアサインされたエンジニアは要求仕様書から機能の洗い出しを行うが、この時点で 納期が短すぎるのでは? となった場合はその時点からマネージャーに対して 強い不信感 を抱き始める。(逆に、期間が長いと感じたらマネージャーへの好感度は上がる!)

納期を変えることはできないのでしぶしぶ開発は始めるが、実際に時間が足りなくなった時は クソみたいな見積もりをしたマネージャーの尻拭いをさせられている という考えが絶対に付きまとうので、精神上も良くない。そしてこの時のモチベーションは世界最低ランクだ。

この現象の対処法としては、やはりアサインが想定されるエンジニアも見積もりに参加させることが一番良いと思う。作業者自身もマネージャーと一緒に見積もりを行うことで、作業者に納期への納得感を与えることができるし、なにより技術を良く分かっていないマネージャーの適当なクソ見積もりを防ぐことができる。

この点からも、やはり現役エンジニア(実際の作業者推奨)を見積もりに参加させるのは必須と感じた。

プロダクトの品質

開発(プログラミング)に費やす時間の多くは アルゴリズムを考える 時間でもある。自分は特にその傾向が強く、一旦の実装をとりあえず作ってから綺麗なコードに書きなおすことが多い。

これは実際に案件のスケジュールが完全に遅れた状態になって分かったのだが、スケジュールが切羽詰っていると自分は製品を作るためのプログラミングではなく 帰るためのプログラミング を行うようになるらしい。

帰るためのプログラミングが何かというと、先述した アルゴリズムを考える 時間を大幅に省き、一旦の実装( HACK 的実装)のままどんどん機能追加を行うことだ。なんたって時間の余裕がないので、 綺麗なコードへの書き直し = 追加の残業 となる状態で自分はコードのリファクタリングまで行えなかった。なぜなら、絶対に残業はしたくなかったからだ。(結局時間が足りず、機能追加で残業や徹夜までしたが)

これがプロダクトの品質に悪いのは明白だが、エンジニアの精神状態にも大きなダメージを与える。コーディングする度に自分やチームメンバーのソースコードを見てリファクタリングしたい気持ちを抑え、「俺はこんな実装をしたいわけじゃないのに…」と思いながら新しい機能を追加していたあの頃は、きっとエンジニアとしては死んでいたのかもしれない。

プロダクトの品質はそのまま改修のしやすさにも繋がる。一時的な実装が多いということは、次に機能追加や改修の案件を担当した人に負債がのしかかるということだ。時間が無いなら仕方ないが、出来るだけ綺麗なコードを心がけたい…。

テスト

リファクタリングを行う時間が無いと言うことは、単体テスト結合テストのコードを書く時間も無いということだ。いや今回の場合、初めの頃はなんとかテストを書くスタイルだったが、度重なる機能追加と機能変更などの作業増加によって書く時間が明らかに無くなったと言ったほうが正しい。

今回で言うとテストチームがバグ出しを頑張ってくれたので、プロダクトとして最低限の品質は保障できた。中には単体テストをちゃんとやっていれば出ないようなバグも数あり、テストの大切さを改めて実感。(何よりも余裕を持ったスケジュールのほうが大事だけどな)

自分への影響

自分の精神的なストレス耐性は低いらしく、残業と徹夜はかなりしんどい思い出だった。

生きる活力がかなり削がれていたし、具体的には唇がよく切れるようになった。メロンパンを食べた時は、かじった部分が赤くなっていたくらいだ。

おわりに

この遅れが見積もりの失敗であれマネジメントの失敗であれ、どちらにせよ 遅れ (極端に言えば炎上)はプロダクトの寿命を縮めることに繋がることに間違いはない。

それは純粋なコードの品質の低さ、テストの未実施などもあるが、何より疲弊したモチベーションの低いエンジニアから生み出されたプロダクトが良いものであるはずがないからだ。マネージャーにはエンジニアのモチベーションを第一に考え、慎重に見積もりやマネジメントを行ってもらいたい。

そしてやはり、残業は悪い文明である。

WindowsでCaps LockをCtrlに、JISキーボードをUSキーボードにする方法

Windowsをよく再インストールするけど、その度にCaps LockをCtrlにする方法を調べている気がする…。年末なのでまた再インストールしました。

(備忘録。そのうちちゃんと書く)

regedit

Caps -> Ctrl

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layout]

name value
Scancode Map 00,00,00,00,00,00,00,00,02,00,00,00,1d,00,3a,00,00,00,00,00

JISキーボード -> USキーボード

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\i8042prt\Parameters]

name value
LayerDriver kbd101.dll
OverrideKeyboardIdentifier PCAT_101KEY
OverrideKeyboardSubtype 0

参考

Windows/TIPS/レジストリを修正してCAPSLOCKの割り当て変更 - yanor.net/wiki

今更だけどghqを使ったリポジトリ管理を布教したい

ghq を使ってない人は人生の1割損してる。

本題

自分が ghq を使い出して数年経ったが、周りには案外、こういうリポジトリの管理ツールを使っていない人が多いらしい。絶対リポジトリの管理ツールはあったほうが良いので、ここで今更ながら宣伝しておく。 ghq 使います。

Goのインストール(準備編①)

まずはGoのインストールから。自分は goenv を使っている。(言語のバージョン管理は ○○env をよく使ってる)

goenvのインストールはこちらから。

goenvのインストールが完了したら、goをインストールする。インストールできるバージョンは goenv install --list で確認できて、このリストは ~/.goenvgit pull したら更新される。

$ goenv install --list
  (省略)
  1.11rc2
  1.11.1
  1.11.2
  1.11.3
  1.11.4

目的のバージョン(たぶん最新バージョンでいい)を見つけたらそのバージョンをインストール。インストールしたGoは goenv global で設定できて、 goenv versions で確認できる。

$ goenv install 1.11.4
  (インストールのログ)

$ goenv global 1.11.4
$ goenv versions
* 1.11.4 (set by /home/user/.goenv/version)

GOPATHの設定

実はGoには元々リポジトリ(外部ライブラリ)を管理する機能が備わっている。

リポジトリの管理は環境変数 GOPATH で設定されているディレクトリ(デフォルトは ~/go )で行われて、 go get で取得したリポジトリはここに入るようになる。ソースは $GOPATH/src に保存されて、 ghq みたいにバイナリが付属するやつは $GOPATH/bin にバイナリが入る。

ただの外部ライブラリ管理ディレクトリのように思えるが、Goのプログラムを開発するときはリポジトリGOPATH の下に置いておかないとimport周りが面倒くさくなるので(経験談)、実は普通のリポジトリもここに置いて一元管理しておいたほうが良い。そのため、 GOPATH にはこれから自分がリポジトリ管理に使いたいディレクトリを設定しておく。

自分の場合は ~/Work を設定している。リポジトリとかプログラムの管理は全部ここでやってて、 $ work~/Work に飛ぶエイリアスもある。(あと、 $GOPATH/bin をパスに追加しておこう)

# bashrc
export GOPATH=$HOME/Work
export PATH=$GOPATH/bin:$PATH

function work { cd ~/Work; }

ghq(とpeco)のインストール(準備編②)

pecoは go get でバイナリを取得できなくなったこともあり、Linuxだとちょっとだけ手間になった。ここではダウンロードしたソースをbuildする方法でpecoをゲットする。( releases/peco_linux_amd64 のところはOSによると思う)

$ go get github.com/peco/peco
$ cd $GOPATH/src/github.com/peco/peco

$ make build
$ cp releases/peco_linux_amd64/peco $GOPATH/bin

ghqのインストールは go get で行える。これだけで $GOPATH/bin にバイナリが入るので、それを利用できる。

$ go get github.com/motemen/ghq

ghqの設定

ghqgo get のようにリモートリポジトリをまとめる機能を持っていて、このためにGOPATHのようにghqの設定も記載しておかなければならない。設定するファイルは .gitconfig[ghq] 部分で、 一番下に次の例のように、 $GOPATH/src のパスを追記するだけで良い。

環境変数使えるのかな……。自分は ~/Work/src を設定していた)

[ghq]
  root = ~/Work/src

インストール作業は以上。

スーパージャンプ!(本編)

結論から言うとこの関数をbashrcに追記して使用する。関数名は何でもいいが、自分は入力のしやすさから repositoriesre としている。

# bashrc

function re {
  local path=$(ghq list --full-path | peco --query "$LBUFFER")
  if [ -n "$path" ]; then
    if [ -t 1 ]; then
      cd ${path}
      echo 'jump to' ${path}
    fi
  fi
}

仕組みとか

ghq が使えるようになって設定も完了しているなら、現在 ghqgo getリポジトリ管理に使うディレクトリは同じものになっているはずだ。( $GOPATH.gitconfig の設定)

試しに ghq list で確認してみると、さっきGoでクローンしたリポジトリが出力される。そして、今回欲しいのは --full-path を付けたfull pathのリスト。

$ ghq list --full-path
/home/shion/Work/src/github.com/motemen/ghq
/home/shion/Work/src/github.com/peco/peco

この結果をpecoに食わせて、pecoのQUERYと選択した行を出力してくれる機能を使ってリポジトリを絞り込んでいる。ここで取得したパスは変数 path に保存され、チェックなどが行わた後にそれを使って cd で移動する。 echo は消しても良い。

Gitリポジトリのクローン

Gitリポジトリのクローンは ghq get を使う。これは別に go get でもいいけど…。

ghq get https://github.com/githubtraining/hellogitworld

これで設定したディレクトリの下に、パスで区切られたいいかんじの階層でリポジトリが保存される。 ghq list を実行しても確認できるはず。

ローカルにしかないリポジトリの管理

ghq list で取得できるのは、指定ディレクトリ以下の .git を含むディレクトリのパスだ。( ghq get で取ってきたものだけ、というわけではない)

自分の場合、ローカルのリポジトリlocal というディレクトリに保存している。パスで言うと $GOPATH/src/local 。ここで例えば rails new とかで自分のプロジェクトを生成し、 git init.git を作成することで ghq list でパスを取得できるようになる。

$ ghq list
local/my-local-project

実行例

$ pwd
/home/user

$ re
jump to /home/user/Work/src/github.com/peco/peco

$ pwd
/home/user/Work/src/github.com/peco/peco

エンジニア、会社に給料を上げてもらうのは難しい 説

この記事が腑に落ちたので、思いついたことをちょっと書く。

blog.tinect.jp

本題

それなりの給与がもらえるかどうかは「人に投資すると売上が伸びる会社で働いているかどうか」

この一文が腑に落ちた。これは言い換えると、「人に投資することで売上が伸びる会社は、社員の給料を上げやすい」ということだろう。

エンジニアは職業柄、投資をされたところで会社の売上を直接伸ばすの難しい。そして何より、投資の結果が見えにくい。(知識労働者あるあるなのでは)

このような原因もあり、多くの企業でのエンジニアへの投資は最小限とされている。つまり、給料が突然上がることがほとんどない。

ほとんどの場合、エンジニアへの投資は先行投資だ。スタートアップ企業では、良いエンジニアを集めてモチベーションを高めるために先行投資を行う光景をよく見る。ただ、これはスタートアップだから先行投資が行われるというわけではなく、事業が少なく、投資の結果が見えやすいスタートアップが投資を行いやすい環境にあるだけなのだろうが…。(お金がないスタートアップの話もよく聞くので、一概にこうとは言えない)

逆に、体力はあれどモチベーションのような不確定なものに投資を行わない大企業などは先行投資ではなく成果報酬となりがちだ。社員が多い場合はなおさらその傾向がある。こういう企業では残念ながら、経営者は今エンジニアに払っている給料が十分なものだと考えているので、エンジニアの給料を上げるなんてことはほとんどしない。開発環境(PCなど)への投資のような、比較的安価な先行投資すら知ったことではないという経営者も多いのも事実。

PCの性能は生産性に直接繋がるが、残念ながらモチベーションへの投資がそのまま利益に繋がるわけではない。そのため、こういった先行投資を行わない企業で働くエンジニアが自分の給料を上げてもらうのは、大変な活動となりがちだ。

そのためにはエンジニアは何をするべきか。成果が見えにくいのなら、実績として結果が残ることを行うしかない。ここで言う結果とは、 直接的な会社の利益 である。

エンジニアの給料を上げる方法(例)

直接的な会社の利益とはどういったものか。以下は簡単な一例。

例えば、 社内のワークフロー改善を行い続ける ようなことだ。これはモチベーション改善や環境改善とかではなく、もっと根本的な、仕事の工数を削減するようなワークフローの改善という意味。削減された工数はだいたい数値に現れるし、改善したことによって社員や顧客の満足度が向上したのならなお良い。いわゆる業務コンサルのような仕事。

または、実際に 自分が仕事を引っ張ってくる 選択もある。自分が所属している会社が中小企業であるなら、自分がそれなりの仕事を引っ張ってくれば間違いなく会社の利益となるからだ。(これは営業のような仕事…。)しかし、所属している会社が大きいとこれは難しい。大企業ではそれなりに単価が高い仕事を求められがちなため。

このような、直接会社の利益となる活動を行うことが確実にエンジニアが給料を上げる第一歩だと考えた。エンジニアではあれど、直接的な利益を生み出そうと思うとエンジニア以外の仕事もこなさなければならない。

この結果を持って、「私は業務のワークフローを改善し、結果として○時間の工数を削減した。(会社のために仕事を持ってきた)そして今後もこの活動を行い続けるため、私に投資してもらいたい。」と強気に役員とかに凸して認めてもらおう。

エンジニアらしい選択肢として、 エンジニアとしてめっちゃ頑張る (ヘルプ入りまくって、ツール作りまくって、社内活動頑張る)という選択もあるが、これで給料が上がるかは難しい話だ。その活動を認めるかどうかは経営者次第なところが大きく、会社としてのエンジニアへの理解が求められる点でもある。(こういうことができる人は、エンジニアへの理解がある会社で働くべきでは)

おわりに

エンジニアが給料を上げるには、例えば次のような、直接的な利益を生み出すエンジニア業務外の活動などが効果的だという話をした。

  • 業務の工数を削減できるようなワークフロー改善の継続(コンサル)
  • 自分が仕事を引っ張ってくる(営業)

キーワードはおそらく「会社の利益」と「継続」。

エンジニアへの理解が無い会社だと、エンジニアの満足度向上などモチベーションに関わる活動のほとんどは評価のポイントにならないので、その点は注意。

給料を上げる難易度は会社によって違う。エンジニアへの理解があり、なおかつ体力のある企業であれば給料を上げることは容易だろう。しかし、エンジニアへの理解が無い会社であるなら、それは難しいものになる。多くの企業では管理職になることで給料が上がるキャリアプランが準備されているが、これもエンジニアとして働きたい人には辛い選択でもある。

どうしても難しそうなら 転職するしかない(オススメ)