6
votes

I am taking my first Foray into using Vagrant + Puppet Provisioning scripts to improve my development workflow.

I am currently trying to set up a dev box for L4 development - and am using the https://github.com/paolooo/vagrant-lamp and https://github.com/paolooo/puppet-laravel.

Following the instructions:

Clone the LAMP box:

git clone git://github.com/paolooo/vagrant-lamp.git lamp
cd lamp

Add Puppet provisioning scripts:

git submodule add https://github.com/paolooo/puppet-laravel.git extras/modules/laravel

Then update submodules:

git submodule update --init --recursive

Great so far - easy stuff...

So now ready to run vagrant up - which seems to provision the VM fine, and boots it.

My problems however seem to start when the init.pp script runs. I am getting lots of 404's when the apt-get <<package>> runs.

My first thoughts were the network interface may be down - but mysql-client download worked (i think) looking at the logs.

I have tried this on OSX and Windows machines.

Any help would be really appreciated - i dont want to fall at the first hurdle.

My Puppet Script:

# Default path
Exec { path => ['/usr/bin', '/bin', '/usr/sbin', '/sbin', '/usr/local/bin', '/usr/local/sbin', '/opt/local/bin'] }
exec { 'apt-get update':
  command => '/usr/bin/apt-get update --fix-missing',
  require => Exec['add php54 apt-repo']
}

# Configuration
if $db_name == '' { $db_name = 'development' }
if $db_location == '' { $db_location  = '/vagrant/db/development.sqlite' }
if $username == '' { $username = 'root' }
if $password == '' { $password = '123' }
if $host == '' { $host = 'localhost' }

# Setup

## PHP
include php54
class { 'php': version => latest, }

## APACHE2
include apache
class {'apache::mod::php': }

## PACKAGES
## 'vim','curl','unzip','git','php5-mysql','php5-sqlite','php5-mcrypt','php5-memcache',
## 'php5-suhosin','php5-xsl','php5-tidy','php5-dev','php5-pgsql','php5-odbc', 'php5-ldap','php5-xmlrpc','php5-intl','php5-fpm'
package { ['vim','curl','unzip','git','php5-mcrypt','php5-memcached']:
  ensure  => installed,
  require => Exec['apt-get update'],
}

package { ['php5-mysql','php5-sqlite']:
  ensure  => installed,
  require => Exec['apt-get update'],
}

include pear
include composer

### Apache
apache::vhost { $fqdn:
  priority  => '20',
  port => '80',
  docroot => $docroot,
  logroot => $docroot, # access_log and error_log
  configure_firewall  => false,
}
a2mod { 'rewrite': ensure => present }

## Ruby
class { "ruby": 
  gems_version => "latest"
}

## Nodejs
class { "nodejs": }

## PHP MODULES
php::module { ['curl', 'gd']:
  notify  => [ Service['httpd'], ],
}

## PEAR
pear::package { "PEAR": }
pear::package { "PHPUnit": 
  version     => "latest",
  repository  => "pear.phpunit.de",
  require     => Pear::Package["PEAR"],
}
pear::package { "Yaml": 
  version     => "latest",
  repository  => "pear.symfony.com",
  require     => Pear::Package["PEAR"]
}

## DB
### MySQL
class { 'mysql::server':
  config_hash => { 'root_password' => "${password}" }
}
class { 'mysql': }
mysql::db { "${db_name}":
  user  => "${username}",
  password  => "${password}",
  host  =>  "${host}",
  grant => ['all'],
  charset => 'utf8',
}

### PostgreSQL
class { 'postgresql':
  version => 'latest',
}
class { 'postgresql::server': }
postgresql::db { "${db_name}":
  owner => "${username}",
  password  => "${password}",
}

### SQLite Config
class { 'sqlite': }
define sqlite::db(
    $location   = '',
    $owner      = 'root',
    $group      = 0,
    $mode       = '755',
    $ensure     = present,
    $sqlite_cmd = 'sqlite3'
  ) {

      file { $safe_location:
        ensure  => $ensure,
        owner   => $owner,
        group   => $group,
        notify  => Exec['create_development_db']
      }

      exec { 'create_development_db':
        command     => "${sqlite_cmd} $db_location",
        path        => '/usr/bin:/usr/local/bin',
        refreshonly => true,
      }
  }

## phpmyadmin
class { 'phpmyadmin': } 

My vagrant file:

# -*- mode: ruby -*-
# vi: set ft=ruby :

Vagrant::Config.run do |config|
  # All Vagrant configuration is done here. The most common configuration
  # options are documented and commented below. For a complete reference,
  # please see the online documentation at vagrantup.com.

  # Every Vagrant virtual environment requires a box to build off of.
  config.vm.box = "precise32"

  # The url from where the 'config.vm.box' box will be fetched if it
  # doesn't already exist on the user's system.
  config.vm.box_url = "http://files.vagrantup.com/precise32.box"

  # Boot with a GUI so you can see the screen. (Default is headless)
  # config.vm.boot_mode = :gui

  # Assign this VM to a host-only network IP, allowing you to access it
  # via the IP. Host-only networks can talk to the host machine as well as
  # any other machines on the same network, but cannot be accessed (through this
  # network interface) by any external networks.
  config.vm.network :hostonly, "192.168.33.10"

  # Assign this VM to a bridged network, allowing you to connect directly to a
  # network using the host's network device. This makes the VM appear as another
  # physical device on your network.
  # config.vm.network :bridged

  # Forward a port from the guest to the host, which allows for outside
  # computers to access the VM, whereas host only networking does not.
  config.vm.forward_port 80, 8082

  # Share an additional folder to the guest VM. The first argument is
  # an identifier, the second is the path on the guest to mount the
  # folder, and the third is the path on the host to the actual folder.
  config.vm.share_folder "v-data", "/vagrant/db", "./db"
  config.vm.share_folder "v-web", "/vagrant/www", "c:\\www"

  # Enable provisioning with Puppet stand alone.  Puppet manifests
  # are contained in a directory path relative to this Vagrantfile.
  # You will need to create the manifests directory and a manifest in
  # the file base.pp in the manifests_path directory.
  #
  # An example Puppet manifest to provision the message of the day:
  #
  # # group { "puppet":
  # #   ensure => "present",
  # # }
  # #
  # # File { owner => 0, group => 0, mode => 0644 }
  # #
  # # file { '/etc/motd':
  # #   content => "Welcome to your Vagrant-built virtual machine!
  # #               Managed by Puppet.\n"
  # # }
  #
  config.vm.provision :puppet do |puppet|
    puppet.facter = {
      "fqdn"      => "dev.lamp.mysql",
      "hostname"  => "www",
      "docroot"   => "/vagrant/www",
      "host"      => 'localhost',
      "username"  => 'root',
      "password"  => '123',
      "db_name"   => "development",
      "db_location" => "/vagrant/db/development.sqlite"
    }
    puppet.manifests_path = "puppet/manifests"
    puppet.module_path = ["puppet/modules", "extras/modules"]
    puppet.manifest_file  = "init.pp"
  end

  # Enable provisioning with chef solo, specifying a cookbooks path, roles
  # path, and data_bags path (all relative to this Vagrantfile), and adding 
  # some recipes and/or roles.
  #
  # config.vm.provision :chef_solo do |chef|
  #   chef.cookbooks_path = "../my-recipes/cookbooks"
  #   chef.roles_path = "../my-recipes/roles"
  #   chef.data_bags_path = "../my-recipes/data_bags"
  #   chef.add_recipe "mysql"
  #   chef.add_role "web"
  #
  #   # You may also specify custom JSON attributes:
  #   chef.json = { :mysql_password => "foo" }
  # end

  # Enable provisioning with chef server, specifying the chef server URL,
  # and the path to the validation key (relative to this Vagrantfile).
  #
  # The Opscode Platform uses HTTPS. Substitute your organization for
  # ORGNAME in the URL and validation key.
  #
  # If you have your own Chef Server, use the appropriate URL, which may be
  # HTTP instead of HTTPS depending on your configuration. Also change the
  # validation key to validation.pem.
  #
  # config.vm.provision :chef_client do |chef|
  #   chef.chef_server_url = "https://api.opscode.com/organizations/ORGNAME"
  #   chef.validation_key_path = "ORGNAME-validator.pem"
  # end
  #
  # If you're using the Opscode platform, your validator client is
  # ORGNAME-validator, replacing ORGNAME with your organization name.
  #
  # IF you have your own Chef Server, the default validation client name is
  # chef-validator, unless you changed the configuration.
  #
  #   chef.validation_client_name = "ORGNAME-validator"
end
2

2 Answers

5
votes

It would appear that the issue is the apt-get update note being executed, not sure why this is the case, as my Puppet script appears to be configured correctly to call it...

However - i was able to solve this problem by adding the following line to my Vagrant file:

config.vm.provision :shell, :inline => "apt-get update --fix-missing"

Would love to know what is wrong with the puppet config though, as it would be nice to be able to avoid having to put this in the Vagrant file.

2
votes

Firstly, you made references to some classes which are not included in your post,so I can't comment on those.

It looks like you have a puppet ordering issue; I would suggest running it again and identifying which specific package deployments are failing and determine which class they belong to. So for example if some package x in class y is failing, add the following to your init script just before the closing bracket of the class in question -

class y {

    package { "x":

       ensure  => installed,
    }

    Exec["apt-get update"] -> Class["y"]  

}

The above will ensure apt-get update completes before any class 'y' configuration is run.

Alternatively, for the package resource type, you can continue to add -

require => Exec['apt-get update'] , but I find the class ordering neater.