Sidecarを使い、Keynoteの作図をApplePencilで行う

Keynoteの作図をマウスやトラックボールでやると手首や指への負担が大きい。微妙なサイズ変更や移動も疲れる。どうにか楽にできないかと思い、Sidecarを使ってiPad ProにKeynoteを表示し、Apple Pencilをマウスとして使うというのを試してみた。

オブジェクトの選択など、結構やりやすい気がする。文字入力する時にiPadを見ながらキーボードを入力する必要があり、首が疲れるのが難点だが作図する分にはマウスやトラックボールより楽なのではないかと思う。12インチならもっと快適だったかも。

WFH中に購入したキッチン用品3点

WorkFromHome体制になってから外食は減り、自炊のレパートリーを増やす日々である。手持ちの道具でも困ってはいないのだが、気分を上げるためにいくつかキッチン用品を購入した。

ホットサンドメーカー

Twitterで動画が流れてきたり、知人が買っていて良さそうだったので少し遅れて購入。フレンチトーストを作ると最高で、活用している。

写真内の下半分がホットサンドメーカーで作ったもの。フライパンで作った上半分に比べてフワフワでとにかく美味しい。今後フレンチトーストを作るときはホットサンドメーカーしか使わないと心に固く誓った。

ピーラー

セラミックのものから貝印のピーラーにしたのだが、とにかくスムーズに皮が剥けて良い。微妙に切れなかったりすると地味にイライラするので、こういうのは一定以上の品質のものを使うのが大事そう。

マッシャー

ポテトサラダを作る時にジャガイモを潰すのが大変だったので専用の道具を、と思い購入した。サイズは小さめだけど滅茶苦茶大量に作るわけでもないのでちょいどいい。洗いやすいので気軽に使えるのもよし。

TwitterとSlackのアプリをスマートフォンから消した

最近、なんとなく開いては眺めてしまって時間を無駄にしていること、マイナス感情を呼び起こす情報の方が多いなと感じたことからこれらのアプリをスマホから消すことにした。Facebookアプリは入れてても全く見ないんだけどな。Twitterについてはフォローやキーワードミュートを見直す必要もありそう。

envTestを使って、kubernetesのAPIを使うテストを行う

KubernetesのAPIを呼び出すコードを書いていてそこにロジックが含まれる時、テストを行いたい。こういう時、envTestを使うと手軽にetcdとapiserverを起動してテストできる。

ドキュメントは https://book.kubebuilder.io/reference/testing/envtest.html

まずはシンプルに動かしてみる。testEnv.Start() でetcdとapiserverを起動し、そのapiserverに繋がるrest.Configを得る。rest.Configを使ってkubernetes.Clientsetを作成し、ConfigMapを作成したり取得するというもの。テストの最後にはtestEnv.Stop()でetcdとapiserverを停止している。

package main

import (
	"fmt"
	"github.com/k0kubun/pp"
	v1 "k8s.io/api/core/v1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/client-go/kubernetes"
	"sigs.k8s.io/controller-runtime/pkg/envtest"
	"testing"
)

func Test_envtest(t *testing.T) {
	testEnv := &envtest.Environment{}

	restConfig, err := testEnv.Start()
	if err != nil {
		t.Error(err)
	}

	clientset, err := kubernetes.NewForConfig(restConfig)
	if err != nil {
		t.Error(err)
	}

	cm := &v1.ConfigMap{
		ObjectMeta: metav1.ObjectMeta{
			Name:      "test-configmap",
			Namespace: "default",
		},
		Data: map[string]string{
			"foo": "bar",
		},
	}

	fmt.Printf("cm: %s\n", pp.Sprint(cm))
	_, err = clientset.CoreV1().ConfigMaps("default").Create(cm)
	if err != nil {
		t.Error(err)
	}
	got, err := clientset.CoreV1().ConfigMaps("default").Get("test-configmap", metav1.GetOptions{})
	if err != nil {
		t.Error(err)
	}

	fmt.Printf("got: %s\n", pp.Sprint(got))
	if got.Name != cm.Name {
		t.Errorf("missmatch: got = %v, want = %v", got.Name, cm.Name)
	}

	err = testEnv.Stop()
	if err != nil {
		t.Error(err)
	}
}

実行するとこのようになる。作成元のConfigMapと取得したConfigMapをそれぞれ出力しているが、UIDなどが付与されておりリソースとして登録されていることが確認できる。

$ go test ./testenv_test.go -v
=== RUN   Test_envtest
cm: &v1.ConfigMap{
  TypeMeta: v1.TypeMeta{
    Kind:       "",
    APIVersion: "",
  },
  ObjectMeta: v1.ObjectMeta{
    Name:              "test-configmap",
    GenerateName:      "",
    Namespace:         "default",
    SelfLink:          "",
    UID:               "",
    ResourceVersion:   "",
    Generation:        0,
    CreationTimestamp: v1.Time{
      Time: 1-01-01 00:00:00 UTC,
    },
    DeletionTimestamp:          (*v1.Time)(nil),
    DeletionGracePeriodSeconds: (*int64)(nil),
    Labels:                     map[string]string{},
    Annotations:                map[string]string{},
    OwnerReferences:            []v1.OwnerReference{},
    Initializers:               (*v1.Initializers)(nil),
    Finalizers:                 []string{},
    ClusterName:                "",
    ManagedFields:              []v1.ManagedFieldsEntry{},
  },
  Data: map[string]string{
    "foo": "bar",
  },
  BinaryData: map[string][]uint8{},
}
got: &v1.ConfigMap{
  TypeMeta: v1.TypeMeta{
    Kind:       "",
    APIVersion: "",
  },
  ObjectMeta: v1.ObjectMeta{
    Name:              "test-configmap",
    GenerateName:      "",
    Namespace:         "default",
    SelfLink:          "/api/v1/namespaces/default/configmaps/test-configmap",
    UID:               "478835ca-73df-11ea-b65a-acde48001122",
    ResourceVersion:   "43",
    Generation:        0,
    CreationTimestamp: v1.Time{
      Time: 2020-04-01 15:09:00 Local,
    },
    DeletionTimestamp:          (*v1.Time)(nil),
    DeletionGracePeriodSeconds: (*int64)(nil),
    Labels:                     map[string]string{},
    Annotations:                map[string]string{},
    OwnerReferences:            []v1.OwnerReference{},
    Initializers:               (*v1.Initializers)(nil),
    Finalizers:                 []string{},
    ClusterName:                "",
    ManagedFields:              []v1.ManagedFieldsEntry{},
  },
  Data: map[string]string{
    "foo": "bar",
  },
  BinaryData: map[string][]uint8{},
}
--- PASS: Test_envtest (6.17s)
PASS
ok      command-line-arguments  8.066s

client-goのパッケージはモッキングするのも大変だろうから、envtestを使っていくと良さそう。

iPhoneのパスワード自動補完で1Passwordが使えることに気づいたので設定した

iPhoneのSafariから1Passwordを使う時、これまではシェアボタンから起動していたのだけど、結構面倒。どうにかならんかなと思っていたら、自動補完設定に気づいたので設定した。

設定方法は1Passwordアプリが説明してくれるのでその通りにする。

すると、ページを開いたタイミングですぐにサジェストされる。ログインする場合はボタンを押せばFaceIDで認証してログインできる。

これはもっと早く知りたかった…