railsで写真アップロード機能を実装

環境

手順

写真アップロード用モデルを作成

$ rails g scaffold Picture date:datetime

DBのマイグレートを実行

$ rake db:migrate

サーバーを起動してブラウザでアクセスしてみる

$ rails s

http://localhost:3000/pictures

登録ページが表示されていればここまではOK

Gemのインストール

では、CarrierWaveのインストールをプロジェクトに導入します。

$ vi Gemfile
...
gem "carrierwave"

gemをインストール

$ bundle install

アップローダーの生成

CarrierWaveのジェネレーターでアップローダーを作成する

$ rails g uploader Image
  create  app/uploaders/image_uploader.rb

作成されたファイルのimage_uploader.rbの中をのぞいてみると、ファイルの保存方法(デフォルトはファイル)、保存パス、ファイルのサイズ、拡張子やファイル名の変換などが変更できることがわかる。

CarrierWaveはActiveRecordやMongoId、DataMapperなどのORMと連携することができる。 今回は、RailsのデフォルトでもあるActiveRecordを使って、アップロードしたファイルの情報を保存してみる。

Modelに画像情報保持用のカラムの追加

まずは、Stringカラムをモデルに追加するために、Pictureモデルにマイグレーションファイルを作成し、マイグレート

$ rails g migration add_image_to_picture image:string
$ rake db:migrate

その後、モデルファイルを開き、アップローダーへのマウントする記述を追加

$ app/models/picture.rb
class Picture < ActiveRecord::Base
  mount_uploader :image, ImageUploader
end

画像の追加/編集/表示/削除処理の追加

写真の新規/編集フォームに画像アップロードの入力フィールドを追加する。 hidden属性でimage_cacheを指定しましたが、これは、画像を指定したけれども、バリデーションエラーなどにより保存が失敗した場合の画面再表示時などに、画像情報をキャッシュしておくための領域となる。

$ cat app/views/pictures/_form.html.erb
<%= form_for(@picture) do |f| %>
  <% if @picture.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(@picture.errors.count, "error") %> prohibited this picture from being saved:</h2>

      <ul>
      <% @picture.errors.full_messages.each do |message| %>
        <li><%= message %></li>
      <% end %>
      </ul>
    </div>
  <% end %>

  <div class="field">
    <%= f.label :date %><br>
    <%= f.datetime_select :date %>
  </div>

  <!-- 追加個所 -->
  <div class="field">
    <% if @picture.image? %>
      <div class="thumbnail">
      <%= image_tag @picture.image.url %>
    </div>
  <% end %><br>
    <%= f.label :image %><br>
    <%= f.file_field :image %>
    <%= f.hidden_field :image_cache %>
  </div>
  <div class="field">
    <!-- 既存レコード(DBに保存されている)かつ、画像が存在する場合 -->
    <% if @picture.persisted? && @picture.image? %>
      <label>
      <%= f.check_box :remove_image %>
      画像を削除
    </label>
  <% end %>
  </div>
  <!-- 追加個所終了 -->

  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>

コントローラーにファイルの属性を更新できるようにするために、StrongParametersの箇所を修正

$ app/controllers/pictures_controller.rb

...
# Never trust parameters from the scary internet, only allow the white list through.
def picture_params
  # params.require(:picture).permit(:date)
  params.require(:picture).permit(:date, :image, :image_cache, :remove_image)
end

そして、画像がアップロードされたら、詳細画面で表示するようにします。

$ vi app/views/pictures/show.html.erb
<p id="notice"><%= notice %></p>

<p>
  <strong>Date:</strong>
  <%= @picture.date %>
</p>

<!-- 追加箇所 開始 -->
<p>
<strong>Image:</strong>
<% if @picture.image? %>
  <div class="thumbnail">
  <%= image_tag @picture.image.url %>
</div>
<% end %>
</p>
<!-- 追加箇所 終了 -->

<%= link_to 'Edit', edit_picture_path(@picture) %> |
<%= link_to 'Back', pictures_path %>

end

サーバーを起動してhttp://localhost:3000/picturesにアクセス

新規作成で、写真のアップロードや削除ができる

また、このアップロードされたファイルはpublic/uploads/products配下に保存されている

### CarrierWaveの良く使うメソッド

アップローダーをincludeしたモデル次のようなメソッドを使える


#### モデルの作成

product       = Product.new

#### 画像ファイルの設定

product.image = params[:image]         # paramsから設定
product.image = File.open('somewhere') # Fileオブジェクトを設定

#### 保存

product.save!

#### アップローダーの対するメソッド

product.image.url          # => '/url/to/file.png'
product.image.current_path # => 'path/to/file.png'
prodcut.image.identifier   # => 'file.png'
product.image?   # => imageがあるかを true or false で返す

今回はCarrierWaveの基礎的な内容を記載したが、比較的簡単に画像のCRUDActiveRecordのモデルに追加することができることがわかった。

OpenStackのテストセットTempestをJenkinsから実行

以前の記事OpenStackテストセット Tempestのインストールとセットアップ - watariseinの日記の続き

前提としてJenkinsがインストールされていること されていない場合は以下を参考にインストールしておく

CentOS7にjenkinsをインストール - watariseinの日記

手順

Jenkinsに追加するプラグイン

  • Git Plugin

プロジェクトを作成するときに行う設定

以下のURLを、プロジェクトの設定でGitリポジトリに設定

https://github.com/openstack/tempest

f:id:watarisein:20151012232151p:plain

ビルド手順の追加 -> シェルの実行を選択して、以下のシェルを記述する ここでは、tempestのコンフィグファイルにkeystoneに必要な設定をsedを使って設定している

export PYENV_ROOT="/usr/local/pyenv"
export PYENV_BIN="/usr/local/pyenv/shims"
export PATH="${PYENV_ROOT}/bin:${PYENV_BIN}:${PATH}"
pyenv local 2.7.5
tox -egenconfig
cat etc/tempest.conf.sample | \
sed -e 's/#image_ref = <None>/image_ref = 68d82846-9a44-463b-b8e1-72775c84d116/' | \
sed -e 's/#uri = <None>/uri = http:\/\/192.168.1.41:5000\/v2.0\//'  | \
sed -e 's/#uri_v3 = <None>/uri_v3 = http:\/\/192.168.1.41:5000\/v3\//' | \
sed -e 's/#admin_domain_name = <None>/admin_domain_name = Default/' | \
sed -e 's/#admin_tenant_name = <None>/admin_tenant_name = admin/' | \
sed -e 's/#admin_password = <None>/admin_password = admin/' | \
sed -e 's/#admin_username = <None>/admin_username = admin/' > etc/tempest.conf
tox -eall -- --parallel tempest.api.identity

プロジェクトを保存して実行するとテストが走るので、しばらくすると完了する。

集計とかできるようにするにしなければ・・・

OpenStackテストセット Tempestのインストール~セットアップと使い方

CentOS7 アップデートと開発ツールをインストール アップデートと最低限必要と思われる開発ツールをインストール。

# yum update -y
# yum groupinstall -y "Development Tools"
# yum install -y gcc gcc-c++ make git openssl-devel bzip2-devel zlib-devel readline-devel sqlite-devel libffi-devel python-devel
# yum install -y libxslt-devel libxml2-devel #(liverty 対応)

pyenvとpyenv-virtualenv をインストール pyenvと、使うかわからないけどとりあえずpyenv-virtualenvをインストール。

まずgithubからpyenvをcloneしてくる。

# cd /usr/local
# sudo git clone git://github.com/yyuu/pyenv.git ./pyenv

次に /etc/profile.d にpyenvの環境変数を定義しておく。

# vi /etc/profile.d/pyenv.sh

export PYENV_ROOT="/usr/local/pyenv"
export PATH="${PYENV_ROOT}/bin:${PATH}"
eval "$(pyenv init -)"

シェルを再度起動し直し、環境変数を読み込む

# exec $SHELL -l

pyenvからpythonをインストール pyenvでインストールできるpythonのバージョンを確認。

pythonのバージョンのリスト

# pyenv install --list

Available versions:
  2.1.3
.............
  2.7.9
  2.7.10
.............
  3.4.1
  3.4.2
  3.4.3
.............
  stackless-3.4.1

TempestはPython 2.7 and Python 3.4を推奨しているので、2.7.5をインストール。

# pyenv install 2.7.5

「pyenv versions」で確認できる。

# pyenv versions
* system (set by /usr/local/pyenv/version)
  2.7.5

利用するpythonのバージョンの指定方法は、自分だけを指定する「local」とシステムユーザー全体を指定する「global」の2種類ある。 「local」に関しては、一般ユーザーが自分で指定することができる。

pythonバージョンの指定

# pyenv local 2.7.5

pipをインストール

# curl -kL https://raw.github.com/pypa/pip/master/contrib/get-pip.py | python

toxをインストール

# pip install tox

Tempestのインストール

パッケージをダウンロード

# git clone https://github.com/openstack/tempest.git

コンフィグファイルを作成

# cd tempest
# tox -egenconfig

コンフィグファイルを編集、最低限以下のようにする

[compute]
image_ref = 68d82846-9a44-463b-b8e1-72775c84d116

[identity]
auth_version = v2
admin_domain_name = Default
admin_tenant_name = admin
admin_password = admin
admin_username = admin
uri_v3 = http://192.168.1.41:5000/v3/
uri = http://192.168.1.41:5000/v2.0/

スクリプトで作成

cat etc/tempest.conf.sample | \
sed -e 's/#image_ref = <None>/image_ref = 68d82846-9a44-463b-b8e1-72775c84d116/' | \
sed -e 's/#uri = <None>/uri = http:\/\/192.168.1.41:5000\/v2.0\//'  | \
sed -e 's/#uri_v3 = <None>/uri_v3 = http:\/\/192.168.1.41:5000\/v3\//' | \
sed -e 's/#admin_domain_name = <None>/admin_domain_name = Default/' | \
sed -e 's/#admin_tenant_name = <None>/admin_tenant_name = admin/' | \
sed -e 's/#admin_password = <None>/admin_password = admin/' | \
sed -e 's/#admin_username = <None>/admin_username = admin/' > etc/tempest.conf

試しにkeystoneの認証テスト実行

# tox -eall -- --parallel tempest.api.identity.v2
all create: /root/tempest/.tox/all
all installdeps: setuptools, -r/root/tempest/requirements.txt
all develop-inst: /root/tempest
all installed: anyjson==0.3.3,Babel==2.1.1,boto==2.38.0,cffi==1.2.1,cliff==1.15.0,cmd2==0.6.8,cryptography==1.0.2,debtcollector==0.8.0,ecdsa==0.13,enum34==1.0.4,extras==0.0.3,fasteners==0.13.0,fixtures==1.4.0,functools32==3.2.3.post2,httplib2==0.9.2,idna==2.0,ipaddress==1.0.14,iso8601==0.1.10,jsonschema==2.5.1,linecache2==1.0.0,monotonic==0.4,msgpack-python==0.4.6,netaddr==0.7.18,netifaces==0.10.4,os-testr==0.4.2,oslo.concurrency==2.6.0,oslo.config==2.4.0,oslo.context==0.6.0,oslo.i18n==2.6.0,oslo.log==1.11.0,oslo.serialization==1.10.0,oslo.utils==2.5.0,paramiko==1.15.3,pbr==1.8.1,prettytable==0.7.2,pyasn1==0.1.9,pycparser==2.14,pycrypto==2.6.1,pyOpenSSL==0.15.1,pyparsing==2.0.3,python-mimeparse==0.1.4,python-subunit==1.1.0,pytz==2015.6,PyYAML==3.11,retrying==1.3.3,six==1.10.0,stevedore==1.8.0,-e git+https://github.com/openstack/tempest.git@f656444c017b06f0c8438041765f9b93e6505736#egg=tempest-master,tempest-lib==0.9.0,testrepository==0.0.20,testscenarios==0.5.0,testtools==1.8.0,traceback2==1.4.0,unicodecsv==0.14.1,unittest2==1.1.0,wheel==0.24.0,wrapt==1.10.5
all runtests: PYTHONHASHSEED='3081811371'
all runtests: commands[0] | find . -type f -name *.pyc -delete
all runtests: commands[1] | bash tools/pretty_tox.sh --parallel tempest.api.identity.v2
running testr
2015-10-12 19:34:49.263 25223 INFO tempest [-] Using tempest config file /root/tempest/etc/tempest.conf
2015-10-12 19:34:50.815 25223 INFO tempest_lib.common.rest_client [req-4da75abe-2d53-4b45-9b69-cc1580b6a482 ] Request (main): 200 POST http://192.168.1.41:5000/v2.0/tokens
2015-10-12 19:34:50.888 25223 INFO tempest_lib.common.rest_client [req-d79fae4b-1e46-4d11-85d4-53dcc4c22654 ] Request (main): 200 POST http://192.168.1.41:5000/v2.0/tokens
2015-10-12 19:34:50.965 25223 INFO tempest_lib.common.rest_client [req-d2e4f8af-d05d-4ffd-8ccb-a2e20e0cb381 ] Request (main): 200 POST http://192.168.1.41:35357/v2.0/tenants 0.075s
2015-10-12 19:34:51.081 25223 INFO tempest_lib.common.rest_client [req-929cb067-25a1-4801-9fba-3cf08b1b869e ] Request (main): 200 POST http://192.168.1.41:35357/v2.0/users 0.108s
2015-10-12 19:34:51.146 25223 INFO tempest_lib.common.rest_client [req-232420c7-d433-4dbf-a214-a150b84bb972 ] Request (main): 200 POST http://192.168.1.41:5000/v2.0/tokens
2015-10-12 19:34:51.147 25223 INFO tempest.common.dynamic_creds [-] Acquired dynamic creds:
 credentials: <tempest.common.cred_provider.TestResources object at 0x3386e50>
2015-10-12 19:34:51.216 25223 INFO tempest_lib.common.rest_client [req-abbc6920-c5fe-4f57-9abe-5b1ee15b6089 ] Request (main): 200 POST http://192.168.1.41:5000/v2.0/tokens
2015-10-12 19:34:51.308 25223 INFO tempest_lib.common.rest_client [req-ffa660e4-fd35-43b2-b3b0-2a40eb0e2e07 ] Request (main): 200 GET http://192.168.1.41:8774/v2/5bf44a944b5e4fbab661515a37442f42/flavors 0.090s
2015-10-12 19:34:51.637 25223 INFO tempest_lib.common.rest_client [req-f222f06f-b4d5-41bb-a5b1-65c77d8a7310 ] Request (main): 200 GET http://192.168.1.41:8774/v2/5bf44a944b5e4fbab661515a37442f42/images 0.322s
2015-10-12 19:34:51.732 25223 INFO tempest_lib.common.rest_client [req-b99b6fe9-3ddc-4ce3-8c06-4fc38ef4212b ] Request (main): 204 DELETE http://192.168.1.41:35357/v2.0/users/486db651ba254076855e06192219fc5f 0.089s
2015-10-12 19:34:51.816 25223 INFO tempest_lib.common.rest_client [req-4e66d777-fce1-4a87-bf34-b1a20c7f3e94 ] Request (main): 204 DELETE http://192.168.1.41:35357/v2.0/tenants/5bf44a944b5e4fbab661515a37442f42 0.082s
2015-10-12 19:34:52.308 25232 INFO tempest [-] Using tempest config file /root/tempest/etc/tempest.conf
2015-10-12 19:34:52.807 25232 INFO tempest_lib.common.rest_client [req-9ae99477-33b0-4e92-aef8-9f6f5f796ea2 ] Request (main): 200 POST http://192.168.1.41:5000/v2.0/tokens
2015-10-12 19:34:52.879 25232 INFO tempest_lib.common.rest_client [req-53e7e6ae-f736-408a-ac55-397e4dd1c89f ] Request (main): 200 POST http://192.168.1.41:5000/v2.0/tokens
2015-10-12 19:34:52.995 25232 INFO tempest_lib.common.rest_client [req-8171640d-8456-4cbb-864c-182f1931d6e5 ] Request (main): 200 POST http://192.168.1.41:35357/v2.0/tenants 0.114s
2015-10-12 19:34:53.110 25232 INFO tempest_lib.common.rest_client [req-09018f8a-3194-4e11-a691-17c279c66833 ] Request (main): 200 POST http://192.168.1.41:35357/v2.0/users 0.108s
2015-10-12 19:34:53.170 25232 INFO tempest_lib.common.rest_client [req-69bc373c-5a9a-426e-b47e-12de6056ce4d ] Request (main): 200 POST http://192.168.1.41:5000/v2.0/tokens
2015-10-12 19:34:53.171 25232 INFO tempest.common.dynamic_creds [-] Acquired dynamic creds:
 credentials: <tempest.common.cred_provider.TestResources object at 0x3f4bcd0>
2015-10-12 19:34:53.244 25232 INFO tempest_lib.common.rest_client [req-6bffbfec-e5a0-4519-804f-d37b9e139527 ] Request (main): 200 POST http://192.168.1.41:5000/v2.0/tokens
2015-10-12 19:34:53.331 25232 INFO tempest_lib.common.rest_client [req-d5e126da-8d55-4319-9da4-ed1e06adb713 ] Request (main): 200 GET http://192.168.1.41:8774/v2/fc13bfdf7b4a477dbe00143e9c0b5194/flavors 0.085s
2015-10-12 19:34:53.671 25232 INFO tempest_lib.common.rest_client [req-57a6a22b-02bd-42ce-aff4-e0697ca9c6ed ] Request (main): 200 GET http://192.168.1.41:8774/v2/fc13bfdf7b4a477dbe00143e9c0b5194/images 0.331s
2015-10-12 19:34:53.763 25232 INFO tempest_lib.common.rest_client [req-4bff07ab-1ec0-4916-9153-8af1ba1a7d09 ] Request (main): 204 DELETE http://192.168.1.41:35357/v2.0/users/073b8633ac7540ce8422fdb17b07fea7 0.088s
2015-10-12 19:34:54.041 25232 INFO tempest_lib.common.rest_client [req-4496e157-b816-4fcc-b822-00891575cb49 ] Request (main): 204 DELETE http://192.168.1.41:35357/v2.0/tenants/fc13bfdf7b4a477dbe00143e9c0b5194 0.277s
running=OS_STDOUT_CAPTURE=${OS_STDOUT_CAPTURE:-1} \
OS_STDERR_CAPTURE=${OS_STDERR_CAPTURE:-1} \
OS_TEST_TIMEOUT=${OS_TEST_TIMEOUT:-500} \
OS_TEST_LOCK_PATH=${OS_TEST_LOCK_PATH:-${TMPDIR:-'/tmp'}} \
${PYTHON:-python} -m subunit.run discover -t ${OS_TOP_LEVEL:-./} ${OS_TEST_PATH:-./tempest/test_discover} --list 
running=OS_STDOUT_CAPTURE=${OS_STDOUT_CAPTURE:-1} \
OS_STDERR_CAPTURE=${OS_STDERR_CAPTURE:-1} \
OS_TEST_TIMEOUT=${OS_TEST_TIMEOUT:-500} \
OS_TEST_LOCK_PATH=${OS_TEST_LOCK_PATH:-${TMPDIR:-'/tmp'}} \
${PYTHON:-python} -m subunit.run discover -t ${OS_TOP_LEVEL:-./} ${OS_T2015-10-12 19:34:54.185 25232 INFO tempest_lib.common.rest_client [req-17afdf48-6807-47d1-837c-72561ebca0b8 ] Request (TestApiDiscovery:setUpClass): 200 POST http://192.168.1.41:5000/v2.0/tokens
EST_PATH:-./tempest/test_discover}  --load-list /tmp/tmphQLMMJ
2015-10-12 19:34:54.256 25232 INFO tempest_lib.common.rest_client [req-d963edea-7902-4a27-bbb8-d743cdb7ee16 ] Request (TestApiDiscovery:setUpClass): 200 POST http://192.168.1.41:5000/v2.0/tokens
2015-10-12 19:34:54.331 25232 INFO tempest_lib.common.rest_client [req-8ed8a725-7274-43be-a17a-00545a2ece31 ] Request (TestApiDiscovery:setUpClass): 200 POST http://192.168.1.41:35357/v2.0/tenants 0.073s
2015-10-12 19:34:54.440 25232 INFO tempest_lib.common.rest_client [req-35e6f4c6-6ed5-4aec-8fbf-83a999d131ef ] Request (TestApiDiscovery:setUpClass): 200 POST http://192.168.1.41:35357/v2.0/users 0.108s
2015-10-12 19:34:54.498 25232 INFO tempest_lib.common.rest_client [req-e1ddad16-08a8-419b-9d32-b2a075611985 ] Request (TestApiDiscovery:setUpClass): 200 POST http://192.168.1.41:5000/v2.0/tokens
2015-10-12 19:34:54.498 25232 INFO tempest.common.dynamic_creds [-] Acquired dynamic creds:
 credentials: <tempest.common.cred_provider.TestResources object at 0x32e7d90>
2015-10-12 19:34:54.562 25232 INFO tempest_lib.common.rest_client [req-08ba4c45-5adc-4114-84e2-0daacf20c2f8 ] Request (TestApiDiscovery:test_api_media_types): 200 POST http://192.168.1.41:5000/v2.0/tokens
2015-10-12 19:34:54.604 25232 INFO tempest_lib.common.rest_client [req-a65e32ef-723d-48ae-a097-e9ec50e17212 ] Request (TestApiDiscovery:test_api_media_types): 200 GET http://192.168.1.41:5000/v2.0 0.041s
{0} tempest.api.identity.v2.test_api_discovery.TestApiDiscovery.test_api_media_types [0.103620s] ... ok
2015-10-12 19:34:54.653 25232 INFO tempest_lib.common.rest_client [req-5ee135a1-33c1-4a64-ba28-3661ae3fdab2 ] Request (TestApiDiscovery:test_api_version_resources): 200 GET http://192.168.1.41:5000/v2.0 0.046s
{0} tempest.api.identity.v2.test_api_discovery.TestApiDiscovery.test_api_version_resources [0.048421s] ... ok
2015-10-12 19:34:54.703 25232 INFO tempest_lib.common.rest_client [req-ad077e15-1272-499a-8ad5-913bd57af3fc ] Request (TestApiDiscovery:test_api_version_statuses): 200 GET http://192.168.1.41:5000/v2.0 0.047s
{0} tempest.api.identity.v2.test_api_discovery.TestApiDiscovery.test_api_version_statuses [0.048896s] ... ok
2015-10-12 19:34:54.798 25232 INFO tempest_lib.common.rest_client [req-39486180-7983-4602-bee0-6f201247573a ] Request (TestApiDiscovery:tearDownClass): 204 DELETE http://192.168.1.41:35357/v2.0/users/95cc5a78edd740c682191654cfc24cb4 0.092s
2015-10-12 19:34:54.883 25232 INFO tempest_lib.common.rest_client [req-923b5850-4826-4953-b29c-552041f464d7 ] Request (TestApiDiscovery:tearDownClass): 204 DELETE http://192.168.1.41:35357/v2.0/tenants/9a1666dc45e242508788b68f95455c26 0.083s
2015-10-12 19:34:54.942 25232 INFO tempest_lib.common.rest_client [req-9ac2ff3e-5f4b-4d3d-aa98-cf9e899cefe5 ] Request (EC2CredentialsTest:setUpClass): 200 POST http://192.168.1.41:5000/v2.0/tokens
2015-10-12 19:34:55.029 25232 INFO tempest_lib.common.rest_client [req-9e5bddf4-a3a2-42e8-9133-d24ddf9958fd ] Request (EC2CredentialsTest:setUpClass): 200 POST http://192.168.1.41:5000/v2.0/tokens
2015-10-12 19:34:55.107 25232 INFO tempest_lib.common.rest_client [req-0f05f11f-61e5-463d-8957-7f83ba00fd7e ] Request (EC2CredentialsTest:setUpClass): 200 POST http://192.168.1.41:35357/v2.0/tenants 0.077s
2015-10-12 19:34:55.214 25232 INFO tempest_lib.common.rest_client [req-d3f29e8e-2f1f-486c-904d-0eda14ed37b2 ] Request (EC2CredentialsTest:setUpClass): 200 POST http://192.168.1.41:35357/v2.0/users 0.105s
2015-10-12 19:34:55.275 25232 INFO tempest_lib.common.rest_client [req-390b75ce-9a09-403b-8563-cf827fb47f85 ] Request (EC2CredentialsTest:setUpClass): 200 POST http://192.168.1.41:5000/v2.0/tokens
2015-10-12 19:34:55.276 25232 INFO tempest.common.dynamic_creds [-] Acquired dynamic creds:
 credentials: <tempest.common.cred_provider.TestResources object at 0x400b250>
2015-10-12 19:34:55.346 25232 INFO tempest_lib.common.rest_client [req-3fdcab1e-62cc-4b3a-a968-1d49bb235d4e ] Request (EC2CredentialsTest:test_create_ec2_credentials): 200 POST http://192.168.1.41:5000/v2.0/tokens
2015-10-12 19:34:55.508 25232 INFO tempest_lib.common.rest_client [req-b2b39d45-0edd-4fb3-bf76-cb9e484e4103 ] Request (EC2CredentialsTest:test_create_ec2_credentials): 200 POST http://192.168.1.41:5000/v2.0/users/c2c97c2afdb24a7e8d2ca08fdf2258b3/credentials/OS-EC2 0.160s
2015-10-12 19:34:55.659 25232 INFO tempest_lib.common.rest_client [req-caa869de-bf06-4811-9582-82fce784aee5 ] Request (EC2CredentialsTest:_run_cleanups): 204 DELETE http://192.168.1.41:5000/v2.0/users/c2c97c2afdb24a7e8d2ca08fdf2258b3/credentials/OS-EC2/ab540147ab7540f298d2a59165029093 0.149s
{0} tempest.api.identity.v2.test_ec2_credentials.EC2CredentialsTest.test_create_ec2_credentials [0.376721s] ... ok
2015-10-12 19:34:55.839 25232 INFO tempest_lib.common.rest_client [req-47a61050-79d7-48a5-8839-93710e04d9d5 ] Request (EC2CredentialsTest:test_delete_ec2_credentials): 200 POST http://192.168.1.41:5000/v2.0/users/c2c97c2afdb24a7e8d2ca08fdf2258b3/credentials/OS-EC2 0.178s
2015-10-12 19:34:55.945 25232 INFO tempest_lib.common.rest_client [req-b8fc939e-4160-4a28-b215-4760c80f52c4 ] Request (EC2CredentialsTest:test_delete_ec2_credentials): 204 DELETE http://192.168.1.41:5000/v2.0/users/c2c97c2afdb24a7e8d2ca08fdf2258b3/credentials/OS-EC2/d9bb863b9e7d4d11bece51043db6d194 0.105s
2015-10-12 19:34:56.047 25232 INFO tempest_lib.common.rest_client [req-c78e5553-9797-4c67-b28e-0a1dd656827f ] Request (EC2CredentialsTest:test_delete_ec2_credentials): 404 GET http://192.168.1.41:5000/v2.0/users/c2c97c2afdb24a7e8d2ca08fdf2258b3/credentials/OS-EC2/d9bb863b9e7d4d11bece51043db6d194 0.100s
{0} tempest.api.identity.v2.test_ec2_credentials.EC2CredentialsTest.test_delete_ec2_credentials [0.388969s] ... ok
2015-10-12 19:34:56.190 25232 INFO tempest_lib.common.rest_client [req-9d57db04-e7f8-4658-913e-f3889406a500 ] Request (EC2CredentialsTest:test_list_ec2_credentials): 200 POST http://192.168.1.41:5000/v2.0/users/c2c97c2afdb24a7e8d2ca08fdf2258b3/credentials/OS-EC2 0.139s
2015-10-12 19:34:56.364 25232 INFO tempest_lib.common.rest_client [req-b28a0300-ce96-4a87-9128-c4b0004644b1 ] Request (EC2CredentialsTest:test_list_ec2_credentials): 200 POST http://192.168.1.41:5000/v2.0/users/c2c97c2afdb24a7e8d2ca08fdf2258b3/credentials/OS-EC2 0.172s
2015-10-12 19:34:56.469 25232 INFO tempest_lib.common.rest_client [req-daf12b12-d0df-44fd-9ffd-9d2a143d4384 ] Request (EC2CredentialsTest:test_list_ec2_credentials): 200 GET http://192.168.1.41:5000/v2.0/users/c2c97c2afdb24a7e8d2ca08fdf2258b3/credentials/OS-EC2 0.103s
2015-10-12 19:34:56.574 25232 INFO tempest_lib.common.rest_client [req-94c41d44-32de-4c50-8bda-e5c4ac95689b ] Request (EC2CredentialsTest:_run_cleanups): 204 DELETE http://192.168.1.41:5000/v2.0/users/c2c97c2afdb24a7e8d2ca08fdf2258b3/credentials/OS-EC2/74f78304c09b43daaa8ef035ec60889c 0.103s
2015-10-12 19:34:56.680 25232 INFO tempest_lib.common.rest_client [req-25023eb2-796e-41ff-b3de-f20c623ed875 ] Request (EC2CredentialsTest:_run_cleanups): 204 DELETE http://192.168.1.41:5000/v2.0/users/c2c97c2afdb24a7e8d2ca08fdf2258b3/credentials/OS-EC2/640a8eed36e84b9a9a913e4da758e2cf 0.105s
{0} tempest.api.identity.v2.test_ec2_credentials.EC2CredentialsTest.test_list_ec2_credentials [0.631367s] ... ok
2015-10-12 19:34:56.827 25232 INFO tempest_lib.common.rest_client [req-4086a13e-8f42-4a26-8f9f-8cb1895eebfc ] Request (EC2CredentialsTest:test_show_ec2_credentials): 200 POST http://192.168.1.41:5000/v2.0/users/c2c97c2afdb24a7e8d2ca08fdf2258b3/credentials/OS-EC2 0.144s
2015-10-12 19:34:56.927 25232 INFO tempest_lib.common.rest_client [req-bbe769fa-aa58-4b14-8d5a-13545e4dfe30 ] Request (EC2CredentialsTest:test_show_ec2_credentials): 200 GET http://192.168.1.41:5000/v2.0/users/c2c97c2afdb24a7e8d2ca08fdf2258b3/credentials/OS-EC2/0207367fca8742e49f6713a7c453d9c9 0.100s
2015-10-12 19:34:57.073 25232 INFO tempest_lib.common.rest_client [req-f3674fbb-9257-4fee-802f-64e2001b7f79 ] Request (EC2CredentialsTest:_run_cleanups): 204 DELETE http://192.168.1.41:5000/v2.0/users/c2c97c2afdb24a7e8d2ca08fdf2258b3/credentials/OS-EC2/0207367fca8742e49f6713a7c453d9c9 0.143s
{0} tempest.api.identity.v2.test_ec2_credentials.EC2CredentialsTest.test_show_ec2_credentials [0.391859s] ... ok
2015-10-12 19:34:57.172 25232 INFO tempest_lib.common.rest_client [req-0374fb8b-6761-4e44-b7de-3d1a47b96769 ] Request (EC2CredentialsTest:tearDownClass): 204 DELETE http://192.168.1.41:35357/v2.0/users/c2c97c2afdb24a7e8d2ca08fdf2258b3 0.096s
2015-10-12 19:34:57.261 25232 INFO tempest_lib.common.rest_client [req-96568e3c-d6e5-4b0d-9796-44dc9f96748f ] Request (EC2CredentialsTest:tearDownClass): 204 DELETE http://192.168.1.41:35357/v2.0/tenants/92cb0bd0e755426087b85076856bad69 0.088s
2015-10-12 19:34:57.321 25232 INFO tempest_lib.common.rest_client [req-2f594727-cd51-43c7-9c29-fd12a8c88a0b ] Request (IdentityTenantsTest:setUpClass): 200 POST http://192.168.1.41:5000/v2.0/tokens
2015-10-12 19:34:57.396 25232 INFO tempest_lib.common.rest_client [req-f74532c5-540c-4c2d-a33b-15dc0d8b2d48 ] Request (IdentityTenantsTest:setUpClass): 200 POST http://192.168.1.41:5000/v2.0/tokens
2015-10-12 19:34:57.516 25232 INFO tempest_lib.common.rest_client [req-1bfcbecd-b7ff-45b7-806d-02c7d842f77b ] Request (IdentityTenantsTest:setUpClass): 200 POST http://192.168.1.41:35357/v2.0/tenants 0.119s
2015-10-12 19:34:57.624 25232 INFO tempest_lib.common.rest_client [req-37835f0b-cbec-46d7-946a-4787541f9a50 ] Request (IdentityTenantsTest:setUpClass): 200 POST http://192.168.1.41:35357/v2.0/users 0.106s
2015-10-12 19:34:57.684 25232 INFO tempest_lib.common.rest_client [req-208e765f-40d0-4ed7-92ef-042e3b8493fb ] Request (IdentityTenantsTest:setUpClass): 200 POST http://192.168.1.41:5000/v2.0/tokens
2015-10-12 19:34:57.685 25232 INFO tempest.common.dynamic_creds [-] Acquired dynamic creds:
 credentials: <tempest.common.cred_provider.TestResources object at 0x417cd90>
2015-10-12 19:34:57.767 25232 INFO tempest_lib.common.rest_client [req-c16cca37-8100-4b8d-9020-b4306731bfe9 ] Request (IdentityTenantsTest:setUpClass): 200 POST http://192.168.1.41:35357/v2.0/tenants 0.075s
2015-10-12 19:34:57.873 25232 INFO tempest_lib.common.rest_client [req-43cba925-5fd0-41e1-aa15-f810ac838e6a ] Request (IdentityTenantsTest:setUpClass): 200 POST http://192.168.1.41:35357/v2.0/users 0.104s
2015-10-12 19:34:57.929 25232 INFO tempest_lib.common.rest_client [req-b562cfcd-d41b-411d-852b-09e370bd8dd9 ] Request (IdentityTenantsTest:setUpClass): 200 POST http://192.168.1.41:5000/v2.0/tokens
2015-10-12 19:34:57.930 25232 INFO tempest.common.dynamic_creds [-] Acquired dynamic creds:
 credentials: <tempest.common.cred_provider.TestResources object at 0x419f510>
2015-10-12 19:34:57.991 25232 INFO tempest_lib.common.rest_client [req-55f579dd-9b3b-418d-b024-cbadd8d89c8e ] Request (IdentityTenantsTest:test_list_tenants_returns_only_authorized_tenants): 200 POST http://192.168.1.41:5000/v2.0/tokens
2015-10-12 19:34:58.064 25232 INFO tempest_lib.common.rest_client [req-7e689437-71d0-45b6-a5fa-7653eba6a7fd ] Request (IdentityTenantsTest:test_list_tenants_returns_only_authorized_tenants): 200 GET http://192.168.1.41:5000/v2.0/tenants 0.072s
2015-10-12 19:34:58.120 25232 INFO tempest_lib.common.rest_client [req-7f9a81cd-c2d2-4566-9f57-18c8dee43153 ] Request (IdentityTenantsTest:test_list_tenants_returns_only_authorized_tenants): 200 POST http://192.168.1.41:5000/v2.0/tokens
2015-10-12 19:34:58.169 25232 INFO tempest_lib.common.rest_client [req-a7fd0719-01fe-4592-ae69-af6945c96dbf ] Request (IdentityTenantsTest:test_list_tenants_returns_only_authorized_tenants): 401 POST http://192.168.1.41:5000/v2.0/tokens
{0} tempest.api.identity.v2.test_tenants.IdentityTenantsTest.test_list_tenants_returns_only_authorized_tenants [0.236712s] ... ok
2015-10-12 19:34:58.260 25232 INFO tempest_lib.common.rest_client [req-d22fc8d3-6eed-47c8-ad88-f9367fae27b9 ] Request (IdentityTenantsTest:tearDownClass): 204 DELETE http://192.168.1.41:35357/v2.0/users/5dc37fd4c15541658c8c3029eae6ae17 0.088s
2015-10-12 19:34:58.346 25232 INFO tempest_lib.common.rest_client [req-8b22e159-fbb1-4e2a-b65b-a2763823f458 ] Request (IdentityTenantsTest:tearDownClass): 204 DELETE http://192.168.1.41:35357/v2.0/tenants/7ebffa3080c64742abd845d5962b19fb 0.084s
2015-10-12 19:34:58.475 25232 INFO tempest_lib.common.rest_client [req-627c89da-aaed-4b3f-9c92-4188abd81244 ] Request (IdentityTenantsTest:tearDownClass): 204 DELETE http://192.168.1.41:35357/v2.0/users/6b3b26b815754157a4bc8702379ad34b 0.128s
2015-10-12 19:34:58.560 25232 INFO tempest_lib.common.rest_client [req-82807dc2-5a0c-4d0c-939c-8e29e8a89542 ] Request (IdentityTenantsTest:tearDownClass): 204 DELETE http://192.168.1.41:35357/v2.0/tenants/c863277b40fc457d82d5ac04776d700f 0.084s
2015-10-12 19:34:58.624 25232 INFO tempest_lib.common.rest_client [req-344c1193-1d26-4118-88c0-aca8ee8a6583 ] Request (TokensTest:setUpClass): 200 POST http://192.168.1.41:5000/v2.0/tokens
2015-10-12 19:34:58.699 25232 INFO tempest_lib.common.rest_client [req-805505ef-5bbf-4a06-b903-8b29293503e8 ] Request (TokensTest:setUpClass): 200 POST http://192.168.1.41:5000/v2.0/tokens
2015-10-12 19:34:58.772 25232 INFO tempest_lib.common.rest_client [req-e2a5e658-25aa-455c-b824-103bed2a3b66 ] Request (TokensTest:setUpClass): 200 POST http://192.168.1.41:35357/v2.0/tenants 0.071s
2015-10-12 19:34:58.875 25232 INFO tempest_lib.common.rest_client [req-3f1340a7-7403-4647-a0c6-72dd48dc3be2 ] Request (TokensTest:setUpClass): 200 POST http://192.168.1.41:35357/v2.0/users 0.101s
2015-10-12 19:34:58.933 25232 INFO tempest_lib.common.rest_client [req-9c589e86-8900-41b6-a146-9066c4e0747a ] Request (TokensTest:setUpClass): 200 POST http://192.168.1.41:5000/v2.0/tokens
2015-10-12 19:34:58.933 25232 INFO tempest.common.dynamic_creds [-] Acquired dynamic creds:
 credentials: <tempest.common.cred_provider.TestResources object at 0x4275b50>
2015-10-12 19:34:59.005 25232 INFO tempest_lib.common.rest_client [req-13389cda-69cc-4715-a31d-b37aff664a1b ] Request (TokensTest:test_create_token): 200 POST http://192.168.1.41:5000/v2.0/tokens
{0} tempest.api.identity.v2.test_tokens.TokensTest.test_create_token [0.066294s] ... ok
2015-10-12 19:34:59.104 25232 INFO tempest_lib.common.rest_client [req-40b10b8f-9ed6-4d0d-8a6d-0dbcced99be9 ] Request (TokensTest:tearDownClass): 204 DELETE http://192.168.1.41:35357/v2.0/users/8563de609cdb4cefaedd015d4b81fc22 0.096s
2015-10-12 19:34:59.214 25232 INFO tempest_lib.common.rest_client [req-339357d1-cda1-43da-a262-988fd59b9ee7 ] Request (TokensTest:tearDownClass): 204 DELETE http://192.168.1.41:35357/v2.0/tenants/7e9682a47d214c1fb835a2e797c1180a 0.109s
2015-10-12 19:34:59.284 25232 INFO tempest_lib.common.rest_client [req-42f1257e-e569-4264-97d9-2fb781445e36 ] Request (IdentityUsersTest:setUpClass): 200 POST http://192.168.1.41:5000/v2.0/tokens
2015-10-12 19:34:59.355 25232 INFO tempest_lib.common.rest_client [req-4c92adb2-ccba-4dbe-8399-187c4f1a7442 ] Request (IdentityUsersTest:setUpClass): 200 POST http://192.168.1.41:5000/v2.0/tokens
2015-10-12 19:34:59.479 25232 INFO tempest_lib.common.rest_client [req-4a90bcff-efa0-4d2f-998f-13faa38d89fc ] Request (IdentityUsersTest:setUpClass): 200 POST http://192.168.1.41:35357/v2.0/tenants 0.122s
2015-10-12 19:34:59.588 25232 INFO tempest_lib.common.rest_client [req-96b49f45-487e-410e-8665-8a1b5d2e4765 ] Request (IdentityUsersTest:setUpClass): 200 POST http://192.168.1.41:35357/v2.0/users 0.108s
2015-10-12 19:34:59.649 25232 INFO tempest_lib.common.rest_client [req-8ecff15a-2ad5-45aa-83fb-a1aa8fbb30e3 ] Request (IdentityUsersTest:setUpClass): 200 POST http://192.168.1.41:5000/v2.0/tokens
2015-10-12 19:34:59.650 25232 INFO tempest.common.dynamic_creds [-] Acquired dynamic creds:
 credentials: <tempest.common.cred_provider.TestResources object at 0x429ed10>
2015-10-12 19:34:59.721 25232 INFO tempest_lib.common.rest_client [req-6a5bb6c7-b4e3-4ae5-9462-77b2d12e9b12 ] Request (IdentityUsersTest:test_user_update_own_password): 200 POST http://192.168.1.41:5000/v2.0/tokens
2015-10-12 19:34:59.869 25232 INFO tempest_lib.common.rest_client [req-1541e890-39dc-4b39-a340-ef7f5ddef6ab ] Request (IdentityUsersTest:test_user_update_own_password): 200 PATCH http://192.168.1.41:5000/v2.0/OS-KSCRUD/users/e880e2466e0546ff9574f4cd97e1c8e3 0.147s
2015-10-12 19:34:59.916 25232 INFO tempest_lib.common.rest_client [req-46c11beb-b5c9-47d1-bb64-d645842b1a76 ] Request (IdentityUsersTest:test_user_update_own_password): 200 POST http://192.168.1.41:5000/v2.0/tokens
2015-10-12 19:34:59.974 25232 INFO tempest_lib.common.rest_client [req-1af1f1f3-6de8-4bfb-9324-a2480d60916f ] Request (IdentityUsersTest:test_user_update_own_password): 200 POST http://192.168.1.41:5000/v2.0/tokens
2015-10-12 19:34:59.983 25232 INFO tempest_lib.common.rest_client [req-11357d1d-a765-42a0-a060-579599a368e6 ] Request (IdentityUsersTest:test_user_update_own_password): 401 POST http://192.168.1.41:5000/v2.0/tokens
2015-10-12 19:35:00.019 25232 INFO tempest_lib.common.rest_client [req-9c86932e-246d-4d97-a456-cd242bb90bc7 ] Request (IdentityUsersTest:test_user_update_own_password): 401 POST http://192.168.1.41:5000/v2.0/tokens
2015-10-12 19:35:00.077 25232 INFO tempest_lib.common.rest_client [req-f0c904bd-b1c9-4e8f-8f19-ed3b2765d180 ] Request (IdentityUsersTest:_run_cleanups): 200 POST http://192.168.1.41:5000/v2.0/tokens
2015-10-12 19:35:00.226 25232 INFO tempest_lib.common.rest_client [req-1cd1a282-0218-4e24-a691-42951679c282 ] Request (IdentityUsersTest:_run_cleanups): 200 PATCH http://192.168.1.41:5000/v2.0/OS-KSCRUD/users/e880e2466e0546ff9574f4cd97e1c8e3 0.148s
{0} tempest.api.identity.v2.test_users.IdentityUsersTest.test_user_update_own_password [0.570817s] ... ok
2015-10-12 19:35:00.325 25232 INFO tempest_lib.common.rest_client [req-0bf4b9b8-9a45-4eba-b04b-e402b4d09c67 ] Request (IdentityUsersTest:tearDownClass): 204 DELETE http://192.168.1.41:35357/v2.0/users/e880e2466e0546ff9574f4cd97e1c8e3 0.091s
2015-10-12 19:35:00.411 25232 INFO tempest_lib.common.rest_client [req-162ec80b-6e1d-4e45-9e97-a67eb61ad17a ] Request (IdentityUsersTest:tearDownClass): 204 DELETE http://192.168.1.41:35357/v2.0/tenants/01610ed4bc4e4eccb0aea85d5980c40c 0.084s

======
Totals
======
Ran: 10 tests in 11.0000 sec.
 - Passed: 10
 - Skipped: 0
 - Expected Fail: 0
 - Unexpected Success: 0
 - Failed: 0
Sum of execute time for each test: 2.8637 sec.

==============
Worker Balance
==============
 - Worker 0 (10 tests) => 0:00:05.725521

Slowest Tests:

Test id                                                                                                                                              Runtime (s)
---------------------------------------------------------------------------------------------------------------------------------------------------  -----------
tempest.api.identity.v2.test_ec2_credentials.EC2CredentialsTest.test_list_ec2_credentials[id-9e2ea42f-0a4f-468c-a768-51859ce492e0]                   0.631
tempest.api.identity.v2.test_users.IdentityUsersTest.test_user_update_own_password[id-165859c9-277f-4124-9479-a7d1627b0ca7]                          0.571
tempest.api.identity.v2.test_ec2_credentials.EC2CredentialsTest.test_show_ec2_credentials[id-cb284075-b613-440d-83ca-fe0b33b3c2b8]                   0.392
tempest.api.identity.v2.test_ec2_credentials.EC2CredentialsTest.test_delete_ec2_credentials[id-6aba0d4c-b76b-4e46-aa42-add79bc1551d]                 0.389
tempest.api.identity.v2.test_ec2_credentials.EC2CredentialsTest.test_create_ec2_credentials[id-b580fab9-7ae9-46e8-8138-417260cb6f9f]                 0.377
tempest.api.identity.v2.test_tenants.IdentityTenantsTest.test_list_tenants_returns_only_authorized_tenants[id-ecae2459-243d-4ba1-ad02-65f15dc82b78]  0.237
tempest.api.identity.v2.test_api_discovery.TestApiDiscovery.test_api_media_types[id-007a0be0-78fe-4fdb-bbee-e9216cc17bb2,smoke]                      0.104
tempest.api.identity.v2.test_tokens.TokensTest.test_create_token[id-65ae3b78-91ff-467b-a705-f6678863b8ec]                                            0.066
tempest.api.identity.v2.test_api_discovery.TestApiDiscovery.test_api_version_statuses[id-77fd6be0-8801-48e6-b9bf-38cdd2f253ec,smoke]                 0.049
tempest.api.identity.v2.test_api_discovery.TestApiDiscovery.test_api_version_resources[id-ea889a68-a15f-4166-bfb1-c12456eae853,smoke]                0.048
____________________________________________________ summary _____________________________________________________
  all: commands succeeded
  congratulations :)

CentOS7にjenkinsをインストール

必要なパッケージのインストール

次のコマンドを実行して Open JDK 1.7.0 などをインストールする。

yum -y install java-1.7.0-openjdk httpd wget 

jenkinsのリポジトリを追加

wget -O /etc/yum.repos.d/jenkins.repo http://pkg.jenkins-ci.org/redhat/jenkins.repo
rpm --import http://pkg.jenkins-ci.org/redhat/jenkins-ci.org.key

jenkinsをインストール

yum -y install jenkins

設定

HTTP ポートの無効化

デフォルトでは 8080番ポートで Jenkins へアクセスできるようになっているが、インストールしたサーバーには 既に Apache HTTP Server がインストールされており、リバースプロキシを使用して AJP ポートへアクセスするように構成するため、HTTP ポート(8080番)の LISTEN は無効化する。

HTTP ポートを無効にするには、設定ファイル(/etc/sysconfig/jenkins)の JENKINS_PORT に “-1″ を設定する。

## Type:        integer(0:65535)
## Default:     8080
## ServiceRestart: jenkins
#
# Port Jenkins is listening on.
# Set to -1 to disable
#
JENKINS_PORT="-1"

AJP ポートの設定

前項で記述したとおり、AJP ポートへアクセスさせるため、AJP ポートを設定する。

これはデフォルトでも 8009番ポートで設定済みであるが、Tomcat など このポートを利用するアプリケーションサーバーも多いため、8109番ポートへ設定を変更する。デフォルトのまま 8009番ポートを利用することで問題ない場合は、変更の必要はないが、後述のリバースプロキシの設定の際に 説明と異なる設定が必要になるので注意する。

AJP ポートの設定は、設定ファイル(/etc/sysconfig/jenkins)の JENKINS_AJP_PORT に “8109” を設定する。

## Type:        integer(0:65535)
## Default:     8009
## ServiceRestart: jenkins
#
# Ajp13 Port Jenkins is listening on.
# Set to -1 to disable
#
JENKINS_AJP_PORT="8109"

ProcessTreeKillerの無効+Timezoneの設定

## Type: string
## Default:     "-Djava.awt.headless=true"
## ServiceRestart: jenkins
#
# Options to pass to java when running Jenkins.
#
JENKINS_JAVA_OPTIONS="-Djava.awt.headless=true -Dhudson.util.ProcessTree.disable=true -Dorg.apache.commons.jelly.tags.fmt.timeZone=Asia/Tokyo"

コンテキストパスの設定

Jenkins はデフォルトで サーバールート(http://hostname/)でアクセスされるように設定されているが、同じサーバーでほかのアプリケーションや Web サイトを運用するには都合が悪いため、インストールした Jenkins 独自のコンテキストパスを設定する。

コンテキストパスの設定は、設定ファイル(/etc/sysconfig/jenkins)の JENKINS_ARGS に “–prefix=/jenkins” を設定する。

/jenkins の部分は 設定するコンテキストパスにあわせた任意の文字列を設定すればよい。

## Type:        string
## Default:     ""
## ServiceRestart: jenkins
#
# Pass arbitrary arguments to Jenkins.
# Full option list: java -jar jenkins.war --help
#
JENKINS_ARGS="--prefix=/jenkins"

リバースプロキシの設定

最後に Apache HTTP Server にリバースプロキシの設定を行う。リバースプロキシを設定することで、外部からアクセスする入口を一本化できる。

リバースプロキシは /jenkins (前述の「コンテキストパスの設定」で設定したパス)へアクセスがあったリクエストを ajp://localhost:8109/jenkins へ転送するよう設定する。

Jenkins 用の設定ファイルを /etc/httpd/conf.d/ に作成し、設定内容を記述する。

vi /etc/httpd/conf.d/jenkins.conf

ProxyPass           /jenkins ajp://localhost:8109/jenkins nocanon
ProxyPassReverse    /jenkins ajp://localhost:8109/jenkins
ProxyRequests       Off
AllowEncodedSlashes On
<Proxy "ajp://localhost:8109/jenkins">
  Order deny,allow
  Allow from all
</Proxy>

設定ファイルを保存したら 次のコマンドで設定ファイルの構文チェックを行う。”Syntax OK” と表示されたら「構文的に」正しい。エラーが表示される場合は、もう一度 設定を見直す。

service httpd configtest

Jenkins の起動

ここまでの作業が完了すれば Jenkins のインストール および 初期設定は完了である。 次のコマンドで Jenkins および Apache HTTP Server を起動する。

service jenkins start
service httpd start
chkconfig jenkins on
chkconfig httpd on

既に起動中の場合は再起動させ、設定を反映させる。

アクセスできない場合はSELINUXやfirewallの設定を無効化

systemctl stop firewalld
setenforce 0

OpenStack 配備したインスタンスに外部からアクセス

前回のCentOS7にpackstackを使ってallinone構成でkiloをインストールの続き

インスタンスを外部ネットワークとつなげる設定

openvswitchを使うので、ブリッジとIPの設定を追加する。

サービスLAN用のNICを編集

# vi /etc/sysconfig/network-scripts/ifcfg-ens32
UUID=2d8cd29d-6cd1-4aa3-b6ae-d036eff5429f
DEVICE=ens33
TYPE=OVSPort
DEVICETYPE=ovs
OVS_BRIDGE=br-ex
ONBOOT=yes
NM_CONTROLLED=no
IPV6INIT=no                                                                      

ブリッジの設定

# vi /etc/sysconfig/network-scripts/ifcfg-br-ex

DEVICE=br-ex
DEVICETYPE=ovs
TYPE=OVSBridge
BOOTPROTO=static
IPADDR=192.168.1.41
NETMASK=255.255.255.0
GATEWAY=192.168.1.1
DNS=192.168.1.1
ONBOOT=yes
NM_CONTROLLED=no

選択できるネットワークの種別を追加しておく

# vi /etc/neutron/plugins/ml2/ml2_conf.ini

[ml2]
# (ListOpt) List of network type driver entrypoints to be loaded from
# Example: type_drivers = flat,vlan,gre,vxlan
type_drivers = flat,vlan,gre,vxlan

再起動して反映

# systemctl restart network

# ip addr show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN 
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: ens32: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 00:50:56:a9:75:5e brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.41/24 brd 192.168.1.255 scope global ens32
       valid_lft forever preferred_lft forever
    inet6 fe80::250:56ff:fea9:755e/64 scope link 
       valid_lft forever preferred_lft forever
3: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master ovs-system state UP qlen 1000
    link/ether 00:50:56:a9:2b:55 brd ff:ff:ff:ff:ff:ff
    inet6 fe80::250:56ff:fea9:2b55/64 scope link 
       valid_lft forever preferred_lft forever
4: ovs-system: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN 
    link/ether 8a:bc:6a:2b:ee:c3 brd ff:ff:ff:ff:ff:ff
5: br-ex: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN 
    link/ether 00:50:56:a9:2b:55 brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.42/24 brd 192.168.1.255 scope global br-ex
       valid_lft forever preferred_lft forever
    inet6 fe80::98a4:5bff:fe45:f743/64 scope link 
       valid_lft forever preferred_lft forever
6: br-int: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN 
    link/ether c6:7b:18:37:97:4e brd ff:ff:ff:ff:ff:ff
7: br-tun: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN 
    link/ether de:2a:4f:ef:fa:4a brd ff:ff:ff:ff:ff:ff
11: qbr92287c8b-b1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP 
    link/ether ea:33:00:08:a6:9b brd ff:ff:ff:ff:ff:ff
    inet6 fe80::6cc6:52ff:fec5:c3a1/64 scope link 
       valid_lft forever preferred_lft forever
12: qvo92287c8b-b1: <BROADCAST,MULTICAST,PROMISC,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master ovs-system state UP qlen 1000
    link/ether b2:3f:41:cb:01:72 brd ff:ff:ff:ff:ff:ff
    inet6 fe80::b03f:41ff:fecb:172/64 scope link 
       valid_lft forever preferred_lft forever
13: qvb92287c8b-b1: <BROADCAST,MULTICAST,PROMISC,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master qbr92287c8b-b1 state UP qlen 1000
    link/ether ea:33:00:08:a6:9b brd ff:ff:ff:ff:ff:ff
    inet6 fe80::e833:ff:fe08:a69b/64 scope link 
       valid_lft forever preferred_lft forever
14: tap92287c8b-b1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master qbr92287c8b-b1 state UNKNOWN qlen 500
    link/ether fe:16:3e:2e:20:27 brd ff:ff:ff:ff:ff:ff
    inet6 fe80::fc16:3eff:fe2e:2027/64 scope link 
       valid_lft forever preferred_lft forever

外部ネットワークとfloating-ipについて

Openstackでは、内部のインスタンスにアクセスするためにfloating-ipという仕組みを利用します。 AWSでいうところのEIPです。

起動したインスタンスには内部のネットワークIP(172.16.8.10など内部サブネットとして作成したネットワークアドレス)を振って起動します。 ここにアクセスするためのIPとして、グローバルなIPが余っているならそれを動的に割り当てることが可能です。

ですが、自宅にそんなグローバルなIPが有るわけないので、自宅のプライベートなIPアドレス空間(192.168.1.0/24)を割当てます。 192.168.1.101 – 192.168.1.150 までのIPをopenstack用に使うことにします。(ルーターDHCP範囲とはずらすこと)

これを踏まえて、外部につなげるための構成でネットワークを作成します。

最終的には以下の図のような構成になります

f:id:watarisein:20151012005716p:plain

OpenStackでは仮想マシンは「内部ネットワーク」のアドレスを付与し 外部との通信は「フローティングIP」を割り当てます。 「フローティングIP」を割り当てることで外部から通信が可能となります。

①外部ネットワークの作成 Openstackにadminでログインします。 「管理」-「システムパネル」-「ネットワーク」を選択します。 「+ネットワークの作成」をクリックします。 「ネットワークの作成」画面が表示されるので「外部ネットワーク」にチェックを入れて「ネットワークの作成」をクリックします。 作成したネットワーク名をクリックします。 「+サブネットの作成」をクリックします。 外部ネットワークに接続するネットワークアドレス、DHCPプール等を設定します。

②内部ネットワークの作成 「管理」-「システムパネル」-「ネットワーク」を選択します。 「+ネットワークの作成」をクリックします。 「ネットワークの作成」画面が表示されるので「外部ネットワーク」にチェックを入れずに「ネットワークの作成」をクリックします。 作成したネットワーク名をクリックします。 「+サブネットの作成」をクリックします。 内部ネットワークに割り当てるネットワークアドレス、DHCPプール等を設定します。

③ルータの作成 「プロジェクト」-「ネットワーク」-「ルータ」を選択します。 「+ルータの作成」をクリックします。 ルータ名を入力します。 作成したルータ名のアクション列の「ゲートウェイの設定」をクリックします。 「外部ネットワークの設定」で①で作成したネットワークを割り当てます。 ルータ名をクリックします。 「+インターフェースの追加」をクリックします。 サブネットに②で作成した内部ネットワークのサブネットを割り当てます。

ファイアウォールの設定 「プロジェクト」-「コンピュート」-「アクセスとセキュリティ」を選択します。 「default」ルールの「ルールの管理」をクリックします。 「ルールの追加」から「ルール」に「ALLICMP」「受信」「CIDR 0.0.0.0/0」を追加します。 「ルールの追加」から「ルール」に「SSH」「CIDR 0.0.0.0/0」を追加します。

仮想マシンイメージの作成 下記URLからダウンロードします。 http://docs.openstack.org/ja/image-guide/content/ch_obtaining_images.html cirros-0.3.3-x86_64-disk.img 「プロジェクト」-「コンピュート」-「イメージ」を選択します。 「+イメージの作成」をクリックします。 「イメージソース」で「イメージファイル」を選択してローカルに保存した「cirros-0.3.3-x86_64-disk.img 」を 選択してアップロードします。

仮想マシンイメージの起動 「プロジェクト」-「コンピュート」-「イメージ」を選択します。 ⑤でアップロードしたciirosのアクション列から「起動」をクリックします。 インスタンス名、イメージ名「ciiros」を選択します。 ネットワークタブから②の内部ネットワークを選択して「起動」をクリックします。 「プロジェクト」-「コンピュート」-「インスタンス」を選択します。 起動したインスタンスのアクションから「Floating IPの割り当て」を選択します。 IPアドレスの+を選択後「IPの確保」を選択します。 外部ネットワークから接続できるIPが割り当てられました。 sshでcirrosに接続します。

# ssh -i cloud.key cirros@192.168.1.102
The authenticity of host '192.168.1.102 (192.168.1.102)' can't be established.
RSA key fingerprint is aa:4d:69:8c:dd:ba:e0:17:49:c7:78:d6:7a:d3:95:c5.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.1.102' (RSA) to the list of known hosts.

cirrosのローカルIPを確認すると、ちゃんと見えた

$ ifconfig
eth0      Link encap:Ethernet  HWaddr FA:16:3E:2E:20:27  
          inet addr:172.16.8.3  Bcast:172.16.8.255  Mask:255.255.255.0
          inet6 addr: fe80::f816:3eff:fe2e:2027/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1400  Metric:1
          RX packets:178 errors:0 dropped:0 overruns:0 frame:0
          TX packets:186 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:21789 (21.2 KiB)  TX bytes:18842 (18.4 KiB)

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

CentOS7にpackstackを使ってOpenStack(kilo)をallinone構成でインストール

環境

  • OSインストール: 最小構成
  • CPU: 2
  • MEM: 4G
  • Network: enoxxxxx: 192.168.1.41
  • NIC: ens31 ens32

手順

まずはSELinuxの無効化

# vi /etc/selinux/config

SELINUX=disabled

ホスト名の変更

# vi /etc/hostname

kilo

パッケージをアップグレードして再起動

# yum upgrade
# reboot

NetworkManagerの停止と無効化:

# systemctl stop NetworkManager
# systemctl disable NetworkManager
# systemctl restart network
# systemctl enable network

カーネルパラメータの設定: この設定を書き込み、後述のコマンドで反映させます。

# vi /usr/lib/sysctl.d/00-system.conf

net.ipv4.ip_forward = 1
net.ipv4.conf.default.rp_filter = 0
net.ipv4.conf.all.rp_filter = 0
net.ipv4.conf.all.forwarding = 1

設定を反映

# sysctl -e -p /usr/lib/sysctl.d/00-system.conf

ホスト名の設定:

# hostnamectl set-hostname kilo

hostnameに設定したホスト名を、hostsファイルの管理LANとするエントリーに追加します。

# vi /etc/hosts

192.168.1.41  kilo

ソフトウェアパッケージのインストールとアップデートを行います。

次のコマンドを実行してリポジトリーを有効化:

# yum install -y http://rdoproject.org/repos/openstack-kilo/rdo-release-kilo.rpm

インストール

# yum install -y openstack-packstack

インストール項目の各種設定を記述するアンサーファイルの生成

# packstack --gen-answer-file=packstack-answer.txt
Packstack changed given value  to required value /root/.ssh/id_rsa.pub

アンサーファイルを編集、必要なパラメータの説明

CONFIG_COMPUTE_HOSTS=computeのプライベートIP,computeのプライベートIP,・・・
CONFIG_NETWORK_HOSTS=controllerのプライベートIP
CONFIG_STORAGE_HOST=controllerのプライベートIP
CONFIG_AMQP_HOST=controllerのプライベートIP
CONFIG_MARIADB_HOST=controllerのプライベートIP
CONFIG_NOVA_COMPUTE_PRIVIF=computeのプライベート側インターフェイス
CONFIG_NOVA_NETWORK_PUBIF=controllerのパブリック側インターフェイス
CONFIG_NOVA_NETWORK_PRIVIF=controllerのパブリック側インターフェイス
CONFIG_NOVA_NETWORK_FLOATRANGE=FloatingIPのネットワーク

編集箇所のみ抜粋

# vi packstack-answer.txt

CONFIG_DEFAULT_PASSWORD=password
CONFIG_HEAT_INSTALL=y

# Specify 'y' to provision for demo usage and testing. ['y', 'n']
CONFIG_PROVISION_DEMO=n

# Private interface for flat DHCP on the Compute servers.
CONFIG_NOVA_COMPUTE_PRIVIF=ens32

# Public interface on the Compute network server.
CONFIG_NOVA_NETWORK_PUBIF=ens31

# Private interface for flat DHCP on the Compute network server.
CONFIG_NOVA_NETWORK_PRIVIF=ens32

packstackの実行

# packstack --answer-file=packstack-answer.txt

無事インストールできたか確認するために、ブラウザで設定したアドレスにアクセスしてみる。 http://IPアドレスにアクセスしてopenstackの画面が表示されればOK

adminのパスワードを変更する

# source keystonerc_admin
# keystone user-password-update --pass admin_password admin
/usr/lib/python2.7/site-packages/keystoneclient/shell.py:65: DeprecationWarning: The keystone CLI is deprecated in favor of python-openstackclient. For a Python library, continue using python-keystoneclient.

'python-keystoneclient.', DeprecationWarning)

これで、ブラウザからadmin/admin_passwordでログインできる また、keystonerc_adminのadminパスワードも変更しておく

# vi keystonerc_admin

export OS_PASSWORD=admin_password

# source keystonerc_admin
# keystone endpoint-list

# keystone endpoint-list
/usr/lib/python2.7/site-packages/keystoneclient/shell.py:65: DeprecationWarning: The keystone CLI is deprecated in favor of python-openstackclient. For a Python library, continue using python-keystoneclient. 'python-keystoneclient.', DeprecationWarning)
+----------------------------------+-----------+------------------------------------------------+------------------------------------------------+-------------------------------------------+----------------------------------+
|                id                |   region  |                   publicurl                    |                  internalurl                   |                  adminurl                 |            service_id            |
+----------------------------------+-----------+------------------------------------------------+------------------------------------------------+-------------------------------------------+----------------------------------+
| 0187637acafd46b694e8988974761431 | RegionOne |         http://192.168.1.41:5000/v2.0          |         http://192.168.1.41:5000/v2.0          |       http://192.168.1.41:35357/v2.0      | 7eeba5890c2b41a18b86ac8dd0050e83 |
| 13235f0159b94ac9bbfde6bfc9812991 | RegionOne |   http://192.168.1.41:8776/v2/%(tenant_id)s    |   http://192.168.1.41:8776/v2/%(tenant_id)s    | http://192.168.1.41:8776/v2/%(tenant_id)s | 0a517ebe5a1f4747ac35d06e32742919 |
| 1848dfe55c1f4921acbf541a8787e045 | RegionOne | http://192.168.1.41:8080/v1/AUTH_%(tenant_id)s | http://192.168.1.41:8080/v1/AUTH_%(tenant_id)s |          http://192.168.1.41:8080         | cddfe34f22db4c4eb735f87ebd9fb924 |
| 20b3dcfca74c49c2af68aeaaa9c921a8 | RegionOne |   http://192.168.1.41:8776/v1/%(tenant_id)s    |   http://192.168.1.41:8776/v1/%(tenant_id)s    | http://192.168.1.41:8776/v1/%(tenant_id)s | 9fec70711f0a47ab9cb4bf4ff2796baf |
| 5427fe98d31345d3ac0fd63793b9150d | RegionOne |    http://192.168.1.41:8773/services/Cloud     |    http://192.168.1.41:8773/services/Cloud     |  http://192.168.1.41:8773/services/Admin  | e9cdda11f0634271bea157ab791ade84 |
| 9a67f62cd7044be284105b2b3c54e446 | RegionOne |   http://192.168.1.41:8774/v2/%(tenant_id)s    |   http://192.168.1.41:8774/v2/%(tenant_id)s    | http://192.168.1.41:8774/v2/%(tenant_id)s | 0c0346820ed24b12ab24efc26c478264 |
| ac175564d18047c3bc716d55dda35c7a | RegionOne |            http://127.0.0.1:8774/v3            |            http://127.0.0.1:8774/v3            |          http://127.0.0.1:8774/v3         | 66e76be021a44e6aa406e4ffb4b92b71 |
| d20c078a72624cbc8ca16c986fff4533 | RegionOne |            http://192.168.1.41:8777            |            http://192.168.1.41:8777            |          http://192.168.1.41:8777         | e9d24b1226254a61bb61226efeb24299 |
| e4f89d63a5ed475082739c60de55e86f | RegionOne |            http://192.168.1.41:8080            |            http://192.168.1.41:8080            |          http://192.168.1.41:8080         | b6b2d4e714b2453e985542917314dc51 |
| fa14a7f21f0241ca82f60bb6332d4f20 | RegionOne |            http://192.168.1.41:9292            |            http://192.168.1.41:9292            |          http://192.168.1.41:9292         | 091ceecf404b4b8ca5faf932bda69cf0 |
| fc330c445a8d4c01ac26a5ffd2c3a4c5 | RegionOne |            http://192.168.1.41:9696            |            http://192.168.1.41:9696            |          http://192.168.1.41:9696         | da6b0eb1215f4100bee3ef26717582ab |
+----------------------------------+-----------+------------------------------------------------+------------------------------------------------+-------------------------------------------+----------------------------------+

次は、配備したインスタンスにアクセスする方法

RHEL6.6にJenkinsをインストール

環境

  • RHEL 6.6 基本サーバーでインストール
  • CPU 4
  • Mem 6GB

IPはインストール中に設定。

iptablesselinuxは無効にすること

iptables無効化

# service iptables stop
# chkconfig iptables off

selinux無効化

# vi /etc/selinux/config
enforcing -> disabled

構築手順

CentOSリポジトリ追加

# vi /etc/yum.repos.d/CentOS.repo

[base]
name=CentOS-6.1 - Base
mirrorlist=http://mirrorlist.centos.org/?release=6&arch=$basearch&repo=os
#baseurl=http://mirror.centos.org/centos/$releasever/os/$basearch/
gpgcheck=1
gpgkey=http://mirror.centos.org/centos/RPM-GPG-KEY-CentOS-6

[updates]
name=CentOS-6.1 - Updates
mirrorlist=http://mirrorlist.centos.org/?release=6&arch=$basearch&repo=updates
#baseurl=http://mirror.centos.org/centos/$releasever/updates/$basearch/
gpgcheck=1
gpgkey=http://mirror.centos.org/centos/RPM-GPG-KEY-CentOS-6

[extras]
name=CentOS-6.1 - Extras
mirrorlist=http://mirrorlist.centos.org/?release=6&arch=$basearch&repo=extras
#baseurl=http://mirror.centos.org/centos/$releasever/extras/$basearch/
gpgcheck=1
gpgkey=http://mirror.centos.org/centos/RPM-GPG-KEY-CentOS-6

パッケージ導入

# yum update
# yum install java-1.7.0-openjdk
# jenkinsリポジトリ追加
# wget -O /etc/yum.repos.d/jenkins.repo http://pkg.jenkins-ci.org/redhat/jenkins.repo
# rpm --import http://pkg.jenkins-ci.org/redhat/jenkins-ci.org.key
# yum install httpd jenkins

jenkins設定ファイルを以下のように編集する

[root@jerry ~]# diff -u /etc/sysconfig/jenkins jenkins
--- /etc/sysconfig/jenkins      2015-09-07 16:01:20.000000000 +0900
+++ jenkins     2015-09-09 19:42:44.048979191 +0900
@@ -44,7 +44,9 @@
 #
 # Options to pass to java when running Jenkins.
 #
-JENKINS_JAVA_OPTIONS="-Djava.awt.headless=true"
+#JENKINS_JAVA_OPTIONS="-Djava.awt.headless=true"
+JENKINS_JAVA_OPTIONS="-Djava.awt.headless=true -Dhudson.util.ProcessTree.disable=true"
+

 ## Type:        integer(0:65535)
 ## Default:     8080
@@ -53,7 +55,8 @@
 # Port Jenkins is listening on.
 # Set to -1 to disable
 #
-JENKINS_PORT="8080"
+#JENKINS_PORT="8008"
+JENKINS_PORT="-1"

 ## Type:        string
 ## Default:     ""
@@ -107,7 +110,7 @@
 # Ajp13 Port Jenkins is listening on.
 # Set to -1 to disable
 #
-JENKINS_AJP_PORT="8009"
+JENKINS_AJP_PORT="8109"

 ## Type:        string
 ## Default:     ""
@@ -158,4 +161,5 @@
 # Pass arbitrary arguments to Jenkins.
 # Full option list: java -jar jenkins.war --help
 #
-JENKINS_ARGS=""
+#JENKINS_ARGS=""
+JENKINS_ARGS="--prefix=/jenkins"

httpdの設定ファイルを以下のように編集

# vi /etc/httpd/conf.d/jenkins.conf

ProxyPass           /jenkins ajp://localhost:8109/jenkins nocanon
ProxyPassReverse    /jenkins ajp://localhost:8109/jenkins
ProxyRequests       Off
AllowEncodedSlashes On
<Proxy "ajp://localhost:8109/jenkins">
  Order deny,allow
  Allow from all
</Proxy>

サービス起動

# /etc/init.d/httpd start
# /etc/init.d/jenkins start
# chkconfig jenkins on
# chkconfig httpd on

ブラウザでhttp://[IP address]/jenkinsでアクセスできる。

proxy設定

Jenkinsトップ -> Jenkinsの管理 -> プラグインの管理 -> 高度な設定

key value
サーバー proxy server
ポート番号 port number
ユーザー名 hogehoge
パスワード hogehoge

参考URL http://ymasuda.com/blog/install-jenkins-to-linux/