Tech Trier Blog

エンジニアとして「好奇心」のおもくまま、いろいろやったり調べたりするブログです。

【otto dev】 Ottoを試して理解する(その3)

otto dev を実行すると、以下のことを完全に自動でやってくれます。

  • 開発環境の起動とプロビジョニング
    • base boxをダウンロード
    • 必要なインストールを行う
      • 紹介された例だと、Rubyと5つのgem
    • VMのIP設定を行い、再起動

ログはこんな感じ。

otto dev
==> Creating development environment layers...
    Otto uses layers to speed up building development environments.
    Each layer only needs to be built once. We've detected that the
    layers below aren't created yet. These will be built this time.
    Future development envirionments will use the cached versions
    to be much, much faster.
==> Creating layer: consul
Bringing machine 'default' up with 'virtualbox' provider...
==> default: Preparing master VM for linked clones...
    default: This is a one time operation. Once the master VM is prepared,
    default: it will be used as a base for linked clones, making the creation
    default: of new VMs take milliseconds on a modern system.
==> default: Importing base box 'hashicorp/precise64'...
==> default: Cloning VM...
==> default: Matching MAC address for NAT networking...
==> default: Setting the name of the VM: consul_default_1452961743420_68343
==> default: Fixed port collision for 22 => 2222. Now on port 2200.
==> default: Clearing any previously set network interfaces...
==> default: Preparing network interfaces based on configuration...
    default: Adapter 1: nat
==> default: Forwarding ports...
    default: 22 (guest) => 2200 (host) (adapter 1)
==> default: Booting VM...
==> default: Waiting for machine to boot. This may take a few minutes...
    default: SSH address: 127.0.0.1:2200
    default: SSH username: vagrant
    default: SSH auth method: private key
    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: The guest additions on this VM do not match the installed version of
    default: VirtualBox! In most cases this is fine, but in rare cases it can
    default: prevent things such as shared folders from working properly. If you see
    default: shared folder errors, please make sure the guest additions within the
    default: virtual machine match the version of VirtualBox you have installed on
    default: your host and reload your VM.
    default:
    default: Guest Additions Version: 4.2.0
    default: VirtualBox Version: 5.0
==> default: Mounting shared folders...
    default: /otto/foundation-layer-consul => C:/Users/u1bell/otto/FistTry/otto-getting-started/.otto/compiled/app/foundation-consul/app-dev
==> default: Running provisioner: shell...
    default: Running: inline script
==> default: stdin: is not a tty
==> default: Running provisioner: file...
==> default: Running provisioner: shell...
    default: Running: inline script
==> default: stdin: is not a tty
==> default: Running provisioner: file...
==> default: Running provisioner: shell...
    default: Running: inline script
==> default: stdin: is not a tty
==> default: Running provisioner: shell...
    default: Running: inline script
==> default: stdin: is not a tty
==> default: [otto] Installing Consul...
==> default: [otto] Installing dnsmasq for Consul...
==> default: Attempting graceful shutdown of VM...
==> Creating layer: ruby2.2
Bringing machine 'default' up with 'virtualbox' provider...
==> default: Cloning VM...
==> default: Setting the name of the VM: ruby22_default_1452962008313_90766
==> default: Clearing any previously set forwarded ports...
==> default: Fixed port collision for 22 => 2222. Now on port 2200.
==> default: Clearing any previously set network interfaces...
==> default: Preparing network interfaces based on configuration...
    default: Adapter 1: nat
==> default: Forwarding ports...
    default: 22 (guest) => 2200 (host) (adapter 1)
==> default: Booting VM...
==> default: Waiting for machine to boot. This may take a few minutes...
    default: SSH address: 127.0.0.1:2200
    default: SSH username: vagrant
    default: SSH auth method: private key
    default: Warning: Remote connection disconnect. Retrying...
==> default: Machine booted and ready!
==> default: Checking for guest additions in VM...
    default: The guest additions on this VM do not match the installed version of
    default: VirtualBox! In most cases this is fine, but in rare cases it can
    default: prevent things such as shared folders from working properly. If you see
    default: shared folder errors, please make sure the guest additions within the
    default: virtual machine match the version of VirtualBox you have installed on
    default: your host and reload your VM.
    default:
    default: Guest Additions Version: 4.2.0
    default: VirtualBox Version: 5.0
==> default: Running provisioner: shell...
    default: Running: inline script
==> default: stdin: is not a tty
==> default: Running provisioner: file...
==> default: Running provisioner: shell...
==> default: [otto] Setting locale to en_US.UTF-8...
==> default: Running provisioner: shell...
    default: Running: inline script
==> default: [otto] Updating apt...
==> default: [otto] Installing supporting packages...
==> default: [otto] Installing Ruby 2.2. This can take a few minutes...
==> default: [otto] Installing Bundler...
==> default: [otto] Configuring Git to use SSH instead of HTTP so we can agent-forward private repo auth...
==> default: Attempting graceful shutdown of VM...
==> Creating local development environment with Vagrant if it doesn't exist...
Bringing machine 'default' up with 'virtualbox' provider...
==> default: Cloning VM...
==> default: Setting the name of the VM: dev_default_1452962774521_16824
==> default: Clearing any previously set forwarded ports...
==> default: Fixed port collision for 22 => 2222. Now on port 2200.
==> 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 (guest) => 2200 (host) (adapter 1)
==> default: Booting VM...
==> default: Waiting for machine to boot. This may take a few minutes...
    default: SSH address: 127.0.0.1:2200
    default: SSH username: vagrant
    default: SSH auth method: private key
==> default: Machine booted and ready!
==> default: Checking for guest additions in VM...
    default: The guest additions on this VM do not match the installed version of
    default: VirtualBox! In most cases this is fine, but in rare cases it can
    default: prevent things such as shared folders from working properly. If you see
    default: shared folder errors, please make sure the guest additions within the
    default: virtual machine match the version of VirtualBox you have installed on
    default: your host and reload your VM.
    default:
    default: Guest Additions Version: 4.2.0
    default: VirtualBox Version: 5.0
==> default: Configuring and enabling network interfaces...
==> default: Mounting shared folders...
    default: /vagrant => C:/Users/u1bell/otto/FistTry/otto-getting-started
    default: /otto/foundation-1 => C:/Users/u1bell/otto/FistTry/otto-getting-started/.otto/compiled/app/foundation-consul/app-dev
==> default: Running provisioner: shell...
    default: Running: inline script
==> default: stdin: is not a tty
==> default: [otto] Configuring consul service: otto-getting-started
==> default: Running provisioner: shell...
    default: Running: inline script
==> default: stdin: is not a tty
==> default: Running provisioner: file...
==> default: Running provisioner: shell...
    default: Running: inline script
==> default: stdin: is not a tty
==> default: Running provisioner: file...
==> default: Running provisioner: shell...
==> default: [otto] Bundling gem dependencies...
==> default: Fetching gem metadata from https://rubygems.org/
==> default: Fetching version metadata from https://rubygems.org/
==> default: Installing rack 1.6.4
==> default: Installing tilt 2.0.1
==> default: Using bundler 1.11.2
==> default: Installing rack-protection 1.5.3
==> default: Installing sinatra 1.4.6
==> default: Bundle complete! 1 Gemfile dependency, 5 gems now installed.
==> default: Use `bundle show [gemname]` to see where a bundled gem is installed.
==> Caching SSH credentials from Vagrant...
==> Development environment successfully created!
    IP address: x.x.x.x

    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.

指定されたIPに、TeraTermでログイン。(Portは22です。)

bundle && rackup --host 0.0.0.0

ブラウザで指定されたIP:9292にアクセスしてみます。

f:id:u1bell:20160117182656p:plain

おお、Vagrantfileを一切書かず、yumやgemコマンドを一回も打ったり書いたりせずに、アプリが起動できる開発環境が整いました!

自動生成されたVagrantfileをのぞいてみた

  # ScriptPacks
  dir = "/otto/scriptpacks"
  config.vm.provision "shell", inline: "sudo rm -rf #{dir}; sudo mkdir -p #{dir}; sudo chmod 0777 #{dir}"
  config.vm.provision "file", source: 'C:\Users\u1bell\otto\FistTry\otto-getting-started\.otto\compiled\app\scriptpacks\STDLIB.tar.gz',   destination: "#{dir}/STDLIB.tar.gz"
  config.vm.provision "shell", inline: "cd #{dir}; sudo mkdir STDLIB; sudo tar xzf STDLIB.tar.gz -C STDLIB"

  config.vm.provision "file", source: 'C:\Users\u1bell\otto\FistTry\otto-getting-started\.otto\compiled\app\scriptpacks\RUBY.tar.gz',    destination: "#{dir}/RUBY.tar.gz"
  config.vm.provision "shell", inline: "cd #{dir}; sudo mkdir RUBY; sudo tar xzf RUBY.tar.gz -C RUBY"

Provisioningを行うスクリプトが、ScriptPacksというアーカイブの形で用意されているようです。 アプリケーションのソースコードを自動解析し、必要なScriptPacksを抽出してVagrantfileに追記してくれるということでしょう。 Rubyのインストール一つとっても、素でコンパイルしたり、rbenvを使ったり、古くてよければyumを使ったりといろいろ手段がありますが、ここではhashicorpがベストプラクティスと考える方法が選択されることになります。