From 57ea5789eb144ce1a18060230e5a4eed0585fb80 Mon Sep 17 00:00:00 2001 From: Antonio Terceiro Date: Thu, 21 May 2015 11:21:10 -0300 Subject: [PATCH] Support using lxc containers --- .gitignore | 1 + Rakefile | 47 ++++++++++++++++++++++++++++++++++++++--------- Vagrantfile | 37 ++++++++++++++++++++++++++----------- cookbooks/basics/files/default/is-a-container | 13 +++++++++++++ cookbooks/basics/files/default/selinux-enabled | 8 ++++++++ cookbooks/basics/files/default/selinux-install-module | 6 ++++++ cookbooks/basics/recipes/default.rb | 21 +++++++++++++++++++-- cookbooks/reverse_proxy/recipes/default.rb | 4 +++- test/dns_test.sh | 2 +- utils/reverseproxy_ssh_setup | 10 +++++++++- 10 files changed, 124 insertions(+), 25 deletions(-) create mode 100644 cookbooks/basics/files/default/is-a-container create mode 100644 cookbooks/basics/files/default/selinux-enabled diff --git a/.gitignore b/.gitignore index 2a4606f..6bbb2ca 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ /utils/obs/isv* /Gemfile.lock /config/local/ssh_config +/config/lxc/ /.tmp /tmp /docs/_build diff --git a/Rakefile b/Rakefile index 8865f91..467ff4a 100644 --- a/Rakefile +++ b/Rakefile @@ -1,3 +1,5 @@ +require 'yaml' + begin load 'local.rake' rescue LoadError @@ -13,15 +15,40 @@ iptables_file = "config/#{$SPB_ENV}/iptables-filter-rules" ENV['CHAKE_SSH_CONFIG'] = ssh_config_file +if $SPB_ENV == 'lxc' + system("mkdir -p config/lxc; sudo lxc-ls -f -F name,ipv4 | sed -e '/^softwarepublico/ !d; s/softwarepublico_//; s/_[0-9_]*/:/ ' > #{ips_file}.new") + begin + ips = YAML.load_file("#{ips_file}.new") + raise ArgumentError unless ips.is_a?(Hash) + FileUtils.mv ips_file + '.new', ips_file + rescue Exception => ex + puts ex.message + puts + puts "Q: did you boot the containers first?" + exit + end + config = YAML.load_file('config/local/config.yaml') + config['external_ip'] = ips['reverseproxy'] + config['relay_ip'] = ips['email'] + File.open(config_file, 'w') do |f| + f.puts(YAML.dump(config)) + end + + File.open('config/lxc/iptables-filter-rules', 'w') do |f| + lxc_host_bridge_ip = '192.168.122.1' # FIXME don't hardcode + f.puts "-A INPUT -s #{lxc_host_bridge_ip} -p tcp -m state --state NEW --dport 22 -j ACCEPT" + end +end + require 'chake' if Chake::VERSION < '0.4.3' fail "Please upgrade to chake 0.4.3+" end -config = YAML.load_file(config_file) -ips = YAML.load_file(ips_file) -firewall = File.open(iptables_file).read +ips ||= YAML.load_file(ips_file) +config ||= YAML.load_file(config_file) +firewall ||= File.open(iptables_file).read $nodes.each do |node| node.data['config'] = config node.data['peers'] = ips @@ -38,13 +65,15 @@ task :test do end file 'ssh_config.erb' -file 'config/local/ssh_config' => ['nodes.yaml', 'config/local/ips.yaml', 'ssh_config.erb', 'Rakefile'] do |t| - require 'erb' - template = ERB.new(File.read('ssh_config.erb')) - File.open(t.name, 'w') do |f| - f.write(template.result(binding)) +if ['local', 'lxc'].include?($SPB_ENV) + file ssh_config_file => ['nodes.yaml', ips_file, 'ssh_config.erb', 'Rakefile'] do |t| + require 'erb' + template = ERB.new(File.read('ssh_config.erb')) + File.open(t.name, 'w') do |f| + f.write(template.result(binding)) + end + puts 'ERB %s' % t.name end - puts 'ERB %s' % t.name end task :backup => ssh_config_file do diff --git a/Vagrantfile b/Vagrantfile index 19ee271..fcc129b 100644 --- a/Vagrantfile +++ b/Vagrantfile @@ -13,28 +13,43 @@ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| config.vm.provision 'shell', path: 'utils/proxy.sh', args: [proxy] end - ips = YAML.load_file('config/local/ips.yaml') + load './local.rake' if File.exists?('local.rake') + env = ENV.fetch('SPB_ENV', 'local') + + if File.exist?("config/#{env}/ips.yaml") + ips = YAML.load_file("config/#{env}/ips.yaml") + else + ips = nil + end config.vm.define 'database' do |database| - database.vm.network 'private_network', ip: ips['database'] + database.vm.provider "virtualbox" do |vm| + database.vm.network 'private_network', ip: ips['database'] if ips + end end config.vm.define 'integration' do |integration| - integration.vm.network 'private_network', ip: ips['integration'] - integration.vm.provider "virtualbox" do |v| - v.memory = 1024 - v.cpus = 2 + integration.vm.provider "virtualbox" do |vm| + integration.vm.network 'private_network', ip: ips['integration'] if ips + vm.memory = 1024 + vm.cpus = 2 end end config.vm.define 'email' do |email| - email.vm.network 'private_network', ip: ips['email'] + email.vm.provider "virtualbox" do |vm| + email.vm.network 'private_network', ip: ips['email'] if ips + end end config.vm.define 'social' do |social| - social.vm.network 'private_network', ip: ips['social'] + social.vm.provider "virtualbox" do |vm| + social.vm.network 'private_network', ip: ips['social'] if ips + end end config.vm.define 'reverseproxy' do |reverseproxy| - reverseproxy.vm.network 'private_network', ip: ips['reverseproxy'] - if File.exist?('tmp/preconfig.local.stamp') - reverseproxy.ssh.port = File.read('tmp/preconfig.local.stamp').strip.to_i + reverseproxy.vm.provider "virtualbox" do |vm| + reverseproxy.vm.network 'private_network', ip: ips['reverseproxy'] if ips + end + if File.exist?("tmp/preconfig.#{env}.stamp") + reverseproxy.ssh.port = File.read("tmp/preconfig.#{env}.stamp").strip.to_i reverseproxy.ssh.host = ips['reverseproxy'] end end diff --git a/cookbooks/basics/files/default/is-a-container b/cookbooks/basics/files/default/is-a-container new file mode 100644 index 0000000..f712234 --- /dev/null +++ b/cookbooks/basics/files/default/is-a-container @@ -0,0 +1,13 @@ +#!/bin/sh + +# MANAGED WITH CHEF; DO NOT CHANGE BY HAND + +set -e + +if grep -q '/$' /proc/1/cgroup; then + # "Real" system + exit 1 +else + # container + exit 0 +fi diff --git a/cookbooks/basics/files/default/selinux-enabled b/cookbooks/basics/files/default/selinux-enabled new file mode 100644 index 0000000..ba0e45a --- /dev/null +++ b/cookbooks/basics/files/default/selinux-enabled @@ -0,0 +1,8 @@ +#!/bin/sh + +# MANAGED WITH CHEF; DO NOT CHANGE BY HAND + +set -e + +selinux_status=$(sestatus | sed -e '/^SELinux status:/ !d; s/.*\s//') +[ "$selinux_status" = 'enabled' ] diff --git a/cookbooks/basics/files/default/selinux-install-module b/cookbooks/basics/files/default/selinux-install-module index 29977ad..43de003 100644 --- a/cookbooks/basics/files/default/selinux-install-module +++ b/cookbooks/basics/files/default/selinux-install-module @@ -9,6 +9,12 @@ if [ $# -ne 1 ]; then exit 1 fi +selinux_status=$(sestatus | sed -e '/^SELinux status:/ !d; s/.*\s//') +if ! selinux-enabled; then + echo "I: SELinux disabled, skipping" + exit 0 +fi + input="$1" directory=$(dirname "$input") diff --git a/cookbooks/basics/recipes/default.rb b/cookbooks/basics/recipes/default.rb index 7c4c9d0..2b621c3 100644 --- a/cookbooks/basics/recipes/default.rb +++ b/cookbooks/basics/recipes/default.rb @@ -10,8 +10,19 @@ cookbook_file '/etc/selinux/config' do group 'root' mode 0644 end -execute 'setenforce Enforcing' -execute 'setsebool httpd_can_network_connect 1' + +cookbook_file '/usr/local/bin/selinux-enabled' do + owner 'root' + group 'root' + mode '0755' +end + +execute 'setenforce Enforcing' do + only_if 'selinux-enabled' +end +execute 'setsebool httpd_can_network_connect 1' do + only_if 'selinux-enabled' +end # directory for local type enforcements directory '/etc/selinux/local' do owner 'root' @@ -32,8 +43,14 @@ package 'less' package 'htop' package 'ntp' +cookbook_file '/usr/local/bin/is-a-container' do + owner 'root' + group 'root' + mode '0755' +end service 'ntpd' do action [:enable, :start] + not_if 'is-a-container' end service 'firewalld' do diff --git a/cookbooks/reverse_proxy/recipes/default.rb b/cookbooks/reverse_proxy/recipes/default.rb index 97b38b3..20ece6a 100644 --- a/cookbooks/reverse_proxy/recipes/default.rb +++ b/cookbooks/reverse_proxy/recipes/default.rb @@ -12,7 +12,9 @@ cookbook_file "/etc/sysctl.d/ip_forward.conf" do mode 0644 end -execute 'sysctl -w net.ipv4.ip_forward=1' +execute 'sysctl -w net.ipv4.ip_forward=1' do + not_if 'is-a-container' +end cookbook_file "/etc/nginx/#{node['config']['external_hostname']}.key" do owner 'root' diff --git a/test/dns_test.sh b/test/dns_test.sh index ed95b1d..53a61cb 100644 --- a/test/dns_test.sh +++ b/test/dns_test.sh @@ -1,6 +1,6 @@ . $(dirname $0)/test_helper.sh -if [ "$SPB_ENV" = local ]; then +if [ "$SPB_ENV" = local -o "$SPB_ENV" = lxc ]; then echo "_No DNS for local environment_" exit fi diff --git a/utils/reverseproxy_ssh_setup b/utils/reverseproxy_ssh_setup index 7fa818c..f340171 100755 --- a/utils/reverseproxy_ssh_setup +++ b/utils/reverseproxy_ssh_setup @@ -11,7 +11,15 @@ sed -i -e 's/^#\?\s*Port\s*[0-9]\+\s*$/Port '$port'/g' /etc/ssh/sshd_config yum install -y selinux-policy policycoreutils-python # Tell SELinux to allow the new port -semanage port -a -t ssh_port_t -p tcp "$port" +if grep -q '/$' /proc/1/cgroup; then + # not in a container + semanage port -a -t ssh_port_t -p tcp "$port" +else + # in container; will fail if host does not have SELinux enabled + if ! semanage port -a -t ssh_port_t -p tcp "$port"; then + echo "I: can't use SELinux, your host probably does not have it enabled" + fi +fi # Restart SSH systemctl restart sshd -- libgit2 0.21.2