This repository has been archived by the owner on Aug 29, 2018. It is now read-only.
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- add 'build-sti-base-windows' vagrant command to build windows AMI with required prereqs - hooks to enable simplification of Vagrantfile (auto-discover AMI id, auto-configure standard Vagrantfile parameters for AWS) - hook to wait for Windows instance to report ready after sysprep - provisioners to allow a Windows instance to be autoconfigured to reasonably securely use Docker on a helper RHEL instance - miscellaneous fixes
- Loading branch information
Jim Minter
committed
Nov 29, 2016
1 parent
16fedf6
commit 8791156
Showing
17 changed files
with
560 additions
and
41 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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' | ||
<powershell> | ||
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 | ||
</powershell> | ||
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
Oops, something went wrong.