otto devで使用されるVagrantのboxファイルを変更する
先日HashiCorp社の新プロダクト、ottoがリリースされました。
Vagrant の後継ツールという位置付けであるということで、Vagrant 好きの自分はすぐに飛びついてみます。
otto のインストール
まずは otto をインストールしましょう。
とはいえ otto もワンバイナリのツールであるため、ダウンロードしてきたモジュールをパスの通った場所に保存すれば全て完了です。
$ sudo mv otto /usr/local/bin/
$ otto
usage: otto [--version] [--help] <command> [<args>]
Available commands are:
build Build the deployable artifact for the app
compile Prepares your project for being run.
deploy Deploy the application
dev Start and manage a development environment
infra Builds the infrastructure for the Appfile
status Status of the stages of this application
version Prints the Otto version
何調べるん?
基本の使い方などはすでにいくつか記事があがっておりましたので割愛するとして、今回は otto dev された時に利用されるboxファイルの変更方法を調べてみました。
まずは環境の準備です。
$ git clone https://github.com/hashicorp/otto-getting-started.git
Cloning into 'otto-getting-started'...
remote: Counting objects: 23, done.
remote: Total 23 (delta 0), reused 0 (delta 0), pack-reused 23
Unpacking objects: 100% (23/23), done.
Checking connectivity... done.
次に otto compile で.ottoディレクトリを作成しましょう。
ここまではサンプルの実行手順と同じですね。
$ cd otto-getting-started
$ otto compile
==> Loading Appfile...
==> No Appfile found! Detecting project information...
No Appfile was found. If there is no Appfile, Otto will do its best
to detect the type of application this is and set reasonable defaults.
This is a good way to get started with Otto, but over time we recommend
writing a real Appfile since this will allow more complex customizations,
the ability to reference dependencies, versioning, and more.
==> Fetching all Appfile dependencies...
==> Compiling...
Application: otto-getting-started (ruby)
Project: otto-getting-started
Infrastructure: aws (simple)
Compiling infra...
Compiling foundation: consul
==> Compiling main application...
==> Compilation success!
This means that Otto is now ready to start a development environment,
deploy this application, build the supporting infastructure, and
more. See the help for more information.
Supporting files to enable Otto to manage your application from
development to deployment have been placed in the output directory.
These files can be manually inspected to determine what Otto will do.
作成した.ottoディレクトリの中身はこのような構成になっています。
$ tree .otto/
.otto/
├── appfile
│ ├── Appfile.compiled
│ └── version
├── compiled
│ ├── app
│ │ ├── build
│ │ │ ├── build-ruby.sh
│ │ │ └── template.json
│ │ ├── deploy
│ │ │ └── main.tf
│ │ ├── dev
│ │ │ └── Vagrantfile
│ │ └── foundation-consul
│ │ ├── app-build
│ │ │ ├── main.sh
│ │ │ └── upstart.conf
│ │ ├── app-deploy
│ │ │ └── main.sh
│ │ ├── app-dev
│ │ │ ├── main.sh
│ │ │ └── upstart.conf
│ │ ├── app-dev-dep
│ │ │ └── main.sh
│ │ └── deploy
│ │ ├── main.tf
│ │ ├── module-aws
│ │ │ ├── join.sh
│ │ │ ├── main.tf
│ │ │ ├── outputs.tf
│ │ │ └── variables.tf
│ │ ├── module-aws-simple
│ │ │ ├── main.tf
│ │ │ ├── outputs.tf
│ │ │ ├── setup.sh
│ │ │ └── variables.tf
│ │ └── variables.tf
│ ├── foundation-consul
│ │ ├── app-build
│ │ │ ├── main.sh
│ │ │ └── upstart.conf
│ │ ├── app-deploy
│ │ │ └── main.sh
│ │ ├── app-dev
│ │ │ ├── main.sh
│ │ │ └── upstart.conf
│ │ ├── app-dev-dep
│ │ │ └── main.sh
│ │ └── deploy
│ │ ├── main.tf
│ │ ├── module-aws
│ │ │ ├── join.sh
│ │ │ ├── main.tf
│ │ │ ├── outputs.tf
│ │ │ └── variables.tf
│ │ ├── module-aws-simple
│ │ │ ├── main.tf
│ │ │ ├── outputs.tf
│ │ │ ├── setup.sh
│ │ │ └── variables.tf
│ │ └── variables.tf
│ └── infra-otto-getting-started
│ ├── main.tf
│ └── outputs.tf
└── data
└── dev_ip
24 directories, 41 files
Vagrant の後継ツールとは言われていますが、Vagrant + Packer + Consul + Terraform = ottoという感じですね。
そもそも後継ツールとか言っちゃうのが誤訳なのかも。
今回の主題である Vagrantfile は .otto/compiled/app/dev/Vagrantfile に保存されているようです。
boxファイルを変更
まずはローカルに保存済みのboxファイルの一覧を確認します。
$ vagrant box list
CentOS-7.1.1503-x86_64 (virtualbox, 0)
今回は CentOS7 の box を利用しましょう。
※これが裏目に出ます。
$ vim .otto/compiled/app/dev/Vagrantfile
# Generated by Otto, do not edit!
#
# This is the Vagrantfile generated by Otto for the development of
# this application/service. It should not be hand-edited. To modify the
# Vagrantfile, use the Appfile.
Vagrant.configure("2") do |config|
config.vm.box = "CentOS-7.1.1503-x86_64" ←変更
[snip]
それでは otto dev します。
$ otto dev
==> Creating local development environment with Vagrant if it doesn't exist...
Raw Vagrant output will begin streaming in below. Otto does
not create this output. It is mirrored directly from Vagrant
while the development environment is being created.
Bringing machine 'default' up with 'virtualbox' provider...
==> default: Importing base box 'CentOS-7.1.1503-x86_64'...
==> default: Matching MAC address for NAT networking...
==> default: Setting the name of the VM: dev_default_1444157288651_95865
==> default: Clearing any previously set forwarded ports...
==> default: Clearing any previously set network interfaces...
==> default: Preparing network interfaces based on configuration...
default: Adapter 1: nat
default: Adapter 2: hostonly
==> default: Forwarding ports...
default: 22 => 2222 (adapter 1)
==> default: Booting VM...
==> default: Waiting for machine to boot. This may take a few minutes...
default: SSH address: 127.0.0.1:2222
default: SSH username: vagrant
default: SSH auth method: private key
default: Warning: Connection timeout. Retrying...
default:
default: Vagrant insecure key detected. Vagrant will automatically replace
default: this with a newly generated keypair for better security.
default:
default: Inserting generated public key within guest...
default: Removing insecure key from the guest if it's present...
default: Key inserted! Disconnecting and reconnecting using new SSH key...
==> default: Machine booted and ready!
==> default: Checking for guest additions in VM...
==> default: Configuring and enabling network interfaces...
==> default: Mounting shared folders...
default: /vagrant => /Users/demiglacesource/Develop/repository/otto-getting-started
default: /otto/foundation-1 => /Users/demiglacesource/Develop/repository/otto-getting-started/.otto/compiled/app/foundation-consul/app-dev
==> default: Running provisioner: shell...
default: Running: inline script
==> default: [otto] Installing Consul...
==> default: [otto] Installing dnsmasq for Consul...
==> default: [otto] Configuring consul service: otto-getting-started
==> default: Running provisioner: shell...
default: Running: inline script
==> default: [otto] Adding apt repositories and updating...
==> default: ERROR at /tmp/vagrant-shell:12; Last logs:
==> default: grep: /var/log/syslog: No such file or directory
The SSH command responded with a non-zero exit status. Vagrant
assumes that this means the command failed. The output for this command
should be in the log above. Please read the output to determine what
went wrong.
Error building dev environment: Error executing Vagrant: exit status 1
The error messages from Vagrant are usually very informative.
Please read it carefully and fix any issues it mentions. If
the message isn't clear, please report this to the Otto project.
Error !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
原因調査
恐る恐るエラーになったスクリプトの中を覗いてみます。
$ vim .otto/compiled/app/foundation-consul/app-dev/main.sh
#!/bin/bash
set -e
oe() { $@ 2>&1 | logger -t otto > /dev/null; }
ol() { echo "[otto] $@"; }
dir=$(pwd)
# Download and setup Consul directories
if ! command -v consul >/dev/null 2>&1; then
ol "Installing Consul..."
oe sudo apt-get update -y ←あれ????
oe sudo apt-get install -y unzip ←あれ????
[snip]
これ apt-get !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
※今回 OS は CentOS をつこてる
パッチ
ダメ元で apt-get を yum に全置換してみた。ついでに unzip だけじゃなくて wget もインストールしておくように変更。
あとよくよく見るとスクリプトだけではなくVagrantfileにもapt-getが・・・
最終的にVagrantfileはこんな感じに修正。(だいぶ雑)
# Generated by Otto, do not edit!
#
# This is the Vagrantfile generated by Otto for the development of
# this application/service. It should not be hand-edited. To modify the
# Vagrantfile, use the Appfile.
Vagrant.configure("2") do |config|
config.vm.box = "CentOS-7.1.1503-x86_64"
# Host only network
config.vm.network "private_network", ip: "172.16.1.202"
# Setup a synced folder from our working directory to /vagrant
config.vm.synced_folder '/Users/akio/Develop/repository/otto-getting-started', "/vagrant",
owner: "vagrant", group: "vagrant"
# Enable SSH agent forwarding so getting private dependencies works
config.ssh.forward_agent = true
# Foundation configuration (if any)
dir = "/otto/foundation-1"
config.vm.synced_folder '/Users/akio/Develop/repository/otto-getting-started/.otto/compiled/app/foundation-consul/app-dev', dir
config.vm.provision "shell", inline: "cd #{dir} && bash #{dir}/main.sh"
# Load all our fragments here for any dependencies.
# Install Ruby build environment
config.vm.provision "shell", inline: $script_ruby
end
$script_ruby = <<SCRIPT
set -o nounset -o errexit -o pipefail -o errtrace
error() {
local sourcefile=$1
local lineno=$2
echo "ERROR at ${sourcefile}:${lineno}; Last logs:"
grep otto /var/log/syslog | tail -n 20
}
trap 'error "${BASH_SOURCE}" "${LINENO}"' ERR
# otto-exec: execute command with output logged but not displayed
oe() { $@ 2>&1 | logger -t otto > /dev/null; }
# otto-log: output a prefixed message
ol() { echo "[otto] $@"; }
# Make it so that `vagrant ssh` goes directly to the correct dir
echo "cd /vagrant" >> /home/vagrant/.bashrc
# Configuring SSH for faster login
if ! grep "UseDNS no" /etc/ssh/sshd_config >/dev/null; then
echo "UseDNS no" | sudo tee -a /etc/ssh/sshd_config >/dev/null
oe sudo service ssh restart
fi
export DEBIAN_FRONTEND=noninteractive
ol "Adding apt repositories and updating..."
oe sudo yum update
oe sudo yum install -y epel-release
# TODO: parameterize ruby version as input
export RUBY_VERSION="2.2"
ol "Installing Ruby ${RUBY_VERSION} and supporting packages..."
export DEBIAN_FRONTEND=noninteractive
oe sudo yum install -y bzr git mercurial \
nodejs \
ruby ruby-devel
ol "Installing Bundler..."
oe gem install bundler --no-ri --no-rdoc
ol "Configuring Git to use SSH instead of HTTP so we can agent-forward private repo auth..."
oe git config --global url."git@github.com:".insteadOf "https://github.com/"
SCRIPT
リトライ
まずは otto dev destroy で作った環境を飛ばす。
$ otto dev destroy
==> Destroying the local development environment...
==> default: Forcing shutdown of VM...
==> default: Destroying VM and associated drives...
==> default: Running cleanup tasks for 'shell' provisioner...
==> default: Running cleanup tasks for 'shell' provisioner...
==> Deleting development environment metadata...
==> Development environment has been destroyed!
では、再構築。
$ otto dev
==> Creating local development environment with Vagrant if it doesn't exist...
Raw Vagrant output will begin streaming in below. Otto does
not create this output. It is mirrored directly from Vagrant
while the development environment is being created.
Bringing machine 'default' up with 'virtualbox' provider...
==> default: Importing base box 'CentOS-7.1.1503-x86_64'...
==> default: Matching MAC address for NAT networking...
==> default: Setting the name of the VM: dev_default_1444159206592_75592
==> default: Clearing any previously set forwarded ports...
==> default: Clearing any previously set network interfaces...
==> default: Preparing network interfaces based on configuration...
default: Adapter 1: nat
default: Adapter 2: hostonly
==> default: Forwarding ports...
default: 22 => 2222 (adapter 1)
==> default: Booting VM...
==> default: Waiting for machine to boot. This may take a few minutes...
default: SSH address: 127.0.0.1:2222
default: SSH username: vagrant
default: SSH auth method: private key
default: Warning: Connection timeout. Retrying...
default:
default: Vagrant insecure key detected. Vagrant will automatically replace
default: this with a newly generated keypair for better security.
default:
default: Inserting generated public key within guest...
default: Removing insecure key from the guest if it's present...
default: Key inserted! Disconnecting and reconnecting using new SSH key...
==> default: Machine booted and ready!
==> default: Checking for guest additions in VM...
==> default: Configuring and enabling network interfaces...
==> default: Mounting shared folders...
default: /vagrant => /Users/demiglacesource/Develop/repository/otto-getting-started
default: /otto/foundation-1 => /Users/demiglacesource/Develop/repository/otto-getting-started/.otto/compiled/app/foundation-consul/app-dev
==> default: Running provisioner: shell...
default: Running: inline script
==> default: [otto] Installing Consul...
==> default: [otto] Installing dnsmasq for Consul...
==> default: [otto] Configuring consul service: otto-getting-started
==> default: Running provisioner: shell...
default: Running: inline script
==> default: [otto] Adding apt repositories and updating...
==> default: [otto] Installing Ruby 2.2 and supporting packages...
==> default: [otto] Installing Bundler...
==> default: [otto] Configuring Git to use SSH instead of HTTP so we can agent-forward private repo auth...
==> Caching SSH credentials from Vagrant...
==> Development environment successfully created!
IP address: 172.16.1.202
A development environment has been created for writing a generic
Ruby-based app.
Ruby is pre-installed. To work on your project, edit files locally on your
own machine. The file changes will be synced to the development environment.
When you're ready to build your project, run 'otto dev ssh' to enter
the development environment. You'll be placed directly into the working
directory where you can run 'bundle' and 'ruby' as you normally would.
You can access any running web application using the IP above.
どうやら成功したようです。
動作確認
環境を確認してみます。
$ otto dev ssh
==> Executing SSH. This may take a few seconds...
Welcome to your Vagrant-built virtual machine.
$ cat /etc/redhat-release
CentOS Linux release 7.1.1503 (Core)
CentOS7が起動していますね。
次にサンプルを実行する前にfirewalldを無効化します。
$ sudo systemctl stop firewalld
それではサンプルを実行してみましょう。
$ bundle && rackup --host 0.0.0.0
Fetching gem metadata from https://rubygems.org/..........
Fetching version metadata from https://rubygems.org/..
Installing rack 1.6.4
Installing rack-protection 1.5.3
Installing tilt 2.0.1
Installing sinatra 1.4.6
Using bundler 1.10.6
Bundle complete! 1 Gemfile dependency, 5 gems now installed.
Use `bundle show [gemname]` to see where a bundled gem is installed.
[2015-10-07 15:00:44] INFO WEBrick 1.3.1
[2015-10-07 15:00:44] INFO ruby 2.0.0 (2014-11-13) [x86_64-linux]
[2015-10-07 15:00:44] INFO WEBrick::HTTPServer#start: pid=22388 port=9292
この状態でブラウザから http://172.16.1.202:9292 にアクセスすると、サンプルアプリが表示されました。
アドレスがわからなければ otto dev address で確認することができます。
結論
boxファイルの変更はなんとかできる。
ただし otto が自動生成するスクリプト類が Ubuntu ( Debian もセーフかも?) 前提になっているので CentOS のboxファイルを使うようにすると内部で vagrant up されたときに死ぬ。
そういえば otto compile し直すと変更した内容が全部飛ぶので注意。
そもそもottoの思想的に環境の準備はottoが面倒見ますってスタンスなので、あまりこの辺りの設定はいじるべきではないのかな?
ただ本番にデプロイする時にUbuntuを使う勇気がない自分はどうすれば・・・
バージョンアップに期待。笑