20210606のGoに関する記事は5件です。

goでバージョンアップしたときにはまったことメモ

やったこと 1.13.8 → 1.16.4 go modを使うようにした go envを使うようにした はまったこと go modへ移行したときにパッケージの依存性 https://qiita.com/yuta_vamdemic/items/cb3223eaf4a9a1796db3 1.16系へのバージョンアップ こんなのがでるように ~/A/go ❯ (develop) go mod tidy 241ms  Sun Jun 6 19:20:53 2021 m imports github.com/labstack/echo-contrib/session imports github.com/labstack/echo/v4/middleware tested by github.com/labstack/echo/v4/middleware.test imports io/fs: malformed module path "io/fs": missing dot in first path element m imports github.com/labstack/echo-contrib/session imports github.com/labstack/echo/v4/middleware tested by github.com/labstack/echo/v4/middleware.test imports testing/fstest: malformed module path "testing/fstest": missing dot in first path element 原因 go envが切り替わってなかったこと import指定するパッケージのパスを変える必要があった echoパッケージ before "github.com/labstack/echo/" "github.com/labstack/echo-contrib/session" "github.com/labstack/echo//middleware" after "github.com/labstack/echo/v4" "github.com/labstack/echo-contrib/session" "github.com/labstack/echo/v4/middleware" oidcパッケージ "github.com/coreos/go-oidc/v3/oidc"に変えるひつようがある https://github.com/coreos/go-oidc/tree/v3をみるとbreaking changeとある
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

go modへ移行したときに依存性ではまった

いままではgo modは使わずにGOPATHを利用する普通のパッケージ管理方式でやっていた ビルドしようとしたときに最新のパッケージをダウンロードするからか、どこかのタイミングでビルドが失敗するようになった やること go modへ移行して、ビルド成功していた時のバージョンを指定する サンプル package main import ( "context" "encoding/json" "fmt" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes" "k8s.io/client-go/tools/clientcmd" "log" "os" "path/filepath" ) func main() { // Kubeconfig縺ョ繝輔ぃ繧、繝ォ繝代せ繧呈欠螳・ kubeconfig := filepath.Join(os.Getenv("HOME"), ".kube", "config") config, err := clientcmd.BuildConfigFromFlags("", kubeconfig) if err != nil { log.Fatal(err) } // Kubeconfig繧定ェュ縺ソ霎シ繧€ clientset, err := kubernetes.NewForConfig(config) if err != nil { log.Fatal(err) } // Pod荳€隕ァ繧貞他縺ウ蜃コ縺・ namespace := "default" pods, err := clientset.CoreV1().Pods(namespace).List(context.TODO(), metav1.ListOptions{ LabelSelector: "app=vamdemic111aaa-app", }) if err != nil { log.Fatalln("failed to get pods:", err) } m := map[string]string{} for _, pod := range pods.Items { m[pod.Name] = string(pod.Status.Phase) } data, _ := json.Marshal(m) fmt.Printf(string(data)) } 整理 go mod tidy エラー内容 go: finding k8s.io/utils latest go: finding golang.org/x/time latest main imports k8s.io/client-go/kubernetes imports k8s.io/client-go/discovery imports github.com/googleapis/gnostic/OpenAPIv2: module github.com/googleapis/gnostic@latest found (v0.5.5), but does not contain package github.com/googleapis/gnostic/OpenAPIv2 main imports k8s.io/client-go/kubernetes imports k8s.io/client-go/kubernetes/typed/auditregistration/v1alpha1 imports k8s.io/api/auditregistration/v1alpha1: module k8s.io/api@latest found (v0.21.1), but does not contain package k8s.io/api/auditregistration/v1alpha1 main imports k8s.io/client-go/kubernetes imports k8s.io/client-go/kubernetes/typed/batch/v2alpha1 imports k8s.io/api/batch/v2alpha1: module k8s.io/api@latest found (v0.21.1), but does not contain package k8s.io/api/batch/v2alpha1 main imports k8s.io/client-go/kubernetes imports k8s.io/client-go/kubernetes/typed/settings/v1alpha1 imports k8s.io/api/settings/v1alpha1: module k8s.io/api@latest found (v0.21.1), but does not contain package k8s.io/api/settings/v1alpha1 ひとつづつつぶしていく k8s.io/api main imports k8s.io/client-go/kubernetes imports k8s.io/client-go/kubernetes/typed/auditregistration/v1alpha1 imports k8s.io/api/auditregistration/v1alpha1: module k8s.io/api@latest found (v0.21.1), but does not contain package k8s.io/api/auditregistration/v1alpha1 バージョン一覧 以前は動いていたので、少し前のバージョンをgo modで指定する 指定 go mod edit -require k8s.io/api/auditregistration@v0.20.2 試す 消えてる yuta:/tmp/go $ go mod tidy go: downloading k8s.io/api v0.20.2 go: extracting k8s.io/api v0.20.2 main imports k8s.io/client-go/kubernetes imports k8s.io/client-go/discovery imports github.com/googleapis/gnostic/OpenAPIv2: module github.com/googleapis/gnostic@latest found (v0.5.5), but does not contain package github.com/googleapis/gnostic/OpenAPIv2 main imports k8s.io/client-go/kubernetes imports k8s.io/client-go/kubernetes/typed/auditregistration/v1alpha1 imports k8s.io/api/auditregistration/v1alpha1: module k8s.io/api@latest found (v0.21.1), but does not contain package k8s.io/api/auditregistration/v1alpha1 main imports k8s.io/client-go/kubernetes imports k8s.io/client-go/kubernetes/typed/settings/v1alpha1 imports k8s.io/api/settings/v1alpha1: module k8s.io/api@latest found (v0.21.1), but does not contain package k8s.io/api/settings/v1alpha1 go mod edit -require k8s.io/apimachinery@v0.20.2 と、いろいろやっていたのだけど、同じことをしている方がいた! 結論 go get k8s.io/client-go@v0.20.4とするといいみたい
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

GitLab CIとRenovateでGoパッケージを自動更新する

概要 Webアプリケーション開発のソースコードは、その特性上、多くの外部ライブラリに依存します。 使用者が多いパッケージほど更新頻度が高いため、追従するためには外部パッケージの定期的なアップデートが必要になります。 外部パッケージを定期的に更新していないと、 アップデート時の差分が大きくなり、リスクが高くなる 使用中のバージョンのサポートが打ち切られる 古いバージョンにロックインしてしまう などの問題が発生し、事業インパクトを与える問題に発展しかねません。 ただ、人力での外部パッケージの定期更新作業は面倒です。また、施策を回すための開発より優先度が低くなるため、必要に駆られるまでは後回しにされやすい。 本記事は、外部パッケージのメジャーアップデート検知&更新の自動化を扱った内容となります。 筆者は、業務ではバージョン管理ツールとしてGitLabを使用しています。本記事では外部パッケージのメジャーアップデート検知にRenovate、定期実行ツールとしてGitLab CIを使ったgo パッケージの自動更新のセットアップ方法を扱います。 Renovateとは パッケージの依存関係の更新を自動で検知し、対象ブランチにmerge or pull requestしてくれるツールです。 対象はgo modulesの他にも、 npmパッケージ Gem pip など、他にもさまざまな言語のパッケージ管理ツールをサポートしています。 似たようなものに、Dependabotがあります。こちらは2019年にGitHubに買収されたこともあり、現在はGitHub公式機能になっているため、こちらの方が知名度は高いかもしれません。 筆者は当初、このDependabotを使用する予定だったのですが、こちらをGitLabと組み合わせるには設定が何やら面倒そうでした。 Renovateの方はDockerHubの方に公式イメージがあるので、こちらをGitLabのCIツールであるgitlab-ciでビルドし、Renovateのスクリプトを実行するだけで済みます。この手軽さから、今回はGitLab CI × Renovateの構成を選択しています。 環境 手順 を参考にさせていただき、以下の手順で行いました。 Renovate コンテナからGitLabリポジトリにアクセスできるように、 access tokenを発行 Renovate の設定 GitLab CIの設定 GitLab側の設定(アクセストークンの発行) Renovateの設定(Renovate.json) renovate.jsonに、Renovatebotの設定を書き込みます。 renovate.json { "extends": [ "config:base" ], "postUpdateOptions": [ "gomodTidy" ], "timezone": "Asia/Tokyo" } 基本的に標準の設定をそのまま用いています。 また、パッケージの更新後にgo mod tidyを走らせるために、postUpdateOptionsオプションを追加しています。 ※ gomodTidy: Run go mod tidy after Go module updates. This is implicitly enabled for major module updates. とあるため、設定しなくともよいかも。。。? 今回は自動マージの設定はしておりませんが、その設定も行うことができます。 他にも、様々なオプションを設定できるので、詳しい情報は以下をご参照ください。 GitLab CIの設定(gitlab-ci.yml, schedular) gitlab-ci.ymlに、実行するジョブの設定を記述します。 gitlab-ci.yml stages: - check_version renovate: stage: check_version image: name: renovate/renovate:latest entrypoint: [""] script: - node /usr/src/app/dist/renovate.js --platform gitlab --token {$先ほど作成したアクセストークン} --endpoint https://gitlab.com/api/v4 $CI_PROJECT_NAMESPACE/$CI_PROJECT_NAME only: variables: - $renovate refs: - master image: name: renovate/renovate:latest の部分で、renovateのDocker imageのlatestタグを指定しています。 また、 only: variables: - $renovate refs: - master onlyで、ジョブが作成される条件を制御することができます。 variables・refキーワードで、後で設定する$renovateという変数が有効になっているmasterブランチのイベントに対して、ジョブを作成するよう設定しています。 この設定がないと、リポジトリでのあらゆるイベントに対してジョブが作成されてしまいます。 この時点でのディレクトリは以下のようになっています。 $ tree . ├── gitlab-ci.yml └── renovate.json テスト用にgitlab-ciを手動実行してみる 設定が終わったところで、リモート上で動作確認してみます。 リモートに上げずに、ローカルのDockerコンテナでrenovateを動作させる方法は以下になります。 docker run --rm renovate/renovate --platform gitlab --token {先ほど作成したtoken} --endpoint https://gitlab.com/api/v4 {リポジトリ名} テスト用go.modの作成 動作を確認するため、サンプル用のgo modを作成します。 $ go mod init テスト用に、わざとバージョンが低いパッケージを取得します。今回はginを対象にしています。 $ go get github.com/gin-gonic/gin@v1.6.1 最終的なディレクトリ構成は以下になります。 $ tree . ├── go.mod ├── go.sum └── renovate.json ここまででリモートにpushします。 スケジューラの登録 GitLabで[CI/CD] → [Schedules] → [New schedule]と進み、ジョブのスケジューラを登録します。 実行は一週間に一回の頻度を指定しています。また、Variableでrenovateという変数を有効化します。 この変数は、先ほど設定したgitlab-ci.ymlでジョブの制限条件で使用するものとなります。 スケジュールのテスト実行 GitLabで[CI/CD] → [Schedules] → [▶︎]を押すと、ジョブを手動実行できます。 パッケージのメジャーアップデートがあることを検知しており、masterブランチに対してバージョンアップ用merge requestが作成されていることが確認できます。 マージリクエストの中身をみてみると、go.mod、go.sumの依存パッケージが更新されていることがわかります。 おわりに RenovateをGitLab CIで動かし、メジャーアップデートを検知する仕組みの導入を行いました。人力による外部パッケージのメジャーアップデート追従は厳しいものがあるので、できることなら自動化しておきたいです。 また、業務に導入する際には、そのままだとMerge Requestが放置されたり一部の人に対応が集中したり、などの新たな課題が考えられます。こちらの記事を参考に、マージリクエストをランダムにメンバーにアサインさせるなどの工夫が必要かなと思います。 参考資料
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

GitLab CIとRenovateでgo パッケージを自動更新する

概要 Webアプリケーション開発のソースコードは、その特性上、多くの外部ライブラリに依存します。 使用者が多いパッケージほど更新頻度が高いため、追従するためには外部パッケージの定期的なアップデートが必要になります。 外部パッケージを定期的に更新していないと、 アップデート時の差分が大きくなり、リスクが高くなる 使用中のバージョンのサポートが打ち切られる 古いバージョンにロックインしてしまう などの問題が発生し、事業インパクトを与える問題に発展しかねません。 ただ、人力での外部パッケージの定期更新作業は面倒です。また、施策を回すための開発より優先度が低くなるため、必要に駆られるまでは後回しにされやすい。 本記事は、外部パッケージのメジャーアップデート検知&更新の自動化を扱った内容となります。 筆者は、業務ではバージョン管理ツールとしてGitLabを使用しています。本記事では外部パッケージのメジャーアップデート検知にRenovate、定期実行ツールとしてGitLab CIを使ったgo パッケージの自動更新のセットアップ方法を扱います。 Renovateとは パッケージの依存関係の更新を自動で検知し、対象ブランチにmerge or pull requestしてくれるツールです。 対象はgo modulesの他にも、 npmパッケージ Gem pip など、他にもさまざまな言語のパッケージ管理ツールをサポートしています。 似たようなものに、Dependabotがあります。こちらは2019年にGitHubに買収されたこともあり、現在はGitHub公式機能になっているため、こちらの方が知名度は高いかもしれません。 筆者は当初、このDependabotを使用する予定だったのですが、こちらをGitLabと組み合わせるには設定が何やら面倒そうでした。 Renovateの方はDockerHubの方に公式イメージがあるので、こちらをGitLabのCIツールであるgitlab-ciでビルドし、Renovateのスクリプトを実行するだけで済みます。この手軽さから、今回はGitLab CI × Renovateの構成を選択しています。 環境 手順 を参考にさせていただき、以下の手順で行いました。 Renovate コンテナからGitLabリポジトリにアクセスできるように、 access tokenを発行 Renovate の設定 GitLab CIの設定 GitLab側の設定(アクセストークンの発行) Renovateの設定(Renovate.json) renovate.jsonに、Renovatebotの設定を書き込みます。 renovate.json { "extends": [ "config:base" ], "postUpdateOptions": [ "gomodTidy" ], "timezone": "Asia/Tokyo" } 基本的に標準の設定をそのまま用いています。 また、パッケージの更新後にgo mod tidyを走らせるために、postUpdateOptionsオプションを追加しています。 ※ gomodTidy: Run go mod tidy after Go module updates. This is implicitly enabled for major module updates. とあるため、設定しなくともよいかも。。。? 今回は自動マージの設定はしておりませんが、その設定も行うことができます。 他にも、様々なオプションを設定できるので、詳しい情報は以下をご参照ください。 GitLab CIの設定(gitlab-ci.yml, schedular) gitlab-ci.ymlに、実行するジョブの設定を記述します。 gitlab-ci.yml stages: - check_version renovate: stage: check_version image: name: renovate/renovate:latest entrypoint: [""] script: - node /usr/src/app/dist/renovate.js --platform gitlab --token {$先ほど作成したアクセストークン} --endpoint https://gitlab.com/api/v4 $CI_PROJECT_NAMESPACE/$CI_PROJECT_NAME only: variables: - $renovate refs: - master image: name: renovate/renovate:latest の部分で、renovateのDocker imageのlatestタグを指定しています。 また、 only: variables: - $renovate refs: - master onlyで、ジョブが作成される条件を制御することができます。 variables・refキーワードで、後で設定する$renovateという変数が有効になっているmasterブランチのイベントに対して、ジョブを作成するよう設定しています。 この設定がないと、リポジトリでのあらゆるイベントに対してジョブが作成されてしまいます。 この時点でのディレクトリは以下のようになっています。 $ tree . ├── gitlab-ci.yml └── renovate.json テスト用にgitlab-ciを手動実行してみる 設定が終わったところで、リモート上で動作確認してみます。 リモートに上げずに、ローカルのDockerコンテナでrenovateを動作させる方法は以下になります。 docker run --rm renovate/renovate --platform gitlab --token {先ほど作成したtoken} --endpoint https://gitlab.com/api/v4 {リポジトリ名} テスト用go.modの作成 動作を確認するため、サンプル用のgo modを作成します。 $ go mod init テスト用に、わざとバージョンが低いパッケージを取得します。今回はginを対象にしています。 $ go get github.com/gin-gonic/gin@v1.6.1 最終的なディレクトリ構成は以下になります。 $ tree . ├── go.mod ├── go.sum └── renovate.json ここまででリモートにpushします。 スケジューラの登録 GitLabで[CI/CD] → [Schedules] → [New schedule]と進み、ジョブのスケジューラを登録します。 実行は一週間に一回の頻度を指定しています。また、Variableでrenovateという変数を有効化します。 この変数は、先ほど設定したgitlab-ci.ymlでジョブの制限条件で使用するものとなります。 スケジュールのテスト実行 GitLabで[CI/CD] → [Schedules] → [▶︎]を押すと、ジョブを手動実行できます。 パッケージのメジャーアップデートがあることを検知しており、masterブランチに対してバージョンアップ用merge requestが作成されていることが確認できます。 マージリクエストの中身をみてみると、go.mod、go.sumの依存パッケージが更新されていることがわかります。 おわりに RenovateをGitLab CIで動かし、メジャーアップデートを検知する仕組みの導入を行いました。人力による外部パッケージのメジャーアップデート追従は厳しいものがあるので、できることなら自動化しておきたいです。 また、業務に導入する際には、そのままだとMerge Requestが放置されたり一部の人に対応が集中したり、などの新たな課題が考えられます。こちらの記事を参考に、マージリクエストをランダムにメンバーにアサインさせるなどの工夫が必要かなと思います。 参考資料
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

golang-migrateをコード状から動かした時だけエラーになる

概要 golang-migrateをコマンドラインで実行した際は特に何も起きないのに、Golangコード上から動かすとエラーが出る。。。 環境 Mysql: 8.0.19 golang-migrate: v4 エラー内容 migration failed in line 0: ALTER TABLE `casts` ADD `secret` VARCHAR(255) DEFAULT '' NOT NULL AFTER `capacity`; ALTER TABLE `casts` MODIFY `secret` VARCHAR(255) NOT NULL AFTER `capacity`; (details: Error 1064: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'ALTER TABLE `casts` MODIFY `secret` VARCHAR(255) NOT NULL AFTER `capacity`' at line 2) 実行SQL ALTER TABLE `casts` ADD `secret` VARCHAR(255) DEFAULT '' NOT NULL AFTER `capacity`; ALTER TABLE `casts` MODIFY `secret` VARCHAR(255) NOT NULL AFTER `capacity`; 解決法 multiStatements=trueオプションを追加する user:pass@tcp(host:port)/database?multiStatements=true 参考
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む