diff --git a/lib/vagrant-openshift/action.rb b/lib/vagrant-openshift/action.rb index 2d7643f0..3a0a1ddd 100644 --- a/lib/vagrant-openshift/action.rb +++ b/lib/vagrant-openshift/action.rb @@ -66,6 +66,12 @@ def self.install_golang(options) end end + def self.build_sti_base_windows(options) + Vagrant::Action::Builder.new.tap do |b| + b.use BuildStiBaseWindows, options + end + end + def self.install_origin(options) Vagrant::Action::Builder.new.tap do |b| b.use SetHostName @@ -386,6 +392,7 @@ def self.install_rhc(options) autoload :InstallOriginRhel7, action_root.join("install_origin_rhel7") autoload :BuildOrigin, action_root.join("build_origin") autoload :BuildSti, action_root.join("build_sti") + autoload :BuildStiBaseWindows, action_root.join("build_sti_base_windows") autoload :PrepareSshConfig, action_root.join("prepare_ssh_config") autoload :SyncLocalRepository, action_root.join("sync_local_repository") autoload :SyncUpstreamRepository, action_root.join("sync_upstream_repository") diff --git a/lib/vagrant-openshift/action/build_sti_base_windows.rb b/lib/vagrant-openshift/action/build_sti_base_windows.rb new file mode 100644 index 00000000..c263458d --- /dev/null +++ b/lib/vagrant-openshift/action/build_sti_base_windows.rb @@ -0,0 +1,127 @@ +#-- +# Copyright 2016 Red Hat, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +#++ + +require "fog" +require_relative "../aws" + +module Vagrant + module Openshift + module Action + class BuildStiBaseWindows + include CommandHelper + + def initialize(app, env, options) + @app = app + @env = env + @options = options + end + + def call(env) + aws_creds = Vagrant::Openshift::AWS::aws_creds() + compute = Fog::Compute.new(Vagrant::Openshift::AWS::fog_config(aws_creds)) + + @env[:ui].info("Finding base AMI...") + images = compute.images.all({"Owner" => "amazon", "name" => "Windows_Server-2012-R2_RTM-English-64Bit-Base-*", "state" => "available"}) + # https://github.com/fog/fog-aws/issues/320 would make this less hacky + images.sort_by! {|image| image.name[-10,10]} + @env[:ui].info("Using base AMI #{images.last.name}, #{images.last.id}") + + @env[:ui].info("Creating instance...") + instance = compute.servers.create( + :tags => {"Name" => "#{@options[:instance_prefix]}-windows2012r2_#{Time.now.to_i}"}, + :image_id => images.last.id, + :flavor_id => @options[:flavor_id], + :key_name => aws_creds["AWSKeyPairName"], + :subnet_id => @options[:subnet_id], + :user_data => <<'USERDATA' + +Set-ExecutionPolicy -ExecutionPolicy Bypass + +# Download and install Cygwin +$client = New-Object System.Net.WebClient +$client.DownloadFile("https://cygwin.com/setup-x86_64.exe", "C:\Windows\Temp\setup-x86_64.exe") +&C:\Windows\Temp\setup-x86_64.exe -q -D -L -d -o -s http://mirrors.kernel.org/sourceware/cygwin -l C:\Windows\Temp\cygwin -R C:\cygwin -P curl -P gcc-core -P git -P make -P openssh -P rsync | Out-Null +Remove-Item -Recurse C:\Windows\Temp\cygwin +Remove-Item C:\Windows\Temp\setup-x86_64.exe +$env:Path += ";C:\cygwin\bin" + +# Configure and start OpenSSH +$env:LOGONSERVER = "\\" + $env:COMPUTERNAME # http://petemoore.github.io/general/taskcluster/2016/03/30/windows-sshd-cygwin-ec2-aws.html +&bash -c "ssh-host-config --yes -w Pa$$w0rd" +&bash -c "sed -i -e 's/#PasswordAuthentication yes/PasswordAuthentication no/' /etc/sshd_config" +&bash -c "sed -i -e 's/#ChallengeResponseAuthentication yes/ChallengeResponseAuthentication no/' /etc/sshd_config" +&cygrunsrv -S sshd +&netsh advfirewall firewall add rule name=SSH profile=any localport=22 enable=yes action=allow dir=in protocol=tcp + +# Download and install Golang +$client.DownloadFile("https://storage.googleapis.com/golang/go1.7.1.windows-amd64.msi", "C:\Windows\Temp\go1.7.1.windows-amd64.msi") +&msiexec /qb /i C:\Windows\Temp\go1.7.1.windows-amd64.msi | Out-Null +Remove-Item C:\Windows\Temp\go1.7.1.windows-amd64.msi + +# Create Administrator's home directory +Out-Null | &bash --login +&bash -c "mkdir /home/Administrator/.ssh; curl -o /home/Administrator/.ssh/authorized_keys http://169.254.169.254/latest/meta-data/public-keys/0/openssh-key" +&bash -c "mkdir /data" +$stream = New-Object System.IO.StreamWriter @("c:\cygwin\home\Administrator\.bash_profile", $true) +$stream.Write("export GOPATH='C:\cygwin\data'`n") +$stream.Close() + +# Download and install Docker client +$client.DownloadFile("https://get.docker.com/builds/Windows/x86_64/docker-1.10.3.exe", "C:\cygwin\usr\local\bin\docker.exe") + +# Install a fake sudo +$stream = New-Object System.IO.StreamWriter "C:\cygwin\bin\sudo" +$stream.Write("#!/bin/bash`n`nwhile [[ `$# -ge 0 && `$1 = -* ]]; do`n shift`ndone`n`n`"`$@`"`n") +$stream.Close() +$stream = New-Object System.IO.StreamWriter "C:\cygwin\etc\sudoers" +$stream.Close() + +# Start sysprep (will power off instance when done) +&"C:\Program Files\Amazon\Ec2ConfigService\ec2config.exe" -sysprep + +USERDATA + ) + + @env[:ui].info("Instance ID is #{instance.id}") + + @env[:ui].info("Waiting for instance state == running...") + instance.wait_for { ready? } + + @env[:ui].info("Waiting for instance state == stopped...") + instance.wait_for(3600) { state == "stopped" } + + @env[:ui].info("Creating AMI...") + image_req = compute.create_image(instance.id, "#{@options[:ami_prefix]}-windows2012r2_#{Time.now.to_i}", "", false) + + @env[:ui].info("AMI ID is #{image_req.body['imageId']}") + + @env[:ui].info("Waiting for AMI state == available...") + Fog.wait_for { + image = compute.images.get(image_req.body["imageId"]) + !image.nil? && image.ready? + } + + @env[:ui].info("Setting instance name to terminate...") + compute.create_tags(instance.id, "Name" => "terminate") + + @env[:ui].info("Done") + + @app.call(env) + end + end + end + end +end diff --git a/lib/vagrant-openshift/action/clone_upstream_repositories.rb b/lib/vagrant-openshift/action/clone_upstream_repositories.rb index c341196f..b505ac84 100644 --- a/lib/vagrant-openshift/action/clone_upstream_repositories.rb +++ b/lib/vagrant-openshift/action/clone_upstream_repositories.rb @@ -27,9 +27,9 @@ def initialize(app, env, options={}) end def call(env) - ssh_user = env[:machine].ssh_info[:username] + ssh_user, ssh_group = get_ssh_user_and_group(env[:machine]) - remote_write(env[:machine], "/#{ssh_user}/.ssh/config", "#{ssh_user}:#{ssh_user}", "0600") { + remote_write(env[:machine], "/#{ssh_user}/.ssh/config", "#{ssh_user}:#{ssh_group}", "0600") { %{Host github.com StrictHostKeyChecking no UserKnownHostsFile=/dev/null @@ -52,7 +52,7 @@ def call(env) end sudo(env[:machine], "mkdir -p #{Constants.build_dir}") - sudo(env[:machine], "mkdir -p #{Constants.build_dir + "builder"} && chown -R #{ssh_user}:#{ssh_user} #{Constants.build_dir}") + sudo(env[:machine], "mkdir -p #{Constants.build_dir + "builder"} && chown -R #{ssh_user}:#{ssh_group} #{Constants.build_dir}") do_execute env[:machine], git_clone_commands @app.call(env) diff --git a/lib/vagrant-openshift/action/download_artifacts_sti.rb b/lib/vagrant-openshift/action/download_artifacts_sti.rb index 54609688..12950d8c 100644 --- a/lib/vagrant-openshift/action/download_artifacts_sti.rb +++ b/lib/vagrant-openshift/action/download_artifacts_sti.rb @@ -34,12 +34,17 @@ def call(env) artifacts_dir = Pathname.new(File.expand_path(machine.env.root_path + "artifacts")) download_map = { - "/var/log/yum.log" => artifacts_dir + "yum.log", - "/var/log/secure" => artifacts_dir + "secure", - "/var/log/audit/audit.log" => artifacts_dir + "audit.log", "/tmp/sti/" => artifacts_dir + "sti/" } + if !is_windows?(machine) + download_map.merge!({ + "/var/log/yum.log" => artifacts_dir + "yum.log", + "/var/log/secure" => artifacts_dir + "secure", + "/var/log/audit/audit.log" => artifacts_dir + "audit.log" + }) + end + download_map.each do |source,target| machine.ui.info "Downloading artifacts from '#{source}' to '#{target}'" if target.to_s.end_with? '/' diff --git a/lib/vagrant-openshift/action/generate_template.rb b/lib/vagrant-openshift/action/generate_template.rb index 90806752..25a6f015 100644 --- a/lib/vagrant-openshift/action/generate_template.rb +++ b/lib/vagrant-openshift/action/generate_template.rb @@ -15,6 +15,7 @@ #++ require 'yaml' require 'fog' +require_relative '../aws' module Vagrant module Openshift @@ -48,10 +49,14 @@ def call(env) @openstack_creds_file = Pathname.new(File.expand_path(@openstack_creds_file)) box_info[:openstack_creds_file] = @openstack_creds_file - @aws_creds_file = ENV['AWS_CREDS'].nil? || ENV['AWS_CREDS'] == '' ? "~/.awscred" : ENV['AWS_CREDS'] - @aws_creds_file = Pathname.new(File.expand_path(@aws_creds_file)) - box_info[:aws_creds_file] = @aws_creds_file - find_ami_from_tag(box_info) + if !box_info[:aws].nil? && !box_info[:aws][:ami_tag_prefix].nil? + begin + aws_creds = Vagrant::Openshift::AWS::aws_creds() + compute = Fog::Compute.new(Vagrant::Openshift::AWS::fog_config(aws_creds, box_info[:aws][:ami_region])) + box_info[:aws][:ami] = Vagrant::Openshift::AWS::find_ami_from_tag(compute, box_info[:aws][:ami_tag_prefix], @options[:required_name_tag]) + rescue AWSCredentialsNotConfiguredError + end + end gopath = nil if ENV['GOPATH'] && !ENV['GOPATH'].empty? @@ -103,33 +108,6 @@ def call(env) @app.call(env) end - - private - - def find_ami_from_tag(box_info) - return if box_info[:aws].nil? || box_info[:aws][:ami_tag_prefix].nil? - @env[:ui].info("Reading AWS credentials from #{@aws_creds_file.to_s}") - if @aws_creds_file.exist? - aws_creds = @aws_creds_file.exist? ? Hash[*(File.open(@aws_creds_file.to_s).readlines.map{ |l| l.strip! - l.split('=') }.flatten)] : {} - - fog_config = { - :provider => :aws, - :region => box_info[:aws][:ami_region], - :aws_access_key_id => aws_creds['AWSAccessKeyId'], - :aws_secret_access_key => aws_creds['AWSSecretKey'], - } - - aws_compute = Fog::Compute.new(fog_config) - @env[:ui].info("Searching for latest base AMI") - image_filter = {'Owner' => 'self', 'name' => "#{box_info[:aws][:ami_tag_prefix]}*", 'state' => 'available' } - image_filter['tag:Name'] = @options[:required_name_tag] unless @options[:required_name_tag].nil? - images = aws_compute.images.all(image_filter) - latest_image = images.sort_by{ |i| i.name.split("_")[-1].to_i }.last - box_info[:aws][:ami] = latest_image.id - @env[:ui].info("Found: #{latest_image.id} (#{latest_image.name})") - end - end end end end diff --git a/lib/vagrant-openshift/action/run_sti_tests.rb b/lib/vagrant-openshift/action/run_sti_tests.rb index 47e205a0..648eaab2 100644 --- a/lib/vagrant-openshift/action/run_sti_tests.rb +++ b/lib/vagrant-openshift/action/run_sti_tests.rb @@ -34,7 +34,7 @@ def call(env) cmds = ['OUTPUT_COVERAGE=/tmp/sti/artifacts/coverage hack/test-go.sh'] if @options[:all] - cmds << 'STI_TIMEOUT="--timeout 240s" hack/test-integration.sh' + cmds << 'hack/test-integration.sh' cmds << 'hack/test-stirunimage.sh' end @@ -49,6 +49,8 @@ def call(env) " end + # TODO: the PATH export below should be removed once + # https://github.com/openshift/source-to-image/pull/625 merges. _,_,env[:test_exit_code] = sudo(env[:machine], %{ set -e pushd #{Constants.build_dir}/source-to-image >/dev/null diff --git a/lib/vagrant-openshift/aws.rb b/lib/vagrant-openshift/aws.rb new file mode 100644 index 00000000..a3938e4b --- /dev/null +++ b/lib/vagrant-openshift/aws.rb @@ -0,0 +1,60 @@ +#-- +# Copyright 2016 Red Hat, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +#++ + +require "pathname" +require "fog" + +module Vagrant + module Openshift + class AWSCredentialsNotConfiguredError < RuntimeError + def initialize(msg="AWS credentials not configured") + super + end + end + + class AWS + def self.aws_creds() + aws_creds_file = ENV["AWS_CREDS"].nil? || ENV["AWS_CREDS"] == "" ? "~/.awscred" : ENV["AWS_CREDS"] + aws_creds_file = Pathname.new(File.expand_path(aws_creds_file)) + + raise AWSCredentialsNotConfiguredError if !aws_creds_file.exist? + + return Hash[*(aws_creds_file.open.readlines.map{|l| l.strip.split("=")}.flatten)] + end + + def self.fog_config(aws_creds, region="us-east-1") + { + :provider => :aws, + :aws_access_key_id => aws_creds["AWSAccessKeyId"], + :aws_secret_access_key => aws_creds["AWSSecretKey"], + :region => region + } + end + + def self.find_ami_from_tag(compute, ami_tag_prefix, required_name_tag=nil) + image_filter = {"Owner" => "self", "name" => "#{ami_tag_prefix}*", "state" => "available"} + image_filter["tag:Name"] = required_name_tag unless required_name_tag.nil? + images = compute.images.all(image_filter) + latest_image = images.sort_by{|i| i.name.split("_")[-1].to_i}.last + if !latest_image.nil? + return latest_image.id + end + + nil + end + end + end +end diff --git a/lib/vagrant-openshift/command/build_sti_base_windows.rb b/lib/vagrant-openshift/command/build_sti_base_windows.rb new file mode 100644 index 00000000..7f5245c1 --- /dev/null +++ b/lib/vagrant-openshift/command/build_sti_base_windows.rb @@ -0,0 +1,66 @@ +#-- +# Copyright 2016 Red Hat, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +#++ +require_relative "../action" + +module Vagrant + module Openshift + module Commands + class BuildStiBaseWindows < Vagrant.plugin(2, :command) + include CommandHelper + + def self.synopsis + "install the prereqs for source-to-image on Windows" + end + + def execute + options = { + :ami_prefix => ENV["USER"], + :flavor_id => "m4.large", + :instance_prefix => ENV["USER"] + } + + opts = OptionParser.new do |o| + o.banner = "Usage: vagrant build-sti-base-windows subnet_id" + o.separator "" + + o.on("--ami-prefix prefix", "Prefix for AMI name.") do |prefix| + options[:ami_prefix] = prefix + end + + o.on("--flavor flavor", "Flavor of instance.") do |flavor| + options[:flavor_id] = flavor + end + + o.on("--instance-prefix prefix", "Prefix for instance name.") do |prefix| + options[:instance_prefix] = prefix + end + end + + # Parse the options + argv = parse_options(opts) + return if !argv + + raise Errors::CLIInvalidOptions, help: opts.help.chomp if argv.length != 1 + options[:subnet_id] = argv[0] + + actions = Vagrant::Openshift::Action.build_sti_base_windows(options) + @env.action_runner.run actions + 0 + end + end + end + end +end diff --git a/lib/vagrant-openshift/config.rb b/lib/vagrant-openshift/config.rb index 75e5e07f..1e33a402 100644 --- a/lib/vagrant-openshift/config.rb +++ b/lib/vagrant-openshift/config.rb @@ -17,14 +17,15 @@ module Vagrant module Openshift class Config < Vagrant.plugin(2, :config) + attr_accessor :autoconfigure_aws def initialize - super + @autoconfigure_aws = UNSET_VALUE end def finalize! - super + @autoconfigure_aws = false if @autoconfigure_aws == UNSET_VALUE end end end -end \ No newline at end of file +end diff --git a/lib/vagrant-openshift/helper/command_helper.rb b/lib/vagrant-openshift/helper/command_helper.rb index d6a50c15..aa662440 100644 --- a/lib/vagrant-openshift/helper/command_helper.rb +++ b/lib/vagrant-openshift/helper/command_helper.rb @@ -235,6 +235,15 @@ def bash_systemd_polling_functions return command end + def is_windows?(machine) + machine.config.ssh.username == "Administrator" + end + + def get_ssh_user_and_group(machine) + ssh_user = machine.ssh_info[:username] + ssh_group = is_windows?(machine) ? "Administrators" : ssh_user + return ssh_user, ssh_group + end end end end diff --git a/lib/vagrant-openshift/hooks/configure_aws.rb b/lib/vagrant-openshift/hooks/configure_aws.rb new file mode 100644 index 00000000..e3e93ad4 --- /dev/null +++ b/lib/vagrant-openshift/hooks/configure_aws.rb @@ -0,0 +1,51 @@ +#-- +# Copyright 2016 Red Hat, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +#++ + +require_relative "../aws" + +module Vagrant + module Openshift + module Hooks + class ConfigureAWS + def initialize(app, env) + @app = app + end + + def call(env) + if env[:machine].config.openshift.autoconfigure_aws + aws_creds = Vagrant::Openshift::AWS::aws_creds() + + aws = env[:machine].config.vm.get_provider_config(:aws) + aws.access_key_id = aws_creds["AWSAccessKeyId"] + aws.secret_access_key = aws_creds["AWSSecretKey"] + aws.keypair_name = aws_creds["AWSKeyPairName"] + + box_info = YAML.load_file(Pathname.new(File.expand_path("#{__FILE__}/../../templates/command/init-openshift/box_info.yaml"))) + if !aws.ami.nil? && !aws.ami.start_with?("ami-") + os, stage = aws.ami.split(":", 2) + env[:machine].config.ssh.username = box_info[os.to_sym][stage.to_sym][:aws][:ssh_user] + end + env[:machine].config.ssh.private_key_path = [aws_creds["AWSPrivateKeyPath"]] + env[:machine].config.vm.box = "https://github.com/mitchellh/vagrant-aws/raw/master/dummy.box" + env[:machine].config.vm.synced_folders["/vagrant"] = {:disabled => true, :guestpath => "/vagrant", :hostpath => "."} + end + + @app.call(env) + end + end + end + end +end diff --git a/lib/vagrant-openshift/hooks/find_ami.rb b/lib/vagrant-openshift/hooks/find_ami.rb new file mode 100644 index 00000000..d3921462 --- /dev/null +++ b/lib/vagrant-openshift/hooks/find_ami.rb @@ -0,0 +1,42 @@ +#-- +# Copyright 2016 Red Hat, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +#++ + +require_relative "../aws" + +module Vagrant + module Openshift + module Hooks + class FindAMI + def initialize(app, env) + @app = app + end + + def call(env) + if env[:machine].config.openshift.autoconfigure_aws + aws = env[:machine].config.vm.get_provider_config(:aws) + if !aws.ami.nil? && !aws.ami.start_with?("ami-") + box_info = YAML.load_file(Pathname.new(File.expand_path("#{__FILE__}/../../templates/command/init-openshift/box_info.yaml"))) + os, stage = aws.ami.split(":", 2) + aws.ami = Vagrant::Openshift::AWS::find_ami_from_tag(env[:aws_compute], box_info[os.to_sym][stage.to_sym][:aws][:ami_tag_prefix]) + end + end + + @app.call(env) + end + end + end + end +end diff --git a/lib/vagrant-openshift/hooks/windows_wait.rb b/lib/vagrant-openshift/hooks/windows_wait.rb new file mode 100644 index 00000000..abf621ca --- /dev/null +++ b/lib/vagrant-openshift/hooks/windows_wait.rb @@ -0,0 +1,40 @@ +#-- +# Copyright 2016 Red Hat, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +#++ + +require_relative "../aws" + +module Vagrant + module Openshift + module Hooks + class WindowsWait + include CommandHelper + + def initialize(app, env) + @app = app + end + + def call(env) + if env[:machine].config.openshift.autoconfigure_aws && is_windows?(env[:machine]) + env[:ui].info 'Waiting for instance to report "Windows is Ready to use"...' + Fog.wait_for(1200) { /Message: Windows is Ready to use/.match(env[:aws_compute].get_console_output(env[:machine].id).body["output"]) } + end + + @app.call(env) + end + end + end + end +end diff --git a/lib/vagrant-openshift/plugin.rb b/lib/vagrant-openshift/plugin.rb index 655d67d8..8c01f833 100644 --- a/lib/vagrant-openshift/plugin.rb +++ b/lib/vagrant-openshift/plugin.rb @@ -72,6 +72,11 @@ class Plugin < Vagrant.plugin("2") Commands::BuildOriginBase end + command "build-sti-base-windows" do + require_relative "command/build_sti_base_windows" + Commands::BuildStiBaseWindows + end + command "build-origin" do require_relative "command/build_origin" Commands::BuildOrigin @@ -232,10 +237,35 @@ class Plugin < Vagrant.plugin("2") Commands::RepoSyncCustomerDiagnostics end + provisioner("configure-docker-client-windows") do + require_relative "provisioner/configure_docker_client_windows" + Provisioner::ConfigureDockerClientWindows + end + + provisioner("configure-docker-server-linux") do + require_relative "provisioner/configure_docker_server_linux" + Provisioner::ConfigureDockerServerLinux + end + provisioner(:openshift) do require_relative "provisioner" Provisioner end + + action_hook(:configure_aws, :machine_action_read_state) do |hook| + require_relative "hooks/configure_aws" + hook.before(Vagrant::Action::Builtin::ConfigValidate, Vagrant::Openshift::Hooks::ConfigureAWS) + end + + action_hook(:find_ami, :machine_action_up) do |hook| + require_relative "hooks/find_ami" + hook.before(VagrantPlugins::AWS::Action::RunInstance, Vagrant::Openshift::Hooks::FindAMI) + end + + action_hook(:windows_wait, :machine_action_up) do |hook| + require_relative "hooks/windows_wait" + hook.after(VagrantPlugins::AWS::Action::RunInstance, Vagrant::Openshift::Hooks::WindowsWait) + end end end end diff --git a/lib/vagrant-openshift/provisioner/configure_docker_client_windows.rb b/lib/vagrant-openshift/provisioner/configure_docker_client_windows.rb new file mode 100644 index 00000000..4ce7950d --- /dev/null +++ b/lib/vagrant-openshift/provisioner/configure_docker_client_windows.rb @@ -0,0 +1,38 @@ +#-- +# Copyright 2016 Red Hat, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +#++ + +module Vagrant + module Openshift + module Provisioner + class ConfigureDockerClientWindows < Vagrant.plugin("2", :provisioner) + def provision + @machine.communicate.execute(%{mkdir -p /cygdrive/c/Users/Administrator/.docker}) + @machine.communicate.upload(".vagrant/docker-config/ca.crt", "/cygdrive/c/Users/Administrator/.docker/ca.pem") + @machine.communicate.upload(".vagrant/docker-config/client.crt", "/cygdrive/c/Users/Administrator/.docker/cert.pem") + @machine.communicate.upload(".vagrant/docker-config/client.key", "/cygdrive/c/Users/Administrator/.docker/key.pem") + @machine.communicate.upload(".vagrant/docker-config/dockerenv", ".dockerenv") + + cmd = %{ +if ! grep -q dockerenv .bash_profile; then + echo ". .dockerenv" >>.bash_profile +fi +} + @machine.communicate.execute(cmd) + end + end + end + end +end diff --git a/lib/vagrant-openshift/provisioner/configure_docker_server_linux.rb b/lib/vagrant-openshift/provisioner/configure_docker_server_linux.rb new file mode 100644 index 00000000..74fce643 --- /dev/null +++ b/lib/vagrant-openshift/provisioner/configure_docker_server_linux.rb @@ -0,0 +1,54 @@ +#-- +# Copyright 2016 Red Hat, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +#++ + +module Vagrant + module Openshift + module Provisioner + class ConfigureDockerServerLinux < Vagrant.plugin("2", :provisioner) + def provision + begin + Dir.mkdir(".vagrant/docker-config") + rescue Errno::EEXIST + end + + cmd = %{ +IP=$(ifconfig eth0 | awk '/inet / { print $2; }') +openssl genrsa -out /tmp/ca.key +openssl req -new -key /tmp/ca.key -subj /CN=CA -x509 -sha1 -days 7 -set_serial 1 -out /tmp/ca.crt +openssl genrsa -out /tmp/server.key +openssl req -new -key /tmp/server.key -subj /CN=$IP -out /tmp/server.csr +echo subjectAltName=IP:$IP | openssl x509 -req -in /tmp/server.csr -CA /tmp/ca.crt -CAkey /tmp/ca.key -days 7 -extfile /dev/stdin -set_serial 2 -out /tmp/server.crt +rm -f /tmp/server.csr +openssl genrsa -out /tmp/client.key +openssl req -new -key /tmp/client.key -subj /CN=client -out /tmp/client.csr +echo extendedKeyUsage=clientAuth | openssl x509 -req -in /tmp/client.csr -CA /tmp/ca.crt -CAkey /tmp/ca.key -days 7 -extfile /dev/stdin -set_serial 3 -out /tmp/client.crt +rm -f /tmp/client.csr +if ! grep -q tlsverify /etc/sysconfig/docker; then + sed -i -e "s|^OPTIONS='|OPTIONS='--tlsverify --tlscacert=/tmp/ca.crt --tlscert=/tmp/server.crt --tlskey=/tmp/server.key -H unix:///var/run/docker.sock -H tcp://0.0.0.0:2376 |" /etc/sysconfig/docker +fi +systemctl restart docker.service +echo -e "export DOCKER_HOST=tcp://$IP:2376\nexport DOCKER_TLS_VERIFY=1" >/tmp/dockerenv +} + @machine.communicate.sudo(cmd) + @machine.communicate.download("/tmp/ca.crt", ".vagrant/docker-config/ca.crt") + @machine.communicate.download("/tmp/client.crt", ".vagrant/docker-config/client.crt") + @machine.communicate.download("/tmp/client.key", ".vagrant/docker-config/client.key") + @machine.communicate.download("/tmp/dockerenv", ".vagrant/docker-config/dockerenv") + end + end + end + end +end diff --git a/lib/vagrant-openshift/templates/command/init-openshift/box_info.yaml b/lib/vagrant-openshift/templates/command/init-openshift/box_info.yaml index 87a71a27..af44960b 100644 --- a/lib/vagrant-openshift/templates/command/init-openshift/box_info.yaml +++ b/lib/vagrant-openshift/templates/command/init-openshift/box_info.yaml @@ -208,3 +208,12 @@ :image: :flavor: m1.small :ssh_user: root +:windows2012r2: + :deps: + :aws: + :ami: + :ami_region: us-east-1 + :ssh_user: Administrator + :machine_name: openshift-windows2012r2 + :ebs_volume_size: 30 + :ami_tag_prefix: openshift-windows2012r2_