Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

download url override and checksum updates #237

Merged
merged 6 commits into from
Aug 31, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ matrix:
env: SUITE=ubuntu
- rvm: 2.3
env: SUITE=windows-server
- rvm: 2.3
env: SUITE=centos

before_script:
- ci/before-script.sh
Expand Down
28 changes: 27 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ options = {
Collecting software dependencies and license content for ArtifactInfo instances
requires additional requests to the repository server. By default, collection is disabled.
To return data for instance methods `software_dependencies` and `license_content`, the `include_metadata` option must be enabled.
```
```ruby
options = {
channel: :current,
product_name: 'chef',
Expand All @@ -197,6 +197,32 @@ artifact.software_dependencies.class

```


### Install Scripts
mixlib-install generates the bootstrap installation scripts known as install.sh and install.ps1. The associated install script will be returned when calling `#install_command` on the Mixlib::Install instance.

Mixlib::Install instantiation option `install_command_options` can accept variables (bourne) or parameters (powershell) to modify the behavior of the install scripts.

Some of the more common options include:

`download_url_override`: Use the provided URL instead of fetching the metadata URL from Chef Software Inc's software distribution systems.
`checksum`: SHA256 value associated to the directed file for the download_url_override option. This setting is optional. Not setting this will download the file even if a cached file is detected.
`install_strategy`: Set to "once" to have the script exit if the product being installed is detected.

```ruby
options = {
product_name: 'chef',
install_command_options: {
download_url_override: "https://file/path",
checksum: "OPTIONAL",
install_strategy: "once",
}
}

Mixlib::Install.new(options).install_command
```


## Development
VCR is a tool that helps cache and replay http responses. When these responses change or when you add more tests you might need to update cached responses. Check out [spec_helper.rb](https://github.com/chef/mixlib-install/blob/master/spec/spec_helper.rb) for instructions on how to do this.

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
nodes/
tmp/

# Terraform
*.tfstate
*.tfstate.backup
*_override.tf

Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Generate install script then write to disk for terraform to copy to the instance for execution
execute "bundle exec ruby -e \"require 'mixlib/install'; puts Mixlib::Install.new(product_name: 'chef', product_version: :latest, channel: :stable, install_command_options: {download_url_override: 'https://packages.chef.io/files/stable/chef/13.2.20/ubuntu/14.04/chef_13.2.20-1_amd64.deb', cmdline_dl_dir: '/tmp/checksum'}).install_command\" > ../.acceptance_data/ubuntu_install_url.sh" do
cwd node['chef-acceptance']['suite-dir']
end

execute "bundle exec ruby -e \"require 'mixlib/install'; puts Mixlib::Install.new(product_name: 'chef', product_version: :latest, channel: :stable, install_command_options: {download_url_override: 'https://packages.chef.io/files/stable/chef/13.2.20/ubuntu/14.04/chef_13.2.20-1_amd64.deb', checksum: '88cd274a694bfe23d255937794744d50af972097958fa681a544479e2bfb7f6b', cmdline_dl_dir: '/tmp/checksum'}).install_command\" > ../.acceptance_data/ubuntu_install_checksum.sh" do
cwd node['chef-acceptance']['suite-dir']
end

execute "bundle exec ruby -e \"require 'mixlib/install'; puts Mixlib::Install.new(product_name: 'chef', product_version: :latest, channel: :stable, install_command_options: {cmdline_dl_dir: '/tmp/metadata'}).install_command\" > ../.acceptance_data/ubuntu_install_metadata.sh" do
cwd node['chef-acceptance']['suite-dir']
end

execute "bundle exec ruby -e \"require 'mixlib/install'; puts Mixlib::Install.new(product_name: 'chef', product_version: :latest, channel: :stable, install_command_options: {download_url_override: 'https://packages.chef.io/files/stable/chef/13.2.20/ubuntu/14.04/chef_13.2.20-1_amd64.deb', checksum: 'FOOOOOOOOOOOOOO', cmdline_dl_dir: '/tmp/bad'}).install_command\" > ../.acceptance_data/ubuntu_install_bad.sh" do
cwd node['chef-acceptance']['suite-dir']
end

execute "terraform plan" do
cwd "#{node['chef-acceptance']['suite-dir']}/terraform"
end

execute "terraform apply" do
cwd "#{node['chef-acceptance']['suite-dir']}/terraform"
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
ruby_block "get ip" do
block do
tf_state = JSON.parse(File.read("#{node['chef-acceptance']['suite-dir']}/terraform/terraform.tfstate"))
node.default["ip"] = tf_state["modules"].first["resources"]["aws_instance.mixlib_install_sh"]["primary"]["attributes"]["public_ip"]
end
end

execute "run inspec" do
command lazy { "inspec exec verify.rb -t ssh://ubuntu@#{node['ip']} -i ~/.ssh/es-infrastructure.pem" }
cwd "#{node['chef-acceptance']['suite-dir']}/inspec"
end
78 changes: 78 additions & 0 deletions acceptance/.suites/ubuntu_install_checksum/inspec/verify.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# Uncomment when re-running for local development
describe command("sudo rm -rf /tmp/metadata /tmp/checksum /tmp/bad; sudo dpkg -r chef") do
its("exit_status") { should eq 0 }
end

#
# DOWNLOAD URL TESTS
#
# No checksum provided
describe command("sudo /tmp/install.sh") do
its("stdout") { should match /Download URL override specified/ }
its("stdout") { should match /tmp\/checksum\/chef.* not found/ }
its("stdout") { should match /Thank you/ }
end

# Running same script again
describe command("sudo /tmp/install.sh") do
its("stdout") { should match /Download URL override specified/ }
its("stdout") { should match /Verifying local file/ }
its("stdout") { should match /Checksum not specified/ }
its("stdout") { should match /Thank you/ }
end

# Now with a valid checksum
describe command("sudo /tmp/install_checksum.sh") do
its("stdout") { should match /Download URL override specified/ }
its("stdout") { should match /Verifying local file/ }
its("stdout") { should match /Checksum match/ }
its("stdout") { should match /Thank you/ }
end

# Corrupt the file we just downloaded
describe command("sudo chown ubuntu /tmp/checksum; sudo chown ubuntu /tmp/checksum/*; for i in /tmp/checksum/*; do echo 'oops'>>$i; done;") do
its("exit_status") { should eq 0 }
end

# Run with checksum and it should download and re-verify the checksum
describe command("sudo /tmp/install_checksum.sh") do
its("stdout") { should match /Download URL override specified/ }
its("stdout") { should match /Verifying local file/ }
its("stdout") { should match /Checksum mismatch/ }
its("stdout") { should match /Thank you/ }
end

# clean up
describe command("sudo dpkg -r chef") do
its("stdout") { should match /Removing chef/ }
end

#
# METADATA URL TESTS
#
# Default behavior when specifying a download location (otherwise caching is unavailable)
describe command("sudo /tmp/install_metadata.sh") do
its("stdout") { should_not match /tmp\/metadata\/chef.* exists/ }
its("stdout") { should match /Thank you/ }
end

# Running same script again
describe command("sudo /tmp/install_metadata.sh") do
its("stdout") { should match /tmp\/metadata\/chef.* exists/ }
its("stdout") { should match /Thank you/ }
end

# clean up
describe command("sudo dpkg -r chef") do
its("stdout") { should match /Removing chef/ }
end

#
# DOWNLOAD URL BAD CHECKSUM TESTS
#
describe command("sudo /tmp/install_bad.sh") do
its("stdout") { should match /Download URL override specified/ }
its("stdout") { should match /tmp\/bad\/chef.* not found/ }
its("stdout") { should match /Package checksum mismatch/ }
its("exit_status") { should eq 1 }
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
data "aws_ami" "ubuntu_14_ami" {
most_recent = true

filter {
name = "owner-id"
values = ["099720109477"]
}

filter {
name = "name"
values = ["ubuntu/images/*/ubuntu-*-14.04-*-server-*"]
}

filter {
name = "architecture"
values = ["x86_64"]
}

filter {
name = "virtualization-type"
values = ["hvm"]
}

filter {
name = "block-device-mapping.volume-type"
values = ["standard"]
}

filter {
name = "image-type"
values = ["machine"]
}
}

resource "aws_instance" "mixlib_install_sh" {
count = 1

ami = "${data.aws_ami.ubuntu_14_ami.id}"
instance_type = "${var.aws_instance_type}"
key_name = "es-infrastructure"

associate_public_ip_address = true

subnet_id = "subnet-11ac0174" # Planet Releng Public Subnet
source_dest_check = false

vpc_security_group_ids = [
"sg-96274af3",
]

connection {
user = "ubuntu"
private_key = "${file("${var.connection_private_key}")}"
agent = "${var.connection_agent}"
timeout = "10m"
}

tags {
# ChefOps's AWS standard tags:
X-Dept = "EngServ"
X-Contact = "pwright"
X-Production = "false"
X-Environment = "acceptance"
X-Application = "mixlib-install"
}

provisioner "file" {
source = "../../.acceptance_data/ubuntu_install_url.sh"
destination = "/tmp/install.sh"
}

provisioner "file" {
source = "../../.acceptance_data/ubuntu_install_checksum.sh"
destination = "/tmp/install_checksum.sh"
}

provisioner "file" {
source = "../../.acceptance_data/ubuntu_install_metadata.sh"
destination = "/tmp/install_metadata.sh"
}

provisioner "file" {
source = "../../.acceptance_data/ubuntu_install_bad.sh"
destination = "/tmp/install_bad.sh"
}

provisioner "remote-exec" {
inline = [
"chmod +x /tmp/install.sh",
"chmod +x /tmp/install_checksum.sh",
"chmod +x /tmp/install_metadata.sh",
"chmod +x /tmp/install_bad.sh",
]
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"version": 3,
"terraform_version": "0.9.2",
"serial": 49,
"lineage": "56ba621c-ff22-4b46-9e39-b5caa54d1f6c",
"modules": [
{
"path": [
"root"
],
"outputs": {},
"resources": {},
"depends_on": []
}
]
}
27 changes: 27 additions & 0 deletions acceptance/.suites/ubuntu_install_checksum/terraform/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Region to create infrastructure in
variable "aws_region" {
type = "string"
default = "us-west-2"
}

variable "aws_instance_type" {
type = "string"
default = "t2.micro"
}

# Used to indicidate whether the environment should be treated as "prod"
# This is mainly used for the `X-Production` AWS tag.
variable "production" {
default = "false"
}

# SSH Connection info used for remote provisioning instances
variable "connection_agent" {
description = "Set to false to disable using ssh-agent to authenticate"
default = false
}

variable "connection_private_key" {
description = "File path to AWS keypair private key to provision with"
default = "~/.ssh/es-infrastructure.pem"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
nodes/
tmp/

# Terraform
*.tfstate
*.tfstate.backup
*_override.tf

Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
name 'acceptance-cookbook'

Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
execute "terraform destroy -force" do
cwd "#{node['chef-acceptance']['suite-dir']}/terraform"
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Generate install script then write to disk for terraform to copy to the instance for execution
execute "bundle exec ruby -e \"require 'mixlib/install'; puts Mixlib::Install.new(product_name: 'chef', product_version: :latest, channel: :stable, install_command_options: {download_url_override: 'https://packages.chef.io/files/stable/chef/13.3.42/el/7/chef-13.3.42-1.el7.x86_64.rpm', cmdline_dl_dir: '/tmp/checksum'}).install_command\" > ../.acceptance_data/centos_install_url.sh" do
cwd node['chef-acceptance']['suite-dir']
end

execute "bundle exec ruby -e \"require 'mixlib/install'; puts Mixlib::Install.new(product_name: 'chef', product_version: :latest, channel: :stable, install_command_options: {download_url_override: 'https://packages.chef.io/files/stable/chef/13.3.42/el/7/chef-13.3.42-1.el7.x86_64.rpm', checksum: 'fe051b504856a74ccce1fd23ff92c296506cb8292a3933c71069ae915e7a4a00', cmdline_dl_dir: '/tmp/checksum'}).install_command\" > ../.acceptance_data/centos_install_checksum.sh" do
cwd node['chef-acceptance']['suite-dir']
end

execute "bundle exec ruby -e \"require 'mixlib/install'; puts Mixlib::Install.new(product_name: 'chef', product_version: :latest, channel: :stable, install_command_options: {cmdline_dl_dir: '/tmp/metadata'}).install_command\" > ../.acceptance_data/centos_install_metadata.sh" do
cwd node['chef-acceptance']['suite-dir']
end

execute "bundle exec ruby -e \"require 'mixlib/install'; puts Mixlib::Install.new(product_name: 'chef', product_version: :latest, channel: :stable, install_command_options: {download_url_override: 'https://packages.chef.io/files/stable/chef/13.3.42/el/7/chef-13.3.42-1.el7.x86_64.rpm', checksum: 'FOOOOOOOOOOOOOO', cmdline_dl_dir: '/tmp/bad'}).install_command\" > ../.acceptance_data/centos_install_bad.sh" do
cwd node['chef-acceptance']['suite-dir']
end

execute "terraform plan" do
cwd "#{node['chef-acceptance']['suite-dir']}/terraform"
end

execute "terraform apply" do
cwd "#{node['chef-acceptance']['suite-dir']}/terraform"
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
ruby_block "get ip" do
block do
tf_state = JSON.parse(File.read("#{node['chef-acceptance']['suite-dir']}/terraform/terraform.tfstate"))
node.default["ip"] = tf_state["modules"].first["resources"]["aws_instance.mixlib_install_sh"]["primary"]["attributes"]["public_ip"]
end
end

execute "run inspec" do
command lazy { "inspec exec verify.rb -t ssh://centos@#{node['ip']} -i ~/.ssh/es-infrastructure.pem" }
cwd "#{node['chef-acceptance']['suite-dir']}/inspec"
end
Loading