まだプログラマーですが何か?

プログラマーネタ中心。たまに作成したウェブサービス関連の話も https://twitter.com/dotnsf

タグ:git

社内ネットワークに Proxy サーバーが設置されている環境は珍しくないと思いますが、そのような環境下でパブリッククラウドを利用して開発作業を行ったり、アプリケーションをデプロイする際に Proxy 環境に応じた設定が必要になります(ついでにいうと、そのような環境下では特定ポート以外を通さない設定になっていることも多いので、単なる Proxy 対応だけでは不十分なこともあります)。

実際にそのような環境でのお客様対応を通じて苦労した得た情報を設定手順含めて共有します。なお以下は IBM Cloud を使ったケースとして紹介していますが、そこそこ広くパブリッククラウド利用時に役立つ情報だと思っています。


【Proxy 環境下で git コマンドを使う】
コマンドプロンプトやターミナルを開いて以下を入力します:
$ git config --global http.proxy http://my.proxyserver.com:8080

$ git config --global https.proxy http://my.proxyserver.com:8080


なお http://my.proxyserver.com:8080 部分は Proxy サーバー名およびポート番号です(以下も同様)。


【ssh でなく https で github(gitlab) を使う】
これは Proxy とは直接関係ないのですが、ssh プロトコル通信が閉じられているような環境下でプライベートな github(gitlab) リポジトリを使いたい場合の、つまり https プロトコルでプライベートな github(gitlab) リポジトリを使う場合に必要な設定項目です。 作業内容としては Private Access Token を設定することで https でも認証が可能になり、プライベートリポジトリを利用することができるようになります。以下 github を使う前提での画面で紹介しますが、gitlab でもほぼ同様です。

まず github にログインし、画面右上の "Settings"  を選択します:
2020022801


次に画面左の "Developer Settings" を選択します:
2020022802


Developer Settings のメニューから "Personal access tokens" を選択し、画面右の "Generate new token" ボタンをクリックします:
2020022803


新たに生成するトークンの設定を指定します。まず名前を(myToken など)適当に入力し、scopes を選択します(わからなければとりあえずは全部):
2020022804


そして最後に画面下部にある "Generate token" ボタンをクリック:
2020022805


すると以下のような画面になり、トークン文字列が表示されます。この文字列はこの一回しか表示されません(一度異なるページを表示した後に再度表示する方法は用意されていません)。別ファイルにコピーするなどしてこの値を再度入力できるようにしてください:
2020022806

ここまで完了していれば、以下のコマンドで https プロトコルだけで github から git clone ができます:
$ git clone https://github.com/aabbcc/xxyyzz.git
 Username: (GitHub のユーザー名)
 Password: (取得したトークン文字列)

なお gitlab の場合は以下のようになります:
$ git clone https://gitlab.com/aabbcc/xxyyzz.git
 Username: oauth2
 Password: (取得したトークン文字列)

【Proxy 環境下で npm コマンドを使う】
サーバーサイド JavaScript である Node.js を使ってアプリケーションを開発する場合、ほぼ npm コマンドを併用することになると思っています。この npm コマンドを Proxy 環境下で使う場合にも設定が必要です。
$ npm -g config set proxy "http://my.proxyserver.com:8080/"
$ npm -g config set https-proxy "http://my.proxyserver.com:8080/"
$ npm -g config set registry "http://registry.npmjs.org/"

proxy と https-proxy の設定をすれば動くはず、ですが、この2つだけではエラーになることがあるらしいです。その場合は registry も設定してください。


【Proxy 環境下で cf コマンドを使う】
これは IBM Cloud 環境に特化した設定かもしれませんが、PaaS である Cloud Foundry ランタイムにアプリケーションを push(デプロイ)する際に利用する cf コマンド(ibmcloud cf コマンド)も Proxy 環境下ではそのための環境設定をしないと使うことはできません。

※Delivery Pipeline サービスを利用することで、cf コマンドを使わずに Git と連動してデプロイすることは可能です。


具体的には環境変数の設定を行う必要があります。以下は Windows 10 での環境変数設定方法です。

コントロールパネル - システムとセキュリティ - システム - システムの詳細設定 を選択します:
2020022807


「詳細設定」タブの「環境変数」ボタンをクリック:
2020022808


ユーザー環境変数で「新規」ボタンをクリック:
2020022809


新しいユーザー変数として、以下の2つを設定します:
変数名変数値
http_proxyProxy サーバー URL
https_proxyProxy サーバー URL

20200228010


2つの環境変数が新たに追加されていることを確認します:

20200228011


これで cf コマンドを指定した Proxy サーバー経由で実行することができるようになりました。

令和最初のブログエントリです。


Node.js アプリの中で git を使う方法を調べてみました。git で Node.js のソースコードを管理する、のではなく、アプリケーションの中で特定の git リポジトリに対して clone したり、pull したり、add して commit して push したり、、、といった操作を Node.js アプリ側から行う方法、という意味です。

この操作を実現するためのライブラリとして simple-git というものを使ってみました。npm を使って以下のコマンドを実行することで導入できます:
$ npm install simple-git

2019050201


そして、以下のコードで扱う git リポジトリは https://github.com/dotnsf/simple-git-sample.git であると仮定します。異なるリポジトリで実験する場合は( fork してコピーを作るなどして)適宜読み替えてください。またローカル側のワーキングフォルダ(git で管理するフォルダ)は ./work/ であると仮定します。


【初期化】
まず、このライブラリを使って Node.js アプリを作る際の初期化方法を紹介します(実はここが一番ややこしい所だったりします)。ここは「実行時に git clone して初期化」するのか、「実行時に git pull して初期化」するのかによって手順が異なります。

実行時に git clone して初期化する場合は以下のようにします:
//. git-clone.js
var git = require( 'simple-git' );

var git_url = 'https://github.com/dotnsf/simple-git-sample.git';
var local_folder = 'work';


//. clone
git().clone( git_url, local_folder );

このコードを node コマンドで実行すると、work/ というフォルダが新規に作成され、https://github.com/dotnsf/simple-git-sample.git のクローンがそのフォルダの中に作成されます。

一方、実行時に git pull して初期化する場合は以下のようにします:
//. git-pull.js
var git = require( 'simple-git' );

var git_url = 'https://github.com/dotnsf/simple-git-sample.git';
var local_folder = 'work';


//. pull
git( local_folder ).pull();

このコードを node コマンドで実行すると、既にワーキングフォルダとして存在している ./work/ フォルダの中に最新のリポジトリ状態が git pull されます。

ここでややこしいのが「どちらを使って初期化するべきか?」です。既にワーキングフォルダ ./work/ が存在している状態で git clone を実行するとエラーになってしまうし、一方ワーキングフォルダが存在していない状態では git pull してもエラーとなってしまうからです。というわけで、以下のように実行すべきだと思いました:
//. git-init.js
var git = require( 'simple-git' );
var fs = require( 'fs' );
var path = require( 'path' );

var git_url = 'https://github.com/dotnsf/simple-git-sample.git';
var local_folder = 'work';

//. フォルダの存在確認
var dirname = path.dirname( './' + local_folder );
fs.access( dirname, fs.constants.R_OK | fs.constants.W_OK, ( err ) => {
  if( err ){
    //. clone
    git().clone( git_url, local_folder );
  }else{
    //. pull
    git( local_folder ).pull();
  }
});

ワーキングフォルダが存在しているかどうかを確認し、存在していなかった場合は git clone を、存在していた場合は(git clone 済みと解釈して)git pull を、それぞれ実行して初期化しています。


【ファイル追加】
次にこの(初期化済みの)ライブラリを使って、リポジトリにファイルを追加する方法を紹介します。厳密にいうと「(git pull して、)git add して、git commit して、git push する」までの一連の方法を紹介します。

といっても、実は結構簡単でこんな感じで一連の処理を実現できます:
//. git-push.js
var git = require( 'simple-git' );
var fs = require( 'fs' );
var path = require( 'path' );

var git_url = 'https://github.com/dotnsf/simple-git-sample.git';
var local_folder = 'work';

//. pull, add, commit, and push
git( local_folder ).pull()
  .add( 'README.md' )
  .commit( 'README.md updated.' )
  .push( [ '-u', 'origin', 'master' ] );

add() のパラメータに追加したいファイル名、commit() のパラメータにはコミットメッセージ、そして push のパラメータにはオプションを指定します(この例だと $ git push -u origin master を実行しているのと同じ処理をしています)。


実際にはブランチ切ったり、マージが必要になったりすることもあるので、全ての git 処理を全自動でというのはなかなか難しい所もあると思いますが、一連の決まった処理を(例外処理無しで)実現するにはシンプルで便利なライブラリだと思いました。


GitHub で作成してしばらく使っていたリポジトリが、当初の想定以上に盛り上がったりすると、最初に適当に付けたリポジトリ名からちゃんとした正式名称のリポジトリに変更したくなる(というか、した)、という経験をしました。その時の作業手順メモです。

まず最初の注意点として、GitHub リポジトリのリネームは GitHub サーバー側と、そのクローンを保持するローカル側の両方で行う必要があります。クローンを保持するローカルが複数ある場合は、その全てのローカル側で対応が必要になります。

今回は
 https://github.com/dotnsf/old_app.git

 https://github.com/dotnsf/new_app.git
にリネームする想定で以下を説明します。

【GitHub サーバー側】
サーバー側の変更は GitHub のリポジトリ画面内から行います。まずブラウザでリポジトリページを開き、"Settings" メニューを選択します:
2018061401


"Settings" メニューのすぐ下に "Repository name" フィールドがあり、ここに変更前のリポジトリ名(今回であれば "old_app")が入力されています:
2018061402


ここを新しいリポジトリ名称(今回であれば "new_app")に変更し、"Rename" ボタンをクリックして確定させます:
2018061403


サーバー側の変更はこれだけです。この時点で名称変更前の URL にアクセスしても自動的に新しい URL にフォワードされて、新しい名前のリポジトリが表示されます:
2018061404



【ローカル側】
クローンしたローカルリポジトリ内の .git/config ファイルを編集します:
  :
  :

[remote "origin"]
        url = https://github.com/dotnsf/new_app
        fetch = +refs/heads/*:refs/remotes/origin/*

  :
  :

[remote "origin"] 項目内の url の値を新しいリポジトリの URL に変更して保存します。ローカル側の変更もこれだけですが、複数のマシンにローカルリポジトリが存在する場合は全てのローカルリポジトリを変更します。



ここまでの作業でサーバー側&リモート側ともリポジトリのリネーム作業が完了しました。当然ですが、中身は変わってない(リネーム前のまま)ので、改めてリネーム後に変更が必要なファイル(README.md とか)を更新してください:
2018061405


 

IBM Cloud(Bluemix) のアカウントを所有していると、マネージドサービスとして利用できる GitLab が使えるようになります。サーバーのインストールなどは不要で、プライベートリポジトリを作成することも可能です:
2018011701


使い勝手は GitLab そのものだと思ってください。Issues 管理の機能も使えますし、IBM Cloud の Continous Delivery サービスと連携した Delivery Pipeline による DevOps サービスの一部としても利用できるようになっています。アカウントをお持ちの方は、単にプライベートリポジトリが使える Git として考えるだけでも便利だと思うので、是非活用してください。


ところで、この IBM Cloud の Git を使って Java のアプリケーションコードを管理しようと、作成したリポジトリから Eclipse の Git 機能を使って clone を試みた際に、稀に以下のようなエラーメッセージに遭遇し、クローンに失敗することがあります:
  :
  :
!MESSAGE https://git.ng.bluemix.net/dotnsf/javatest.git: cannot open git-upload-pack
!STACK 0
org.eclipse.jgit.api.errors.TransportException: https://git.ng.bluemix.net/dotnsf/javatest.git: cannot open git-upload-pack
  at org.eclipse.jgit.api.LsRemoteCommand.call(LsRemoteCommand.java:196)
  at org.eclipse.egit.core.op.ListRemoteOperation.run(ListRemoteOperation.java:99)
  at org.eclipse.egit.ui.internal.clone.SourceBranchPage$8.run(SourceBranchPage.java:324)
  at org.eclipse.jface.operation.ModalContext$ModalContextThread.run(ModalContext.java:121)
Caused by: org.eclipse.jgit.errors.TransportException: https://git.ng.bluemix.net/dotnsf/javatest.git: cannot open git-upload-pack
  at org.eclipse.jgit.transport.TransportHttp.connect(TransportHttp.java:499)
  at org.eclipse.jgit.transport.TransportHttp.openFetch(TransportHttp.java:308)
  at org.eclipse.jgit.api.LsRemoteCommand.call(LsRemoteCommand.java:175)
  :
  :

「git-upload-pack がオープンできない」という耳慣れないエラーメッセージで、実はこのメッセージそのものからは原因の追求が難しいものでした。同じようなエラーに遭遇する人が現れた場合に備えて、自分の経験と回避策を紹介します。

エラーメッセージそのものからはわかりにくにのですが、実は直接の原因は暗号化方式の不一致による通信エラーでした。

まず上記で紹介した IBM Cloud の Git 機能を https 接続で使う場合の暗号化方式には TLS v1.2 を使う必要があります:
https://console.bluemix.net/docs/services/ContinuousDelivery/git_working.html#git_local


さて、Eclipse が使う Java のバージョンが 1.8 以上であれば、デフォルト設定のままで TLS v1.2 が使われます。したがってこの場合は何もしなくてもそのまま IBM Cloud の Git を利用することができます。

一方、Eclipse の Java バージョンが 1.7 以下だった場合、デフォルト設定で採用される通信方式は TLS v1.1 以下です。つまり条件を満たしていないことになります。そしてこの条件で Git に接続しようとすると上記のようなエラーメッセージが表示されてしまうのでした。


では、このエラーメッセージが出た場合の解決策はどうすればいいのでしょうか? 1つの方法としてJava のバージョンを 1.8 以上にするという簡単な方法があります。Java 1.8 以上であれば上記のように(デフォルトで) TLS v1.2 が使われるので、この条件を満たすことができるようになります。

ただ何らかの事情で Java 1.8 を導入するわけにはいかない場合もあると思っています。そのような場合は以下の1行を eclipse.ini に追加した上で Eclipse を起動する、という方法もあります:
  :
  :
-Dhttps.protocols=TLSv1.2

この記述により、Java が 1.7 以下であっても強制的に https 接続時の暗号化方式を TLS v1.2 に指定することができ、やはり上記のエラーを回避することができるようになります。


IBM Cloud 以外の Git でも、同様のエラーメッセージが出た場合にはこの対策が有効だと思っています。頭の片隅に入れながら、無料で便利な IBM Cloud の Git を是非使ってみてください。


IBM Bluemix の利用者に提供されているサービスの1つに IBM DevOps Services(以下、IDS)があります。名前の通り、DevOps のための統合環境サービスなのですが、事実上「ウェブから使えるエディタ」として認識している人もいらっしゃるかもしれません:
2016091306


もちろん統合環境であるからには、こうした「ウェブだけでソースコードが編集できる」機能があることも重要ですが、それだけではありません。ソースコードのバージョン管理として事実上の標準となった Git のリポジトリ機能も使えますし、ビルド&デプロイの管理機能も付属しています。これらはバラバラに(=自分の使い慣れたツールと組み合わせて)使うこともできますし、この環境だけで全て利用することもできます。今回はその前者の例として、IDS を Git のリポジトリとして(のみ)使う例を紹介します。要はソースコードの編集は普段使い慣れたローカルマシンのエディタを使いつつ、ソースコードのバージョン管理に IDS を使おう、という考え方です。必ずしも Bluemix アプリケーションではない、普通のウェブアプリケーションやツールのソースコード管理としても IDS が使える、という使い方をイメージしています。

まずは IDS にウェブブラウザでアクセスして IBM Bluemix の ID とパスワードでログインします:
http://hub.jazz.net/


初めて IDS を使う場合はここでユーザー名の別名を聞かれたりするので適当に決めて答えておきましょう。ただ、ここで決めた名前がこの後作成する Git リポジトリの URL の一部になるのでそのつもりで。

ログイン直後の画面です。既にプロジェクトを利用していたりすると、それらが表示されている画面になるので、見た目は人によって多少変わるかもしれません。以下の画面はまだ何も使っていない、まっさらな状態でのプロジェクト一覧画面です:
2016091301


では早速 Git リポジトリとしてのプロジェクトを1つ追加しましょう。"Start coding" と書かれた大きなアイコン部分をクリックします:
2016091301


ここでプロジェクトの名称(以下の例では "my1stApp")を指定します。今回はこの IDS 内に新しいプロジェクトを作成するので、"Create a new repository" を選択します:
2016091302


続いてリポジトリの作成先を指定するので、"Create a Git repo on Bluemix" を選択します:
2016091303


するとアイコンのすぐ下に今から作成する Git のリポジトリ URL が確認できます。後で再確認することもできますが、一度ここでメモしておきましょう。 また作成するリポジトリにサンプルの README を含めるかどうかを選択するチェックボックスが表示されています。ここでは最初に README を含めておくことにします(任意です)ので、チェックボックスを ON にしておきます:
2016091304


続けてオプションが3つ表示されています。上から順に (1)プライベート(非公開)リポジトリにするか、(2) Scrum 管理機能を追加するか、(3) Bluemix アプリケーションプロジェクト機能を追加するか、です。この例では全て OFF にしていますが、いずれも必要に応じて ON/OFF してください。最後に "CREATE" ボタンを押すと、この設定で Git リポジトリが作成されます:
2016091305


Git リポジトリが作成されると、このような画面に切り替わります。指定した名前のプロジェクトが生成され、その中に License.txt と(オプションで指定した)README.md が含まれている状態で生成されています:
2016091306


画面内で Git のブランチ(この図では master)を表示する部分の右側にダウンロードアイコンが表示されています。現在のブランチの状態でソースコードをまとめてダウンロードする場合はこのアイコンをクリックします(今は行わなくて構いません):
2016091307


また、更にその右側に "Git URL" と書かれた箇所があり、そこをクリックすると改めて Git リポジトリの URL を確認することができます。忘れてしまった場合はこの方法で Git URL を確認してください(このすぐ後に使います):
2016091308


では試しにこの Git プロジェクトの中身を別マシンに clone してみましょう。Git が導入されている環境下で以下のように自分の Git URL(以下の例では https://hub.jazz.net/git/teyande/my1stApp)を指定して git clone してみます:
# git clone https://hub.jazz.net/git/teyande/my1stApp

成功するとこのように License.txt と README.md を含む my1stApp というディレクトリが作成され、現在のリポジトリがクローンできたことがわかります:
2016091301


次にこのプロジェクトディレクトリに移動して、ローカルマシンで変更を加えてみます。本当はここでは vim とか Sublime などの普段使い慣れたエディタ等を使ってファイルを編集することを想定していますが、以下の例では echo コマンドを使ってシンプルな phpinfo.php というファイルを1つ追加しています。何か新しいテキストファイルを1つ(以上)同じディレクトリ内に作成してみてください:
# cd my1stApp
# echo '<?php phpinfo(); ?>' > phpinfo.php

この時点でディレクトリにはもともと存在していた2つのファイルに加え、いくつかのファイルが追加されている状態になっています:
2016091302


ではこの変更を Gir リポジトリに反映させましょう。git add して、git commit します:
# git add .
# git commit -m 'phpinfo.php added.'

こんな感じでローカルリポジトリへのコミットが成功するはずです:
2016091303


では最後に、このローカルリポジトリへの変更をリモートリポジトリへも反映させるべく、git push します。途中でユーザー名やパスワードを聞かれるので、IBM Bluemix のIDおよびパスワードをそれぞれ指定して入力します:
# git push
  :
  :

Username for 'https://hub.jazz.net': bluemix@teyan.de
Password for 'https://bluemix@teyan.de@hub.jazz.net':
  :
  :

↓こんな感じになれば成功です:
2016091304


git push が成功すると、IDS 内のファイルにもその変更が反映されているはずです。この例では元のプロジェクトには存在していなかった phpinfo.php ファイルが git push によって送り込まれ、プロジェクトファイルの一部として追加されていることがわかります:
2016091305


とりあえず Git リポジトリとしての機能が使えることがわかりました。ただこれだけなら GitHub と変わりません。GitHub にない機能の1つとしては「(無料で)プライベートリポジトリが持てる」ことが挙げられます。例えば今回は作成時に Private チェックボックスをオフにしていたので、この時点ではリポジトリは公開されており、同じ URL を誰からでも(IBM Bluemix のアカウントを持っていない人からでも)参照することができる状態になっています:
2016091401


公開状態で作成されたリポジトリをプライベートな非公開状態に変更するには、リポジトリ画面右上の歯車アイコンをクリックし、左メニューから "OPTIONS" を選ぶと、"Private" のチェックボックスが現れます。ここにチェックが入っていれば非公開、入っていなければ公開状態となります:
2016091402


非公開状態に切り替えてみましょう。"Private" チェックボックスを ON にして、"SAVE" ボタンをクリックします:
2016091403


この状態で、同じリポジトリ URL にアクセスすると IBM Bluemix アカウントでログインしていない場合はログインが求められるようになります。また自分(リポジトリのオーナー)以外の ID でログインすると、以下の様な「非公開です」という画面だけが表示されて、中身を確認することはできなくなります:
2016091404


Git のリポジトリを非公開状態で管理しようとすると、GitHub では有償アカウントが必要になります。GitHub 以外にオープンソース製品などで独自にプライベートリポジトリを作れないことはないのですが、IBM Bluemix の IDS を使えば、実質的に無料でプライベートリポジトリまで含めて利用することができる、ということになりますね。 IDS は単なる Git のリポジトリ以上の機能がありますが、この無料のプライベートリポジトリ機能だけでも魅力的だと思っています。


このページのトップヘ