diff --git a/.bundle/config b/.bundle/config deleted file mode 100644 index 612e6ae3f3..0000000000 --- a/.bundle/config +++ /dev/null @@ -1,2 +0,0 @@ ---- -BUNDLE_CACHE_ALL: "false" diff --git a/.gitattributes b/.gitattributes deleted file mode 100644 index 70208f0116..0000000000 --- a/.gitattributes +++ /dev/null @@ -1 +0,0 @@ -/vendor/cache/*.gem filter=lfs diff=lfs merge=lfs -text diff --git a/.github/workflows/ruby.yml b/.github/workflows/ruby.yml index ad9ec9b22e..93003ceb2d 100644 --- a/.github/workflows/ruby.yml +++ b/.github/workflows/ruby.yml @@ -11,5 +11,5 @@ jobs: - name: test-bosh-stemcell run: | bundle install - bundle exec rspec + bundle exec rake working-directory: bosh-stemcell/ diff --git a/.github/workflows/sbom.yml b/.github/workflows/sbom.yml index 5d3b053f2d..0d77ab1743 100644 --- a/.github/workflows/sbom.yml +++ b/.github/workflows/sbom.yml @@ -49,7 +49,7 @@ jobs: mv tmp.sarif trivy-results-${n}.sarif done - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@v7 with: name: sbom path: sbom.spdx.json diff --git a/.rubocop.yml b/.rubocop.yml deleted file mode 100644 index d92c42104c..0000000000 --- a/.rubocop.yml +++ /dev/null @@ -1,55 +0,0 @@ -AllCops: - TargetRubyVersion: 3.0.1 - Include: - - Rakefile - Exclude: - - tmp/**/* - -Style/FrozenStringLiteralComment: - Enabled: false - -Style/ClassAndModuleChildren: - Enabled: false - -Style/Documentation: - Enabled: false - -Metrics/LineLength: - Max: 130 - -Metrics/ModuleLength: - Enabled: false - -Metrics/ClassLength: - Max: 200 - -Metrics/MethodLength: - Max: 30 - -Metrics/BlockLength: - Max: 25 - ExcludedMethods: [describe, context, let, it] - -Style/TrailingCommaInArrayLiteral: - Enabled: true - EnforcedStyleForMultiline: comma - -Style/TrailingCommaInHashLiteral: - Enabled: true - EnforcedStyleForMultiline: comma - -Style/TrailingCommaInArguments: - Enabled: true - EnforcedStyleForMultiline: comma - -Layout/MultilineMethodCallIndentation: - EnforcedStyle: aligned - -Metrics/AbcSize: - Enabled: false - -Style/BracesAroundHashParameters: - EnforcedStyle: context_dependent - -Layout/IndentHash: - EnforcedStyle: consistent diff --git a/Gemfile b/Gemfile index b078f1f3c3..5158c13c83 100644 --- a/Gemfile +++ b/Gemfile @@ -1,12 +1,4 @@ source 'https://rubygems.org' -group :development, :test do - gem 'bosh-stemcell', path: 'bosh-stemcell' - gem 'fakefs' - gem 'logging' - gem 'rake' - gem 'rspec' - gem 'rspec-instafail' - gem 'rspec-its' - gem 'timecop' -end +gem 'rake' +gem 'bosh-stemcell', path: 'bosh-stemcell' diff --git a/Gemfile.lock b/Gemfile.lock index 04958045b2..541f2268e8 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -2,17 +2,14 @@ PATH remote: bosh-stemcell specs: bosh-stemcell (0.0.0) + rake + rspec + rspec-its GEM remote: https://rubygems.org/ specs: diff-lcs (1.6.2) - fakefs (3.2.1) - little-plugger (1.1.4) - logging (2.4.0) - little-plugger (~> 1.1) - multi_json (~> 1.14) - multi_json (1.20.0) rake (13.3.1) rspec (3.13.2) rspec-core (~> 3.13.0) @@ -23,8 +20,6 @@ GEM rspec-expectations (3.13.5) diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.13.0) - rspec-instafail (1.0.0) - rspec rspec-its (2.0.0) rspec-core (>= 3.13.0) rspec-expectations (>= 3.13.0) @@ -32,20 +27,13 @@ GEM diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.13.0) rspec-support (3.13.7) - timecop (0.9.10) PLATFORMS ruby DEPENDENCIES bosh-stemcell! - fakefs - logging rake - rspec - rspec-instafail - rspec-its - timecop BUNDLED WITH 2.5.23 diff --git a/README.md b/README.md index c53cefb513..ae673ea45b 100644 --- a/README.md +++ b/README.md @@ -137,6 +137,7 @@ container): ```shell export short_name="noble" cd /opt/bosh/bosh-stemcell + bundle install OS_IMAGE=/opt/bosh/tmp/ubuntu_base_image.tgz bundle exec rspec -fd spec/os_image/ubuntu_${short_name}_spec.rb ``` @@ -150,6 +151,7 @@ container, you should be able to run the specific tests: ```shell cd /opt/bosh/bosh-stemcell; \ +bundle install; \ STEMCELL_IMAGE=/mnt/stemcells/vsphere/esxi/ubuntu/work/work/vsphere-esxi-ubuntu.raw \ STEMCELL_WORKDIR=/mnt/stemcells/vsphere/esxi/ubuntu/work/work/chroot \ OS_NAME=ubuntu \ @@ -173,15 +175,9 @@ an ubuntu chroot environment to run. For this reason, we use the locally, run: ```shell -bundle install --local cd /opt/bosh/bosh-stemcell -OS_IMAGE=/opt/bosh/tmp/ubuntu_base_image.tgz bundle exec rspec spec/ --tag shellout_types -``` - -If on macOS, run: - -```shell -OSX=true OS_IMAGE=/opt/bosh/tmp/ubuntu_base_image.tgz bundle exec rspec spec/ --tag shellout_types +bundle install +OS_IMAGE=/opt/bosh/tmp/ubuntu_base_image.tgz bundle exec rake spec:shellout_types ``` ### How to run tests for BOSH Linux Stemcell Builder @@ -189,9 +185,9 @@ OSX=true OS_IMAGE=/opt/bosh/tmp/ubuntu_base_image.tgz bundle exec rspec spec/ -- The BOSH Linux Stemcell Builder code itself can be tested with the following command's: ```shell -bundle install --local cd /opt/bosh/bosh-stemcell -bundle exec rspec spec/ +bundle install +bundle exec rake ``` ## Troubleshooting diff --git a/Rakefile b/Rakefile index f668764110..ac59a00fa2 100644 --- a/Rakefile +++ b/Rakefile @@ -1,5 +1,4 @@ require 'json' -require 'logging' namespace :stemcell do desc 'Build a base OS image for use in stemcells' diff --git a/bosh-stemcell/.rubocop.yml b/bosh-stemcell/.rubocop.yml deleted file mode 100644 index 253a6a720e..0000000000 --- a/bosh-stemcell/.rubocop.yml +++ /dev/null @@ -1,63 +0,0 @@ -AllCops: - TargetRubyVersion: 3.2.0 - -# Layout -Layout/IndentHash: - EnforcedStyle: consistent - -Layout/MultilineMethodCallIndentation: - EnforcedStyle: aligned - -# Metrics -Metrics/AbcSize: - Enabled: false - -Metrics/BlockLength: - Max: 25 - ExcludedMethods: [describe, context, let, it] - -Metrics/ClassLength: - Max: 200 - -Metrics/LineLength: - Max: 130 - -Metrics/MethodLength: - Max: 30 - -Metrics/ModuleLength: - Enabled: false - -Metrics/ParameterLists: - CountKeywordArgs: false - -# Style -Style/BracesAroundHashParameters: - EnforcedStyle: context_dependent - -Style/ClassAndModuleChildren: - Enabled: false - -Style/Documentation: - Enabled: false - -Style/FrozenStringLiteralComment: - Enabled: false - -Style/NumericLiterals: - Enabled: false - -Style/TrailingCommaInArrayLiteral: - Enabled: true - EnforcedStyleForMultiline: comma - -Style/TrailingCommaInHashLiteral: - Enabled: true - EnforcedStyleForMultiline: comma - -Style/TrailingCommaInArguments: - Enabled: true - EnforcedStyleForMultiline: comma - -Style/MultilineBlockChain: - Enabled: false diff --git a/bosh-stemcell/Gemfile b/bosh-stemcell/Gemfile new file mode 100644 index 0000000000..b4e2a20bb6 --- /dev/null +++ b/bosh-stemcell/Gemfile @@ -0,0 +1,3 @@ +source "https://rubygems.org" + +gemspec diff --git a/bosh-stemcell/Rakefile b/bosh-stemcell/Rakefile new file mode 100644 index 0000000000..e812f462ea --- /dev/null +++ b/bosh-stemcell/Rakefile @@ -0,0 +1,12 @@ +require "rspec/core/rake_task" +require "standard/rake" + +task default: [:standard, :spec] + +RSpec::Core::RakeTask.new(:spec) + +namespace :spec do + RSpec::Core::RakeTask.new(:shellout_types) do |t| + t.rspec_opts = "--tag shellout_types" + end +end diff --git a/bosh-stemcell/bosh-stemcell.gemspec b/bosh-stemcell/bosh-stemcell.gemspec index b6e437a96b..89ab0658d2 100644 --- a/bosh-stemcell/bosh-stemcell.gemspec +++ b/bosh-stemcell/bosh-stemcell.gemspec @@ -1,22 +1,30 @@ -# coding: utf-8 -require File.expand_path('../lib/bosh/stemcell/version', __FILE__) +require File.expand_path("../lib/bosh/stemcell/version", __FILE__) version = Bosh::Stemcell::VERSION Gem::Specification.new do |spec| - spec.name = 'bosh-stemcell' - spec.version = version - spec.authors = 'Pivotal' - spec.email = 'support@cloudfoundry.com' - spec.description = 'Bosh::Stemcell provides tools to manage stemcells' - spec.summary = 'Bosh::Stemcell provides tools to manage stemcells' - spec.homepage = 'https://github.com/cloudfoundry/bosh' - spec.license = 'Apache 2.0' + spec.name = "bosh-stemcell" + spec.version = version + spec.authors = "Pivotal" + spec.email = "support@cloudfoundry.com" + spec.description = "Bosh::Stemcell provides tools to manage stemcells" + spec.summary = "Bosh::Stemcell provides tools to manage stemcells" + spec.homepage = "https://github.com/cloudfoundry/bosh" + spec.license = "Apache 2.0" - spec.required_ruby_version = Gem::Requirement.new('>= 1.9.3') + spec.required_ruby_version = Gem::Requirement.new(">= 1.9.3") - spec.files = Dir['README.md', 'lib/**/*'].select{ |f| File.file? f } - spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) } - spec.test_files = spec.files.grep(%r{^(test|spec|features)/}) + spec.files = Dir["README.md", "lib/**/*"].select { |f| File.file? f } + spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) } spec.require_paths = %w[lib] + + # TODO: separate stemcell specs from gem specs + spec.add_dependency "rake" + spec.add_dependency "rspec" + spec.add_dependency "rspec-its" + + # used only in gem's own specs + spec.add_development_dependency "fakefs" + spec.add_development_dependency "standard" + spec.add_development_dependency "timecop" end diff --git a/bosh-stemcell/lib/bosh/core/shell.rb b/bosh-stemcell/lib/bosh/core/shell.rb index a28ef23f2c..59a668c112 100644 --- a/bosh-stemcell/lib/bosh/core/shell.rb +++ b/bosh-stemcell/lib/bosh/core/shell.rb @@ -21,12 +21,12 @@ def run_command(command, options) stdout.puts command if options[:output_command] lines = [] - if options[:env] + popen_args = if options[:env] # Wrap in a shell because existing api to Shell#run takes a string # which makes it really hard to pass it to popen with custom environment. - popen_args = [options[:env], ENV['SHELL'] || 'bash', '-c', command] + [options[:env], ENV["SHELL"] || "bash", "-c", command] else - popen_args = command + command end io = IO.popen(popen_args) @@ -50,7 +50,7 @@ def report(cmd, command_output, options) redacted_cmd = cmd if options[:redact] - redacted_cmd = redacted_cmd.gsub(/#{options[:redact].join('|')}/, "[REDACTED]") + redacted_cmd = redacted_cmd.gsub(/#{options[:redact].join("|")}/, "[REDACTED]") end err_msg = "Failed: '#{redacted_cmd}' from #{pwd}, with exit status #{$?.to_i}\n\n #{command_output}" @@ -64,7 +64,7 @@ def command_exited_successfully? def pwd Dir.pwd rescue Errno::ENOENT - 'a deleted directory' + "a deleted directory" end end end diff --git a/bosh-stemcell/lib/bosh/stemcell/arch.rb b/bosh-stemcell/lib/bosh/stemcell/arch.rb index 15a5017ec5..4e91c23b21 100644 --- a/bosh-stemcell/lib/bosh/stemcell/arch.rb +++ b/bosh-stemcell/lib/bosh/stemcell/arch.rb @@ -1,11 +1,11 @@ module Bosh::Stemcell class Arch def self.arch - RbConfig::CONFIG['host_cpu'] + RbConfig::CONFIG["host_cpu"] end def self.x86_64? - arch == 'x86_64' + arch == "x86_64" end end end diff --git a/bosh-stemcell/lib/bosh/stemcell/archive.rb b/bosh-stemcell/lib/bosh/stemcell/archive.rb index 4253da89ce..2e5f790511 100644 --- a/bosh-stemcell/lib/bosh/stemcell/archive.rb +++ b/bosh-stemcell/lib/bosh/stemcell/archive.rb @@ -1,12 +1,12 @@ -require 'yaml' -require 'rake/file_utils_ext' -require 'bosh/stemcell/aws/region' +require "yaml" +require "rake/file_utils_ext" +require "bosh/stemcell/aws/region" module Bosh::Stemcell class Archive attr_reader :path - def initialize(path = '') + def initialize(path = "") @path = path validate_stemcell end @@ -16,25 +16,25 @@ def manifest end def name - manifest.fetch('name') + manifest.fetch("name") end def infrastructure - cloud_properties.fetch('infrastructure') + cloud_properties.fetch("infrastructure") end def version - cloud_properties.fetch('version') + cloud_properties.fetch("version") end def sha1 - sha1 = manifest.fetch('sha1') - raise 'sha1 must not be nil' unless sha1 + sha1 = manifest.fetch("sha1") + raise "sha1 must not be nil" unless sha1 sha1.to_s end def light? - infrastructure == 'aws' && has_ami? + infrastructure == "aws" && has_ami? end def extract(tar_options = {}, &block) @@ -51,11 +51,11 @@ def extract(tar_options = {}, &block) private def has_ami? - cloud_properties.has_key? 'ami' + cloud_properties.has_key? "ami" end def cloud_properties - manifest.fetch('cloud_properties') + manifest.fetch("cloud_properties") end def validate_stemcell diff --git a/bosh-stemcell/lib/bosh/stemcell/archive_filename.rb b/bosh-stemcell/lib/bosh/stemcell/archive_filename.rb index 7006dc5f8d..b15f134ff6 100644 --- a/bosh-stemcell/lib/bosh/stemcell/archive_filename.rb +++ b/bosh-stemcell/lib/bosh/stemcell/archive_filename.rb @@ -1,5 +1,5 @@ -require 'bosh/stemcell/arch' -require 'forwardable' +require "bosh/stemcell/arch" +require "forwardable" module Bosh::Stemcell class ArchiveFilename @@ -19,7 +19,7 @@ def to_s definition.stemcell_name(disk_format) ] - "#{stemcell_filename_parts.join('-')}.tgz" + "#{stemcell_filename_parts.join("-")}.tgz" end private @@ -28,7 +28,7 @@ def to_s :base_name, :version, :definition, - :disk_format, + :disk_format ) end end diff --git a/bosh-stemcell/lib/bosh/stemcell/aws/region.rb b/bosh-stemcell/lib/bosh/stemcell/aws/region.rb index 2301f4a028..c0306824d1 100644 --- a/bosh-stemcell/lib/bosh/stemcell/aws/region.rb +++ b/bosh-stemcell/lib/bosh/stemcell/aws/region.rb @@ -1,15 +1,15 @@ -require 'net/http' +require "net/http" module Bosh module Stemcell module Aws class Region - DEFAULT = 'us-east-1' - REGIONS = %w{ + DEFAULT = "us-east-1" + REGIONS = %w[ us-east-1 us-west-1 us-west-2 eu-west-1 eu-central-1 ap-southeast-1 ap-southeast-2 ap-northeast-1 ap-northeast-2 sa-east-1 - } + ] end end end diff --git a/bosh-stemcell/lib/bosh/stemcell/build_environment.rb b/bosh-stemcell/lib/bosh/stemcell/build_environment.rb index 009804e618..9ed462be6c 100644 --- a/bosh-stemcell/lib/bosh/stemcell/build_environment.rb +++ b/bosh-stemcell/lib/bosh/stemcell/build_environment.rb @@ -1,15 +1,15 @@ -require 'bosh/core/shell' -require 'bosh/stemcell/builder_options' -require 'bosh/stemcell/stemcell' -require 'forwardable' +require "bosh/core/shell" +require "bosh/stemcell/builder_options" +require "bosh/stemcell/stemcell" +require "forwardable" module Bosh::Stemcell class BuildEnvironment extend Forwardable - BUILD_TIME_MARKER_FILE = File.join(File.expand_path('../../../../..', __FILE__), 'build_time.txt') - STEMCELL_BUILDER_SOURCE_DIR = File.join(File.expand_path('../../../../..', __FILE__), 'stemcell_builder') - STEMCELL_SPECS_DIR = File.expand_path('../../..', File.dirname(__FILE__)) + BUILD_TIME_MARKER_FILE = File.join(File.expand_path("../../../../..", __FILE__), "build_time.txt") + STEMCELL_BUILDER_SOURCE_DIR = File.join(File.expand_path("../../../../..", __FILE__), "stemcell_builder") + STEMCELL_SPECS_DIR = File.expand_path("../../..", File.dirname(__FILE__)) def initialize(env, definition, version, os_image_tarball_path) @environment = env @@ -20,7 +20,7 @@ def initialize(env, definition, version, os_image_tarball_path) env: env, definition: definition, version: version, - os_image_tarball: os_image_tarball_path, + os_image_tarball: os_image_tarball_path ) @shell = Bosh::Core::Shell.new end @@ -28,7 +28,7 @@ def initialize(env, definition, version, os_image_tarball_path) attr_reader :version def prepare_build - if ENV['resume_from'].nil? + if ENV["resume_from"].nil? sanitize prepare_build_path end @@ -43,8 +43,8 @@ def os_image_rspec_command "cd #{STEMCELL_SPECS_DIR};", "OS_IMAGE=#{os_image_tarball_path}", "bundle exec rspec -fd", - "spec/os_image/#{operating_system_spec_name}_spec.rb", - ].join(' ') + "spec/os_image/#{operating_system_spec_name}_spec.rb" + ].join(" ") end def stemcell_rspec_command @@ -59,36 +59,36 @@ def stemcell_rspec_command "bundle exec rspec -fd#{exclude_exclusions}", "spec/os_image/#{operating_system_spec_name}_spec.rb", "spec/stemcells/#{operating_system_spec_name}_spec.rb", - 'spec/stemcells/go_agent_spec.rb', + "spec/stemcells/go_agent_spec.rb", "spec/stemcells/#{infrastructure.name}_spec.rb", - 'spec/stemcells/stig_spec.rb', - 'spec/stemcells/cis_spec.rb' + "spec/stemcells/stig_spec.rb", + "spec/stemcells/cis_spec.rb" ] cmd << "spec/stemcells/#{operating_system.variant}_spec.rb" if operating_system.variant? - cmd.join(' ') + cmd.join(" ") end def build_path - File.join(build_root, 'build') + File.join(build_root, "build") end def stemcell_files definition.disk_formats.map do |disk_format| - stemcell_filename = Stemcell.new(@definition, 'bosh-stemcell', @version, disk_format) + stemcell_filename = Stemcell.new(@definition, "bosh-stemcell", @version, disk_format) File.join(work_path, stemcell_filename.name) end end def chroot_dir - File.join(work_path, 'chroot') + File.join(work_path, "chroot") end def settings_path - File.join(build_path, 'etc', 'settings.bash') + File.join(build_path, "etc", "settings.bash") end def work_path - File.join(work_root, 'work') + File.join(work_root, "work") end def stemcell_tarball_path @@ -109,7 +109,7 @@ def command_env :@definition, :infrastructure, :operating_system, - :agent, + :agent ) attr_reader( @@ -117,31 +117,31 @@ def command_env :environment, :definition, :stemcell_builder_options, - :os_image_tarball_path, + :os_image_tarball_path ) def sanitize - FileUtils.rm(Dir.glob('*.tgz')) + FileUtils.rm(Dir.glob("*.tgz")) - shell.run("sudo umount #{File.join(work_path, 'mnt/tmp/grub', settings['stemcell_image_name'])} 2> /dev/null", - { ignore_failures: true }) + shell.run("sudo umount #{File.join(work_path, "mnt/tmp/grub", settings["stemcell_image_name"])} 2> /dev/null", + {ignore_failures: true}) - shell.run("sudo umount #{image_mount_point} 2> /dev/null", { ignore_failures: true }) + shell.run("sudo umount #{image_mount_point} 2> /dev/null", {ignore_failures: true}) - shell.run("sudo rm -rf #{base_directory}", { ignore_failures: true }) + shell.run("sudo rm -rf #{base_directory}", {ignore_failures: true}) end def build_time_settings if File.exist?(BUILD_TIME_MARKER_FILE) - return { 'BUILD_TIME' => File.read(BUILD_TIME_MARKER_FILE).chomp } - elsif environment['BUILD_TIME'] - return { 'BUILD_TIME' => environment['BUILD_TIME'] } + return {"BUILD_TIME" => File.read(BUILD_TIME_MARKER_FILE).chomp} + elsif environment["BUILD_TIME"] + return {"BUILD_TIME" => environment["BUILD_TIME"]} end {} end def operating_system_spec_name - "#{operating_system.name}" + operating_system.name.to_s end def prepare_build_path @@ -150,7 +150,7 @@ def prepare_build_path end def prepare_stemcell_path - FileUtils.mkdir_p(File.join(work_path, 'stemcell')) + FileUtils.mkdir_p(File.join(work_path, "stemcell")) end def copy_stemcell_builder_to_build_path @@ -162,8 +162,8 @@ def prepare_work_root end def persist_settings_for_bash - File.open(settings_path, 'a') do |f| - f.printf("\n# %s\n\n", '=' * 20) + File.open(settings_path, "a") do |f| + f.printf("\n# %s\n\n", "=" * 20) settings.each do |k, v| f.print "#{k}=#{v}\n" end @@ -172,38 +172,36 @@ def persist_settings_for_bash def exclude_exclusions [ - case infrastructure.name - when 'alicloud' - ' --tag ~exclude_on_alicloud' - when 'vsphere' - ' --tag ~exclude_on_vsphere' - when 'warden' - ' --tag ~exclude_on_warden' - when 'aws' - ' --tag ~exclude_on_aws' - when 'openstack' - ' --tag ~exclude_on_openstack' - when 'cloudstack' - ' --tag ~exclude_on_cloudstack' - when 'azure' - ' --tag ~exclude_on_azure' - when 'google' - ' --tag ~exclude_on_google' - else - nil - end, - if operating_system.variant? - " --tag ~exclude_on_#{operating_system.variant}" - end, - ].compact.join(' ').rstrip + case infrastructure.name + when "alicloud" + " --tag ~exclude_on_alicloud" + when "vsphere" + " --tag ~exclude_on_vsphere" + when "warden" + " --tag ~exclude_on_warden" + when "aws" + " --tag ~exclude_on_aws" + when "openstack" + " --tag ~exclude_on_openstack" + when "cloudstack" + " --tag ~exclude_on_cloudstack" + when "azure" + " --tag ~exclude_on_azure" + when "google" + " --tag ~exclude_on_google" + end, + if operating_system.variant? + " --tag ~exclude_on_#{operating_system.variant}" + end + ].compact.join(" ").rstrip end def image_file_path - File.join(work_path, settings['stemcell_image_name']) + File.join(work_path, settings["stemcell_image_name"]) end def image_mount_point - File.join(work_path, 'mnt') + File.join(work_path, "mnt") end def settings @@ -211,25 +209,25 @@ def settings end def base_directory - File.join('/mnt', 'stemcells', infrastructure.name, infrastructure.hypervisor, operating_system.name) + File.join("/mnt", "stemcells", infrastructure.name, infrastructure.hypervisor, operating_system.name) end def build_root - File.join(base_directory, 'build') + File.join(base_directory, "build") end def work_root - File.join(base_directory, 'work') + File.join(base_directory, "work") end def proxy_settings_from_environment - keep = %w(HTTP_PROXY HTTPS_PROXY NO_PROXY) + keep = %w[HTTP_PROXY HTTPS_PROXY NO_PROXY] environment.select { |k| keep.include?(k.upcase) } end def hash_as_bash_env(env) - env.map { |k, v| "#{k}='#{v}'" }.join(' ') + env.map { |k, v| "#{k}='#{v}'" }.join(" ") end end end diff --git a/bosh-stemcell/lib/bosh/stemcell/builder_options.rb b/bosh-stemcell/lib/bosh/stemcell/builder_options.rb index 5e8b7dd032..b7464b97bf 100644 --- a/bosh-stemcell/lib/bosh/stemcell/builder_options.rb +++ b/bosh-stemcell/lib/bosh/stemcell/builder_options.rb @@ -1,6 +1,6 @@ -require 'rbconfig' -require 'forwardable' -require 'bosh/stemcell/archive_filename' +require "rbconfig" +require "forwardable" +require "bosh/stemcell/archive_filename" module Bosh::Stemcell class BuilderOptions @@ -17,22 +17,22 @@ def initialize(dependencies = {}) def default { - 'stemcell_image_name' => stemcell_image_name, - 'stemcell_version' => stemcell_version, - 'stemcell_hypervisor' => infrastructure.hypervisor, - 'stemcell_infrastructure' => infrastructure.name, - 'stemcell_operating_system' => operating_system.name, - 'stemcell_operating_system_version' => operating_system.version, - 'stemcell_operating_system_variant' => operating_system.variant, - 'ruby_bin' => ruby_bin, - 'image_create_disk_size' => image_create_disk_size, - 'os_image_tgz' => os_image_tgz_path, + "stemcell_image_name" => stemcell_image_name, + "stemcell_version" => stemcell_version, + "stemcell_hypervisor" => infrastructure.hypervisor, + "stemcell_infrastructure" => infrastructure.name, + "stemcell_operating_system" => operating_system.name, + "stemcell_operating_system_version" => operating_system.version, + "stemcell_operating_system_variant" => operating_system.variant, + "ruby_bin" => ruby_bin, + "image_create_disk_size" => image_create_disk_size, + "os_image_tgz" => os_image_tgz_path }.merge(environment_variables).merge(ovf_options) end attr_reader( :stemcell_version, - :image_create_disk_size, + :image_create_disk_size ) private @@ -41,18 +41,18 @@ def default :@definition, :infrastructure, :operating_system, - :agent, + :agent ) attr_reader( :environment, :definition, - :os_image_tgz_path, + :os_image_tgz_path ) def ovf_options - if infrastructure.name == 'vsphere' - { 'image_ovftool_path' => environment['OVFTOOL'] } + if infrastructure.name == "vsphere" + {"image_ovftool_path" => environment["OVFTOOL"]} else {} end @@ -60,10 +60,10 @@ def ovf_options def environment_variables { - 'UBUNTU_ISO' => environment['UBUNTU_ISO'], - 'UBUNTU_MIRROR' => environment['UBUNTU_MIRROR'], - 'UBUNTU_ADVANTAGE_TOKEN' => environment['UBUNTU_ADVANTAGE_TOKEN'], - 'UBUNTU_FIPS_USE_IAAS_KERNEL' => environment['UBUNTU_FIPS_USE_IAAS_KERNEL'], + "UBUNTU_ISO" => environment["UBUNTU_ISO"], + "UBUNTU_MIRROR" => environment["UBUNTU_MIRROR"], + "UBUNTU_ADVANTAGE_TOKEN" => environment["UBUNTU_ADVANTAGE_TOKEN"], + "UBUNTU_FIPS_USE_IAAS_KERNEL" => environment["UBUNTU_FIPS_USE_IAAS_KERNEL"] } end @@ -72,11 +72,11 @@ def stemcell_image_name end def ruby_bin - environment['RUBY_BIN'] || File.join(RbConfig::CONFIG['bindir'], RbConfig::CONFIG['ruby_install_name']) + environment["RUBY_BIN"] || File.join(RbConfig::CONFIG["bindir"], RbConfig::CONFIG["ruby_install_name"]) end def source_root - File.expand_path('../../../../..', __FILE__) + File.expand_path("../../../../..", __FILE__) end end end diff --git a/bosh-stemcell/lib/bosh/stemcell/definition.rb b/bosh-stemcell/lib/bosh/stemcell/definition.rb index 714c2c9ce4..ac6fabd5a8 100644 --- a/bosh-stemcell/lib/bosh/stemcell/definition.rb +++ b/bosh-stemcell/lib/bosh/stemcell/definition.rb @@ -1,5 +1,5 @@ -require 'bosh/stemcell/infrastructure' -require 'bosh/stemcell/operating_system' +require "bosh/stemcell/infrastructure" +require "bosh/stemcell/operating_system" module Bosh::Stemcell class Definition @@ -9,7 +9,7 @@ def self.for(infrastructure_name, hypervisor_name, operating_system_name, operat new( Bosh::Stemcell::Infrastructure.for(infrastructure_name), hypervisor_name, - Bosh::Stemcell::OperatingSystem.for(operating_system_name, operating_system_version), + Bosh::Stemcell::OperatingSystem.for(operating_system_name, operating_system_version) ) end @@ -23,13 +23,13 @@ def stemcell_name(disk_format) stemcell_name_parts = [ infrastructure.name, hypervisor_name, - operating_system.name, + operating_system.name ] stemcell_name_parts << operating_system.version if operating_system.version stemcell_name_parts << operating_system.variant if operating_system.variant stemcell_name_parts << disk_format unless disk_format == infrastructure.default_disk_format - stemcell_name_parts.join('-') + stemcell_name_parts.join("-") end def disk_formats diff --git a/bosh-stemcell/lib/bosh/stemcell/disk_image.rb b/bosh-stemcell/lib/bosh/stemcell/disk_image.rb index b2ce1c3ac0..4beb10a2f7 100644 --- a/bosh-stemcell/lib/bosh/stemcell/disk_image.rb +++ b/bosh-stemcell/lib/bosh/stemcell/disk_image.rb @@ -1,16 +1,15 @@ -require 'bosh/core/shell' -require 'bosh/stemcell/arch' +require "bosh/core/shell" +require "bosh/stemcell/arch" module Bosh::Stemcell class DiskImage - attr_reader :image_mount_point def initialize(options) - @image_file_path = options.fetch(:image_file_path) + @image_file_path = options.fetch(:image_file_path) @image_mount_point = options.fetch(:image_mount_point, Dir.mktmpdir) - @verbose = options.fetch(:verbose, false) - @shell = Bosh::Core::Shell.new + @verbose = options.fetch(:verbose, false) + @shell = Bosh::Core::Shell.new end def mount @@ -43,24 +42,24 @@ def mount_image end def efi_image - return map_image.lines.length > 1 + map_image.lines.length > 1 end def stemcell_loopback_device_name - split_output = map_image.split(' ') - device_name = split_output[2] + split_output = map_image.split(" ") + device_name = split_output[2] - File.join('/dev/mapper', device_name) + File.join("/dev/mapper", device_name) end def stemcell_loopback_boot_name - efi_partition = map_image.lines.last.split(' ')[2] - File.join('/dev/mapper', efi_partition) + efi_partition = map_image.lines.last.split(" ")[2] + File.join("/dev/mapper", efi_partition) end def stemcell_loopback_efi_name - efi_partition = map_image.lines.first.split(' ')[2] - File.join('/dev/mapper', efi_partition) + efi_partition = map_image.lines.first.split(" ")[2] + File.join("/dev/mapper", efi_partition) end def map_image @@ -75,4 +74,4 @@ def unmap_image shell.run("sudo losetup -v -d #{device}", output_command: verbose) end end -end \ No newline at end of file +end diff --git a/bosh-stemcell/lib/bosh/stemcell/infrastructure.rb b/bosh-stemcell/lib/bosh/stemcell/infrastructure.rb index f94eb323ca..88079bac24 100644 --- a/bosh-stemcell/lib/bosh/stemcell/infrastructure.rb +++ b/bosh-stemcell/lib/bosh/stemcell/infrastructure.rb @@ -2,26 +2,26 @@ module Bosh::Stemcell module Infrastructure def self.for(name) case name - when 'openstack' - OpenStack.new - when 'aws' - Aws.new - when 'alicloud' - Alicloud.new - when 'google' - Google.new - when 'vsphere' - Vsphere.new - when 'warden' - Warden.new - when 'azure' - Azure.new - when 'cloudstack' - CloudStack.new - when 'null' - NullInfrastructure.new - else - raise ArgumentError.new("invalid infrastructure: #{name}") + when "openstack" + OpenStack.new + when "aws" + Aws.new + when "alicloud" + Alicloud.new + when "google" + Google.new + when "vsphere" + Vsphere.new + when "warden" + Warden.new + when "azure" + Azure.new + when "cloudstack" + CloudStack.new + when "null" + NullInfrastructure.new + else + raise ArgumentError.new("invalid infrastructure: #{name}") end end @@ -54,8 +54,8 @@ def ==(other) class NullInfrastructure < Base def initialize super( - name: 'null', - hypervisor: 'null', + name: "null", + hypervisor: "null", default_disk_size: -1, disk_formats: [], stemcell_formats: [] @@ -66,65 +66,65 @@ def initialize class OpenStack < Base def initialize super( - name: 'openstack', - hypervisor: 'kvm', + name: "openstack", + hypervisor: "kvm", default_disk_size: 5120, - disk_formats: ['qcow2', 'raw'], - stemcell_formats: ['openstack-qcow2', 'openstack-raw'] + disk_formats: ["qcow2", "raw"], + stemcell_formats: ["openstack-qcow2", "openstack-raw"] ) end def additional_cloud_properties - {'auto_disk_config' => true} + {"auto_disk_config" => true} end end class CloudStack < Base def initialize super( - name: 'cloudstack', - hypervisor: 'xen', + name: "cloudstack", + hypervisor: "xen", default_disk_size: 5120, - disk_formats: ['vhdx'], - stemcell_formats: ['cloudstack-vhdx'] + disk_formats: ["vhdx"], + stemcell_formats: ["cloudstack-vhdx"] ) end def additional_cloud_properties - {'auto_disk_config' => true} + {"auto_disk_config" => true} end end class Vsphere < Base def initialize - super(name: 'vsphere', - hypervisor: 'esxi', - default_disk_size: 5120, - disk_formats: ['ovf'], - stemcell_formats: ['vsphere-ova', 'vsphere-ovf'] + super(name: "vsphere", + hypervisor: "esxi", + default_disk_size: 5120, + disk_formats: ["ovf"], + stemcell_formats: ["vsphere-ova", "vsphere-ovf"] ) end def additional_cloud_properties - {'root_device_name' => '/dev/sda1'} + {"root_device_name" => "/dev/sda1"} end end class Aws < Base def initialize super( - name: 'aws', - hypervisor: 'xen', + name: "aws", + hypervisor: "xen", default_disk_size: 5120, - disk_formats: ['raw'], - stemcell_formats: ['aws-raw'] + disk_formats: ["raw"], + stemcell_formats: ["aws-raw"] ) end def additional_cloud_properties { - 'root_device_name' => '/dev/sda1', - 'boot_mode' => 'uefi-preferred', + "root_device_name" => "/dev/sda1", + "boot_mode" => "uefi-preferred" } end end @@ -132,72 +132,71 @@ def additional_cloud_properties class Alicloud < Base def initialize super( - name: 'alicloud', - hypervisor: 'kvm', + name: "alicloud", + hypervisor: "kvm", default_disk_size: 5120, - disk_formats: ['raw'], - stemcell_formats: ['alicloud-raw'] + disk_formats: ["raw"], + stemcell_formats: ["alicloud-raw"] ) end def additional_cloud_properties - {'root_device_name' => '/dev/vda1'} + {"root_device_name" => "/dev/vda1"} end end class Google < Base def initialize - super(name: 'google', - hypervisor: 'kvm', - default_disk_size: 5120, - disk_formats: ['rawdisk'], - stemcell_formats: ['google-rawdisk'] - ) + super(name: "google", + hypervisor: "kvm", + default_disk_size: 5120, + disk_formats: ["rawdisk"], + stemcell_formats: ["google-rawdisk"] + ) end def additional_cloud_properties - {'root_device_name' => '/dev/sda1'} + {"root_device_name" => "/dev/sda1"} end end class Warden < Base def initialize super( - name: 'warden', - hypervisor: 'boshlite', + name: "warden", + hypervisor: "boshlite", default_disk_size: 5120, - disk_formats: ['files'], - stemcell_formats: ['warden-tar'] + disk_formats: ["files"], + stemcell_formats: ["warden-tar"] ) end def additional_cloud_properties - {'root_device_name' => '/dev/sda1'} + {"root_device_name" => "/dev/sda1"} end end class Azure < Base def initialize super( - name: 'azure', - hypervisor: 'hyperv', + name: "azure", + hypervisor: "hyperv", default_disk_size: 5120, - disk_formats: ['vhd'], - stemcell_formats: ['azure-vhd'] + disk_formats: ["vhd"], + stemcell_formats: ["azure-vhd"] ) end def additional_cloud_properties { - 'root_device_name' => '/dev/sda1', - 'generation' => 'gen2', - 'accelerated_networking' => true, - 'hibernation' => true, - 'disk_controller_types' => ['scsi', 'nvme'], - 'security_type' => 'TrustedLaunchSupported' + "root_device_name" => "/dev/sda1", + "generation" => "gen2", + "accelerated_networking" => true, + "hibernation" => true, + "disk_controller_types" => ["scsi", "nvme"], + "security_type" => "TrustedLaunchSupported" } end end - end end diff --git a/bosh-stemcell/lib/bosh/stemcell/operating_system.rb b/bosh-stemcell/lib/bosh/stemcell/operating_system.rb index 3cb9678d6c..7c9e202ea3 100644 --- a/bosh-stemcell/lib/bosh/stemcell/operating_system.rb +++ b/bosh-stemcell/lib/bosh/stemcell/operating_system.rb @@ -1,10 +1,9 @@ module Bosh::Stemcell module OperatingSystem - def self.for(operating_system_name, operating_system_version = nil) case operating_system_name - when 'ubuntu' then Ubuntu.new(operating_system_version) - else raise ArgumentError.new("invalid operating system: #{operating_system_name}") + when "ubuntu" then Ubuntu.new(operating_system_version) + else raise ArgumentError.new("invalid operating system: #{operating_system_name}") end end @@ -25,8 +24,8 @@ def ==(other) class Ubuntu < Base def initialize(version) - (version, variant) = version.split('-') if version - super(name: 'ubuntu', version: version, variant: variant) + (version, variant) = version.split("-") if version + super(name: "ubuntu", version: version, variant: variant) end end end diff --git a/bosh-stemcell/lib/bosh/stemcell/os_image_builder.rb b/bosh-stemcell/lib/bosh/stemcell/os_image_builder.rb index 991f074f5b..b0d4bd546f 100644 --- a/bosh-stemcell/lib/bosh/stemcell/os_image_builder.rb +++ b/bosh-stemcell/lib/bosh/stemcell/os_image_builder.rb @@ -9,7 +9,7 @@ def initialize(dependencies = {}) def build(os_image_path) environment.prepare_build - runner.configure_and_apply(collection.operating_system_stages, ENV['resume_from']) + runner.configure_and_apply(collection.operating_system_stages, ENV["resume_from"]) archive_handler.compress(environment.chroot_dir, os_image_path) end diff --git a/bosh-stemcell/lib/bosh/stemcell/stage_collection.rb b/bosh-stemcell/lib/bosh/stemcell/stage_collection.rb index ef3076d3d4..4b64f86f0e 100644 --- a/bosh-stemcell/lib/bosh/stemcell/stage_collection.rb +++ b/bosh-stemcell/lib/bosh/stemcell/stage_collection.rb @@ -1,7 +1,7 @@ -require 'bosh/stemcell/definition' -require 'forwardable' +require "bosh/stemcell/definition" +require "forwardable" -# rubocop:disable ClassLength +# rubocop:disable Metrics/ClassLength module Bosh::Stemcell class StageCollection extend Forwardable @@ -31,7 +31,7 @@ def kernel_stages def extract_operating_system_stages [ - :untar_base_os_image, + :untar_base_os_image ] end @@ -47,42 +47,42 @@ def agent_stages def build_stemcell_image_stages stages = case infrastructure - when Infrastructure::Aws then - aws_stages - when Infrastructure::Alicloud then - alicloud_stages - when Infrastructure::CloudStack then - cloudstack_stages - when Infrastructure::Google then - google_stages - when Infrastructure::OpenStack then - openstack_stages - when Infrastructure::Vsphere then - vsphere_stages - when Infrastructure::Warden then - warden_stages - when Infrastructure::Azure then - azure_stages - end + when Infrastructure::Aws + aws_stages + when Infrastructure::Alicloud + alicloud_stages + when Infrastructure::CloudStack + cloudstack_stages + when Infrastructure::Google + google_stages + when Infrastructure::OpenStack + openstack_stages + when Infrastructure::Vsphere + vsphere_stages + when Infrastructure::Warden + warden_stages + when Infrastructure::Azure + azure_stages + end stages.concat(finish_stemcell_stages) end def package_stemcell_stages(disk_format) case disk_format - when 'raw' then + when "raw" raw_package_stages - when 'rawdisk' then + when "rawdisk" rawdisk_package_stages - when 'qcow2' then + when "qcow2" qcow2_package_stages - when 'ovf' then + when "ovf" ovf_package_stages - when 'vhd' then + when "vhd" vhd_package_stages - when 'vhdx' then + when "vhdx" vhdx_package_stages - when 'files' then + when "files" files_package_stages end end @@ -125,7 +125,6 @@ def cloudstack_stages ] end - def vsphere_stages [ :system_network, @@ -141,7 +140,7 @@ def vsphere_stages # filesystem after it won't apply. :image_create_efi, :image_install_grub, - :sbom_create, + :sbom_create ] end @@ -160,7 +159,7 @@ def aws_stages # filesystem after it won't apply. :image_create_efi, :image_install_grub, - :sbom_create, + :sbom_create ] end @@ -194,7 +193,7 @@ def google_stages # filesystem after it won't apply. :image_create_efi, :image_install_grub, - :sbom_create, + :sbom_create ] end @@ -210,7 +209,7 @@ def warden_stages # filesystem after it won't apply. :image_create_efi, :image_install_grub, - :sbom_create, + :sbom_create ] end @@ -230,14 +229,14 @@ def azure_stages # filesystem after it won't apply. :image_create_efi, :image_install_grub, - :sbom_create, + :sbom_create ] end def finish_stemcell_stages [ :bosh_package_list, - :restore_apt_sources, + :restore_apt_sources ] end @@ -263,7 +262,7 @@ def ubuntu_os_stages :escape_ctrl_alt_del, :bosh_audit_ubuntu, :bosh_log_audit_start, - :clean_machine_id, + :clean_machine_id ].flatten end @@ -282,19 +281,19 @@ def bosh_steps def raw_package_stages [ - :prepare_raw_image_stemcell, + :prepare_raw_image_stemcell ] end def rawdisk_package_stages [ - :prepare_rawdisk_image_stemcell, + :prepare_rawdisk_image_stemcell ] end def qcow2_package_stages [ - :prepare_qcow2_image_stemcell, + :prepare_qcow2_image_stemcell ] end @@ -308,21 +307,21 @@ def ovf_package_stages def vhd_package_stages [ - :prepare_vhd_image_stemcell, + :prepare_vhd_image_stemcell ] end def vhdx_package_stages [ - :prepare_vhdx_image_stemcell, + :prepare_vhdx_image_stemcell ] end def files_package_stages [ - :prepare_files_image_stemcell, + :prepare_files_image_stemcell ] end end end -# rubocop:enable ClassLength +# rubocop:enable Metrics/ClassLength diff --git a/bosh-stemcell/lib/bosh/stemcell/stage_runner.rb b/bosh-stemcell/lib/bosh/stemcell/stage_runner.rb index 056d2cb102..40b0eda6b5 100644 --- a/bosh-stemcell/lib/bosh/stemcell/stage_runner.rb +++ b/bosh-stemcell/lib/bosh/stemcell/stage_runner.rb @@ -1,4 +1,4 @@ -require 'bosh/core/shell' +require "bosh/core/shell" module Bosh::Stemcell class BuildReport @@ -9,7 +9,7 @@ def initialize def measure_configure(name, &block) start = Time.now.utc - puts "== Started configuring '#{name}' at #{start.strftime('%a %b %e %H:%M:%S %Z %Y')} ==" + puts "== Started configuring '#{name}' at #{start.strftime("%a %b %e %H:%M:%S %Z %Y")} ==" yield @stats << {type: "configure", name: name, duration: Time.now.utc - start} end @@ -17,7 +17,7 @@ def measure_configure(name, &block) def measure_apply(name, &block) start = Time.now.utc - puts "== Started applying '#{name}' at #{start.strftime('%a %b %e %H:%M:%S %Z %Y')} ==" + puts "== Started applying '#{name}' at #{start.strftime("%a %b %e %H:%M:%S %Z %Y")} ==" yield @stats << {type: "apply", name: name, duration: Time.now.utc - start} end @@ -31,8 +31,7 @@ def print_report end class StageRunner - - REQUIRED_UID=1000 + REQUIRED_UID = 1000 def initialize(options) @build_path = options.fetch(:build_path) @@ -52,7 +51,7 @@ def configure_and_apply(stages, resume_from_stage = nil) def configure(stages) stages.each do |stage| - stage_config_script = File.join(build_path, 'stages', stage.to_s, 'config.sh') + stage_config_script = File.join(build_path, "stages", stage.to_s, "config.sh") @report.measure_configure(stage) do if File.exist?(stage_config_script) && File.executable?(stage_config_script) @@ -67,14 +66,12 @@ def apply(stages) FileUtils.mkdir_p(work_path) @report.measure_apply(stage) do - begin - stage_apply_script = File.join(build_path, 'stages', stage.to_s, 'apply.sh') + stage_apply_script = File.join(build_path, "stages", stage.to_s, "apply.sh") - run_sudo_with_command_env("#{stage_apply_script} #{work_path}") - rescue => _ - puts "=== You can resume_from the '#{stage}' stage by using resume_from=#{stage} ===" - raise - end + run_sudo_with_command_env("#{stage_apply_script} #{work_path}") + rescue => _ + puts "=== You can resume_from the '#{stage}' stage by using resume_from=#{stage} ===" + raise end end end diff --git a/bosh-stemcell/lib/bosh/stemcell/stemcell_builder.rb b/bosh-stemcell/lib/bosh/stemcell/stemcell_builder.rb index ac815e1e7c..aecd63ae06 100644 --- a/bosh-stemcell/lib/bosh/stemcell/stemcell_builder.rb +++ b/bosh-stemcell/lib/bosh/stemcell/stemcell_builder.rb @@ -1,5 +1,5 @@ -require 'fileutils' -require 'bosh/stemcell/stage_collection' +require "fileutils" +require "bosh/stemcell/stage_collection" module Bosh::Stemcell class StemcellBuilder @@ -16,7 +16,7 @@ def build collection.kernel_stages + collection.agent_stages + collection.build_stemcell_image_stages - runner.configure_and_apply(stemcell_stages, ENV['resume_from']) + runner.configure_and_apply(stemcell_stages, ENV["resume_from"]) end private diff --git a/bosh-stemcell/lib/bosh/stemcell/stemcell_packager.rb b/bosh-stemcell/lib/bosh/stemcell/stemcell_packager.rb index a9d99e9fcb..2e339caf77 100644 --- a/bosh-stemcell/lib/bosh/stemcell/stemcell_packager.rb +++ b/bosh-stemcell/lib/bosh/stemcell/stemcell_packager.rb @@ -1,5 +1,5 @@ -require 'psych' -require 'open3' +require "psych" +require "open3" module Bosh module Stemcell @@ -7,7 +7,7 @@ class StemcellPackager def initialize(options = {}) @definition = options.fetch(:definition) @version = options.fetch(:version) - @stemcell_build_path = File.join(options.fetch(:work_path), 'stemcell') + @stemcell_build_path = File.join(options.fetch(:work_path), "stemcell") @tarball_path = options.fetch(:tarball_path) @disk_size = options.fetch(:disk_size) @runner = options.fetch(:runner) @@ -28,10 +28,8 @@ def package(disk_format) attr_reader :definition, :version, :stemcell_build_path, :tarball_path, :disk_size, :runner, :collection def write_manifest(disk_format) - manifest_filename = File.join(stemcell_build_path, 'stemcell.MF') - File.open(manifest_filename, 'w') do |f| - f.write(Psych.dump(manifest(disk_format))) - end + manifest_filename = File.join(stemcell_build_path, "stemcell.MF") + File.write(manifest_filename, Psych.dump(manifest(disk_format))) end def manifest(disk_format) @@ -39,51 +37,51 @@ def manifest(disk_format) stemcell_name = "bosh-#{definition.stemcell_name(disk_format)}" { - 'name' => stemcell_name, - 'version' => version.to_s, - 'bosh_protocol' => 1, - 'api_version' => 3, - 'sha1' => image_checksum, - 'operating_system' => "#{definition.operating_system.name}-#{definition.operating_system.version}", - 'stemcell_formats' => infrastructure.stemcell_formats, - 'cloud_properties' => manifest_cloud_properties(disk_format, infrastructure, stemcell_name) + "name" => stemcell_name, + "version" => version.to_s, + "bosh_protocol" => 1, + "api_version" => 3, + "sha1" => image_checksum, + "operating_system" => "#{definition.operating_system.name}-#{definition.operating_system.version}", + "stemcell_formats" => infrastructure.stemcell_formats, + "cloud_properties" => manifest_cloud_properties(disk_format, infrastructure, stemcell_name) } end def manifest_cloud_properties(disk_format, infrastructure, stemcell_name) - architecture = 'x86_64' + architecture = "x86_64" { - 'name' => stemcell_name, - 'version' => version.to_s, - 'infrastructure' => infrastructure.name, - 'hypervisor' => infrastructure.hypervisor, - 'disk' => disk_size, - 'disk_format' => disk_format, - 'container_format' => 'bare', - 'os_type' => 'linux', - 'os_distro' => definition.operating_system.name, - 'architecture' => architecture, + "name" => stemcell_name, + "version" => version.to_s, + "infrastructure" => infrastructure.name, + "hypervisor" => infrastructure.hypervisor, + "disk" => disk_size, + "disk_format" => disk_format, + "container_format" => "bare", + "os_type" => "linux", + "os_distro" => definition.operating_system.name, + "architecture" => architecture }.merge(infrastructure.additional_cloud_properties) end def create_tarball(disk_format) - stemcell_name = ArchiveFilename.new(version, definition, 'bosh-stemcell', disk_format).to_s + stemcell_name = ArchiveFilename.new(version, definition, "bosh-stemcell", disk_format).to_s tarball_name = File.join(tarball_path, stemcell_name) - expected = ['stemcell.MF', 'packages.txt', 'dev_tools_file_list.txt', 'image', 'sbom.spdx.json', 'sbom.cdx.json'] + expected = ["stemcell.MF", "packages.txt", "dev_tools_file_list.txt", "image", "sbom.spdx.json", "sbom.cdx.json"] Dir.chdir(stemcell_build_path) do - stdout, stderr, status = Open3.capture3('ls') + stdout, stderr, status = Open3.capture3("ls") raise stderr unless status.success? - actual = stdout.split(' ') + actual = stdout.split(" ") missing = expected.reject { |f| actual.include?(f) } - raise "Files are missing from stemcell directory: #{missing.join(' ')}" unless missing.empty? + raise "Files are missing from stemcell directory: #{missing.join(" ")}" unless missing.empty? extra = actual.reject { |f| expected.include?(f) } - raise "Extra files found in stemcell directory: #{extra.join(' ')}" unless extra.empty? + raise "Extra files found in stemcell directory: #{extra.join(" ")}" unless extra.empty? - _, stderr, status = Open3.capture3("tar zcf #{tarball_name} #{expected.join(' ')}") + _, stderr, status = Open3.capture3("tar zcf #{tarball_name} #{expected.join(" ")}") raise stderr unless status.success? end @@ -95,7 +93,7 @@ def image_checksum end def stemcell_image_path - File.join(stemcell_build_path, 'image') + File.join(stemcell_build_path, "image") end end end diff --git a/bosh-stemcell/lib/bosh/stemcell/version.rb b/bosh-stemcell/lib/bosh/stemcell/version.rb index 35b9980ebf..a2fcd0ad4f 100644 --- a/bosh-stemcell/lib/bosh/stemcell/version.rb +++ b/bosh-stemcell/lib/bosh/stemcell/version.rb @@ -1,5 +1,5 @@ module Bosh module Stemcell - VERSION = '0.0.0' + VERSION = "0.0.0" end end diff --git a/bosh-stemcell/lib/shellout_types/chroot.rb b/bosh-stemcell/lib/shellout_types/chroot.rb index 1691eee302..fd9c928c10 100644 --- a/bosh-stemcell/lib/shellout_types/chroot.rb +++ b/bosh-stemcell/lib/shellout_types/chroot.rb @@ -1,9 +1,9 @@ -require 'open3' -require 'shellwords' +require "open3" +require "shellwords" module ShelloutTypes class Chroot - @@chroot_dir = '' + @@chroot_dir = "" def self.chroot_dir=(dir) @@chroot_dir = dir @@ -12,7 +12,7 @@ def self.chroot_dir=(dir) def self.unmount_proc dir = @@chroot_dir return if dir.empty? - system('sudo', 'umount', "#{dir}/proc", [:out, :err] => '/dev/null') + system("sudo", "umount", "#{dir}/proc", [:out, :err] => "/dev/null") end def initialize(dir = nil) @@ -20,9 +20,9 @@ def initialize(dir = nil) end def run(*cmd) - cmd.unshift('mknod -m 666 /dev/urandom c 1 9 2>/dev/null;') - cmd.unshift('mknod -m 666 /dev/random c 1 8 2>/dev/null;') - inner = cmd.join(' ') + cmd.unshift("mknod -m 666 /dev/urandom c 1 9 2>/dev/null;") + cmd.unshift("mknod -m 666 /dev/random c 1 8 2>/dev/null;") + inner = cmd.join(" ") wrapper = <<~SH.strip if ! mountpoint -q #{chroot_dir}/proc 2>/dev/null; then mkdir -p #{chroot_dir}/proc @@ -30,7 +30,7 @@ def run(*cmd) fi chroot #{chroot_dir} /bin/bash -c #{inner.shellescape} SH - stdout, stderr, status = Open3.capture3('sudo', '/bin/bash', '-c', wrapper) + stdout, stderr, status = Open3.capture3("sudo", "/bin/bash", "-c", wrapper) [stdout, stderr, status.exitstatus] end diff --git a/bosh-stemcell/lib/shellout_types/file.rb b/bosh-stemcell/lib/shellout_types/file.rb index bbafc90ce1..eb833077db 100644 --- a/bosh-stemcell/lib/shellout_types/file.rb +++ b/bosh-stemcell/lib/shellout_types/file.rb @@ -10,15 +10,15 @@ def to_s end def file? - stdout, _, _ = @chroot.run('stat', '-c', '%F', true_path_in_chroot) + stdout, _, _ = @chroot.run("stat", "-c", "%F", true_path_in_chroot) !stdout.strip.match(/\Aregular (empty )?file\z/).nil? rescue RuntimeError - return false + false end def owner - stdout, stderr, status = @chroot.run('stat', '-c', '%u', @path) + stdout, stderr, status = @chroot.run("stat", "-c", "%u", @path) stdout.strip! raise stderr if status != 0 @@ -27,7 +27,7 @@ def owner raise "user for file #{filepath} does not exist" if status == 2 raise stderr if status != 0 - passwd_split = stdout.split(':', -1) + passwd_split = stdout.split(":", -1) raise "passwd has an invalid format: #{stdout}" if passwd_split.size != 7 passwd_split.first @@ -39,9 +39,9 @@ def owned_by?(username) def content stdout, stderr, status = @chroot.run("cat", @path) - raise RuntimeError, stderr if status != 0 + raise stderr.to_s if status != 0 - return stdout + stdout end def content_as_lines @@ -53,10 +53,10 @@ def mode?(expected_mode) end def mode - stdout, stderr, status = @chroot.run('stat', '-c', '%a', @path) - raise RuntimeError, stderr if status != 0 + stdout, stderr, status = @chroot.run("stat", "-c", "%a", @path) + raise stderr.to_s if status != 0 - stdout.strip.to_i(8) & 0777 + stdout.strip.to_i(8) & 0o777 end def group @@ -64,50 +64,50 @@ def group end def executable? - stdout, stderr, status = @chroot.run('stat', '-c', '%a', @path) - raise RuntimeError, stderr if status != 0 + stdout, stderr, status = @chroot.run("stat", "-c", "%a", @path) + raise stderr.to_s if status != 0 - (stdout.strip.to_i(8) & 0111) != 0 + (stdout.strip.to_i(8) & 0o111) != 0 end def directory? - stdout, _, _ = @chroot.run('stat', '-c', '%F', true_path_in_chroot) - stdout.strip == 'directory' + stdout, _, _ = @chroot.run("stat", "-c", "%F", true_path_in_chroot) + stdout.strip == "directory" end def readable_by_user?(username) this_mode = mode if owned_by?(username) - return (this_mode & 0400) != 0 + return (this_mode & 0o400) != 0 end - members = group_entry.last.split(',') + members = group_entry.last.split(",") stdout, stderr, status = @chroot.run("getent passwd #{username}") - raise RuntimeError, "user #{username} does not exist" if status == 2 - raise RuntimeError, stderr if status != 0 + raise "user #{username} does not exist" if status == 2 + raise stderr.to_s if status != 0 - passwd_split = stdout.strip.split(':', -1) - raise RuntimeError, "passwd has an invalid format: #{stdout}" if passwd_split.size != 7 + passwd_split = stdout.strip.split(":", -1) + raise "passwd has an invalid format: #{stdout}" if passwd_split.size != 7 gid_for_username = passwd_split[3] members.map!(&:strip) if members.include?(username) || (gid == gid_for_username) - return (this_mode & 0040) != 0 + return (this_mode & 0o040) != 0 end - (mode & 0004) != 0 + (mode & 0o004) != 0 end def writable_by?(by_whom) case by_whom - when 'group' - (mode & 0020) != 0 - when 'other' - (mode & 0002) != 0 - else - raise "#{by_whom} is an invalid input to writable_by?, please specify one of: ['group', 'other']" + when "group" + (mode & 0o020) != 0 + when "other" + (mode & 0o002) != 0 + else + raise "#{by_whom} is an invalid input to writable_by?, please specify one of: ['group', 'other']" end end @@ -118,8 +118,8 @@ def linked_to?(target) private def true_path_in_chroot - stdout, stderr, status = @chroot.run('readlink', '-m', @path) - raise RuntimeError, stderr if status != 0 + stdout, stderr, status = @chroot.run("readlink", "-m", @path) + raise stderr.to_s if status != 0 stdout.strip end @@ -129,8 +129,8 @@ def filepath end def gid - stdout, stderr, status = @chroot.run('stat', '-c', '%g', @path) - raise RuntimeError, stderr if status != 0 + stdout, stderr, status = @chroot.run("stat", "-c", "%g", @path) + raise stderr.to_s if status != 0 stdout.strip end @@ -141,12 +141,12 @@ def group_entry def fetch_and_validate_group_entry_for_gid(group_id) stdout, stderr, status = @chroot.run("getent group #{group_id}") - raise RuntimeError, "group #{group_id} does not exist" if status == 2 - raise RuntimeError, stderr if status != 0 + raise "group #{group_id} does not exist" if status == 2 + raise stderr.to_s if status != 0 - group_split = stdout.split(':', -1) - raise RuntimeError, "group entry is an invalid format: #{stdout}" if group_split.size != 4 - return group_split + group_split = stdout.split(":", -1) + raise "group entry is an invalid format: #{stdout}" if group_split.size != 4 + group_split end end end diff --git a/bosh-stemcell/lib/shellout_types/group.rb b/bosh-stemcell/lib/shellout_types/group.rb index 5fe554f267..cfa324659c 100644 --- a/bosh-stemcell/lib/shellout_types/group.rb +++ b/bosh-stemcell/lib/shellout_types/group.rb @@ -10,7 +10,7 @@ def to_s end def exists? - _, _, status = @chroot.run('getent', 'group', @group) + _, _, status = @chroot.run("getent", "group", @group) status == 0 end end diff --git a/bosh-stemcell/lib/shellout_types/package.rb b/bosh-stemcell/lib/shellout_types/package.rb index f064204cfd..fcee58d946 100644 --- a/bosh-stemcell/lib/shellout_types/package.rb +++ b/bosh-stemcell/lib/shellout_types/package.rb @@ -19,9 +19,9 @@ def installed? private def pkg_query - stdout, _, _ = @chroot_cmd_runner.run('cat /etc/*release') - if stdout.match /Ubuntu/ - return 'dpkg -s' + stdout, _, _ = @chroot_cmd_runner.run("cat /etc/*release") + if stdout.match?(/Ubuntu/) + "dpkg -s" else raise "Cannot determine Linux distribution: #{stdout}" end diff --git a/bosh-stemcell/lib/shellout_types/service.rb b/bosh-stemcell/lib/shellout_types/service.rb index f82a8be529..d417a0693f 100644 --- a/bosh-stemcell/lib/shellout_types/service.rb +++ b/bosh-stemcell/lib/shellout_types/service.rb @@ -1,4 +1,4 @@ -require 'shellout_types/file' +require "shellout_types/file" module ShelloutTypes class Service @@ -24,20 +24,20 @@ def enabled_for_level?(runlevel) private def check_service_enabled(runlevel) - stdout, stderr, status = @chroot.run('cat', '/etc/*release') - raise RuntimeError, stderr if status != 0 + stdout, stderr, status = @chroot.run("cat", "/etc/*release") + raise stderr.to_s if status != 0 - raise "Cannot determine Linux distribution: #{stdout}" unless stdout.match(/Ubuntu/) + raise "Cannot determine Linux distribution: #{stdout}" unless /Ubuntu/.match?(stdout) check_is_enabled_systemctl end def check_upstart_links(runlevel) - scripts_list, stderr, status = @chroot.run('ls', '-1', "/etc/rc#{runlevel}.d") - raise RuntimeError, stderr if status != 0 + scripts_list, stderr, status = @chroot.run("ls", "-1", "/etc/rc#{runlevel}.d") + raise stderr.to_s if status != 0 script_links = scripts_list.split("\n") - script_for_service = script_links.select { |link| link.match(/^S\d\d#{@service}$/) }.first + script_for_service = script_links.find { |link| link.match(/^S\d\d#{@service}$/) } !script_for_service.nil? end @@ -46,17 +46,17 @@ def check_init_conf(runlevel) return false unless conf_file.file? start_on_block = conf_file.content.match(/^start on .*(\n[\t ]+.*)*/)[0] - if start_on_block.match(/runlevel \[\d*#{runlevel}\d*\]/) || start_on_block.match('startup') - return true + if start_on_block.match(/runlevel \[\d*#{runlevel}\d*\]/) || start_on_block.match("startup") + true else - return false + false end end def check_is_enabled_systemctl - stdout, _, _ = @chroot.run('systemctl', 'is-enabled', @service) + stdout, _, _ = @chroot.run("systemctl", "is-enabled", @service) - return stdout.match(/^enabled$/) ? true : false + /^enabled$/.match?(stdout) || false end end end diff --git a/bosh-stemcell/lib/shellout_types/user.rb b/bosh-stemcell/lib/shellout_types/user.rb index dba25b03e4..03ff2c2391 100644 --- a/bosh-stemcell/lib/shellout_types/user.rb +++ b/bosh-stemcell/lib/shellout_types/user.rb @@ -18,7 +18,7 @@ def in_group?(group_name) return false unless exists? stdout, _, status = @chroot_cmd_runner.run("id -Gn #{@user_name}") return false unless status == 0 - groups_for_user = stdout.split(' ') + groups_for_user = stdout.split(" ") groups_for_user.include?(group_name) end end diff --git a/bosh-stemcell/spec/bosh/stemcell/archive_filename_spec.rb b/bosh-stemcell/spec/bosh/stemcell/archive_filename_spec.rb index 619d3cafa0..7f5ac4c74c 100644 --- a/bosh-stemcell/spec/bosh/stemcell/archive_filename_spec.rb +++ b/bosh-stemcell/spec/bosh/stemcell/archive_filename_spec.rb @@ -1,43 +1,42 @@ -require 'spec_helper' -require 'bosh/stemcell/archive_filename' -require 'bosh/stemcell/definition' +require "spec_helper" +require "bosh/stemcell/archive_filename" +require "bosh/stemcell/definition" module Bosh::Stemcell describe ArchiveFilename do - let(:version) { '007' } + let(:version) { "007" } let(:infrastructure) do - instance_double('Bosh::Stemcell::Infrastructure::Base', - name: 'INFRASTRUCTURE', - hypervisor: 'HYPERVISOR') + instance_double("Bosh::Stemcell::Infrastructure::Base", + name: "INFRASTRUCTURE", + hypervisor: "HYPERVISOR") end let(:operating_system) do - instance_double('Bosh::Stemcell::OperatingSystem::Base', - name: 'OPERATING_SYSTEM', - version: 'OPERATING_SYSTEM_VERSION', - ) + instance_double("Bosh::Stemcell::OperatingSystem::Base", + name: "OPERATING_SYSTEM", + version: "OPERATING_SYSTEM_VERSION") end let(:agent) do instance_double( - 'Bosh::Stemcell::Agent::Go', - name: 'go' + "Bosh::Stemcell::Agent::Go", + name: "go" ) end let(:definition) do instance_double( - 'Bosh::Stemcell::Definition', - stemcell_name: 'fake-stemcell-name', - infrastructure: instance_double('Bosh::Stemcell::Infrastructure::Base', default_disk_format: 'iso'), + "Bosh::Stemcell::Definition", + stemcell_name: "fake-stemcell-name", + infrastructure: instance_double("Bosh::Stemcell::Infrastructure::Base", default_disk_format: "iso") ) end - let(:disk_format) { 'iso' } + let(:disk_format) { "iso" } subject(:archive_filename) do - ArchiveFilename.new(version, definition, 'FAKE_NAME', disk_format) + ArchiveFilename.new(version, definition, "FAKE_NAME", disk_format) end - describe '#to_s' do - it 'includes name, version, stemcell name' do - expect(archive_filename.to_s).to eq ("FAKE_NAME-007-fake-stemcell-name.tgz") + describe "#to_s" do + it "includes name, version, stemcell name" do + expect(archive_filename.to_s).to eq("FAKE_NAME-007-fake-stemcell-name.tgz") end end end diff --git a/bosh-stemcell/spec/bosh/stemcell/archive_handler_spec.rb b/bosh-stemcell/spec/bosh/stemcell/archive_handler_spec.rb index e8aaf528d2..95add62383 100644 --- a/bosh-stemcell/spec/bosh/stemcell/archive_handler_spec.rb +++ b/bosh-stemcell/spec/bosh/stemcell/archive_handler_spec.rb @@ -1,5 +1,5 @@ -require 'spec_helper' -require 'bosh/stemcell/archive_handler' +require "spec_helper" +require "bosh/stemcell/archive_handler" module Bosh::Stemcell describe ArchiveHandler do @@ -11,11 +11,11 @@ module Bosh::Stemcell allow(Bosh::Core::Shell).to receive(:new).and_return(shell) end - describe 'compress' do - it 'compresses the given directory' do - expect(shell).to receive(:run).with('sudo tar -cz -f some.tar.gz -C some_dir .') + describe "compress" do + it "compresses the given directory" do + expect(shell).to receive(:run).with("sudo tar -cz -f some.tar.gz -C some_dir .") - archiver.compress('some_dir', 'some.tar.gz') + archiver.compress("some_dir", "some.tar.gz") end end end diff --git a/bosh-stemcell/spec/bosh/stemcell/archive_spec.rb b/bosh-stemcell/spec/bosh/stemcell/archive_spec.rb index b1d66e6110..6791a96bab 100644 --- a/bosh-stemcell/spec/bosh/stemcell/archive_spec.rb +++ b/bosh-stemcell/spec/bosh/stemcell/archive_spec.rb @@ -1,104 +1,104 @@ -require 'spec_helper' -require 'bosh/stemcell/archive' +require "spec_helper" +require "bosh/stemcell/archive" module Bosh::Stemcell describe Archive do subject { described_class.new(stemcell_path) } - let(:stemcell_path) { spec_asset('fake-stemcell-aws-xen-ubuntu.tgz') } + let(:stemcell_path) { spec_asset("fake-stemcell-aws-xen-ubuntu.tgz") } - describe '#initialize' do - it 'errors if path does not exist' do + describe "#initialize" do + it "errors if path does not exist" do expect { - described_class.new('/not/found/stemcell.tgz') + described_class.new("/not/found/stemcell.tgz") }.to raise_error("Cannot find file '/not/found/stemcell.tgz'") end end - describe '#manifest' do - it 'has a manifest' do + describe "#manifest" do + it "has a manifest" do expect(subject.manifest).to be_a(Hash) end end - describe '#name' do - it 'has a name' do - expect(subject.name).to eq('fake-stemcell') + describe "#name" do + it "has a name" do + expect(subject.name).to eq("fake-stemcell") end end - describe '#infrastructure' do - it 'has an infrastructure' do - expect(subject.infrastructure).to eq('aws') + describe "#infrastructure" do + it "has an infrastructure" do + expect(subject.infrastructure).to eq("aws") end end - describe '#path' do - it 'has a path' do + describe "#path" do + it "has a path" do expect(subject.path).to eq(stemcell_path) end end - describe '#version' do - it 'has a version' do - expect(subject.version).to eq('007') + describe "#version" do + it "has a version" do + expect(subject.version).to eq("007") end end - describe '#sha1' do - context 'when sha1 is just a string (from fake-stemcell-aws-xen-ubuntu.tgz)' do - it 'returns a sha1 as a string' do - expect(subject.sha1).to eq('fake-stemcell-sha1') + describe "#sha1" do + context "when sha1 is just a string (from fake-stemcell-aws-xen-ubuntu.tgz)" do + it "returns a sha1 as a string" do + expect(subject.sha1).to eq("fake-stemcell-sha1") end end - context 'when sha1 happens to be a number' do - before { subject.manifest['sha1'] = 123 } + context "when sha1 happens to be a number" do + before { subject.manifest["sha1"] = 123 } - it 'returns a sha1 as a string' do - expect(subject.sha1).to eq('123') + it "returns a sha1 as a string" do + expect(subject.sha1).to eq("123") end end - context 'when the sha1 is nil' do - before { subject.manifest['sha1'] = nil } + context "when the sha1 is nil" do + before { subject.manifest["sha1"] = nil } - it 'raises an error' do + it "raises an error" do expect { subject.sha1 - }.to raise_error(RuntimeError, 'sha1 must not be nil') + }.to raise_error(RuntimeError, "sha1 must not be nil") end end end - describe '#light?' do + describe "#light?" do context 'when infrastructure is "aws"' do context 'when there is not an "ami" key in the "cloud_properties" section of the manifest' do it { should_not be_light } end context 'when there is an "ami" key in the "cloud_properties" section of the manifest' do - let(:stemcell_path) { spec_asset('light-fake-stemcell-aws-xen-ubuntu.tgz') } + let(:stemcell_path) { spec_asset("light-fake-stemcell-aws-xen-ubuntu.tgz") } it { should be_light } end end context 'when infrastructure is anything but "aws"' do - let(:stemcell_path) { spec_asset('fake-stemcell-vsphere.tgz') } + let(:stemcell_path) { spec_asset("fake-stemcell-vsphere.tgz") } it { should_not be_light } end end - describe '#extract' do - it 'extracts stemcell' do + describe "#extract" do + it "extracts stemcell" do expect(Rake::FileUtilsExt).to receive(:sh).with(/tar xzf .*#{stemcell_path} --directory/) subject.extract {} end - it 'extracts stemcell and excludes files' do + it "extracts stemcell and excludes files" do expect(Rake::FileUtilsExt).to receive(:sh).with(/tar xzf .*#{stemcell_path} --directory .* --exclude=image/) - subject.extract(exclude: 'image') {} + subject.extract(exclude: "image") {} end end end diff --git a/bosh-stemcell/spec/bosh/stemcell/build_environment_spec.rb b/bosh-stemcell/spec/bosh/stemcell/build_environment_spec.rb index 786a218a58..1cf26595a9 100644 --- a/bosh-stemcell/spec/bosh/stemcell/build_environment_spec.rb +++ b/bosh-stemcell/spec/bosh/stemcell/build_environment_spec.rb @@ -1,8 +1,9 @@ -require 'spec_helper' -require 'bosh/stemcell/build_environment' -require 'bosh/stemcell/infrastructure' -require 'bosh/stemcell/operating_system' -require 'bosh/stemcell/definition' +require "spec_helper" +require "bosh/stemcell/build_environment" +require "bosh/stemcell/infrastructure" +require "bosh/stemcell/operating_system" +require "bosh/stemcell/definition" +require "fakefs/spec_helpers" module Bosh::Stemcell describe BuildEnvironment do @@ -14,78 +15,77 @@ module Bosh::Stemcell let(:definition) do instance_double( - 'Bosh::Stemcell::Definition', + "Bosh::Stemcell::Definition", infrastructure: infrastructure, - operating_system: operating_system, + operating_system: operating_system ) end - let(:version) { '1234' } - let(:os_image_tarball_path) { '/some/os_image.tgz' } + let(:version) { "1234" } + let(:os_image_tarball_path) { "/some/os_image.tgz" } - let(:build_time_marker_file) { '/fake/path/to/build/time/marker/file' } - let(:stemcell_builder_source_dir) { '/fake/path/to/stemcell_builder' } - let(:stemcell_specs_dir) { '/fake/path/to/stemcell/specs/dir' } + let(:build_time_marker_file) { "/fake/path/to/build/time/marker/file" } + let(:stemcell_builder_source_dir) { "/fake/path/to/stemcell_builder" } + let(:stemcell_specs_dir) { "/fake/path/to/stemcell/specs/dir" } - let(:version) { '007' } + let(:version) { "007" } let(:root_dir) do - File.join('/mnt/stemcells', infrastructure.name, infrastructure.hypervisor, operating_system.name) + File.join("/mnt/stemcells", infrastructure.name, infrastructure.hypervisor, operating_system.name) end - let(:build_path) { File.join(root_dir, 'build', 'build') } - let(:settings_file) { File.join(build_path, 'etc', 'settings.bash') } - let(:work_root) { File.join(root_dir, 'work') } - let(:work_path) { File.join(work_root, 'work') } + let(:build_path) { File.join(root_dir, "build", "build") } + let(:settings_file) { File.join(build_path, "etc", "settings.bash") } + let(:work_root) { File.join(root_dir, "work") } + let(:work_path) { File.join(work_root, "work") } let(:infrastructure) do - instance_double('Bosh::Stemcell::Infrastructure::Base', - name: 'fake-infrastructure-name', - hypervisor: 'fake-hypervisor', - default_disk_size: -1, - ) + instance_double("Bosh::Stemcell::Infrastructure::Base", + name: "fake-infrastructure-name", + hypervisor: "fake-hypervisor", + default_disk_size: -1) end let(:stemcell_builder_options) do - instance_double('Bosh::Stemcell::BuilderOptions', default: options) + instance_double("Bosh::Stemcell::BuilderOptions", default: options) end let(:options) do { - 'hello' => 'world', - 'stemcell_tgz' => 'fake-stemcell.tgz', - 'stemcell_image_name' => 'fake-root-disk-image.raw' + "hello" => "world", + "stemcell_tgz" => "fake-stemcell.tgz", + "stemcell_image_name" => "fake-root-disk-image.raw" } end let(:operating_system) do - instance_double('Bosh::Stemcell::OperatingSystem::Base', - name: 'fake-operating-system-name') + instance_double("Bosh::Stemcell::OperatingSystem::Base", + name: "fake-operating-system-name") end let(:shell) { instance_double(Bosh::Core::Shell) } - let(:run_options) { { ignore_failures: true } } + let(:run_options) { {ignore_failures: true} } before do allow(Bosh::Core::Shell).to receive(:new).and_return(shell) allow(BuilderOptions).to receive(:new).and_return(stemcell_builder_options) - stub_const('Bosh::Stemcell::BuildEnvironment::BUILD_TIME_MARKER_FILE', build_time_marker_file) - stub_const('Bosh::Stemcell::BuildEnvironment::STEMCELL_BUILDER_SOURCE_DIR', stemcell_builder_source_dir) - stub_const('Bosh::Stemcell::BuildEnvironment::STEMCELL_SPECS_DIR', stemcell_specs_dir) + stub_const("Bosh::Stemcell::BuildEnvironment::BUILD_TIME_MARKER_FILE", build_time_marker_file) + stub_const("Bosh::Stemcell::BuildEnvironment::STEMCELL_BUILDER_SOURCE_DIR", stemcell_builder_source_dir) + stub_const("Bosh::Stemcell::BuildEnvironment::STEMCELL_SPECS_DIR", stemcell_specs_dir) end - it 'constructs stemcell builder options' do + it "constructs stemcell builder options" do expect(BuilderOptions).to receive(:new).with( env: env, definition: definition, version: version, - os_image_tarball: os_image_tarball_path, + os_image_tarball: os_image_tarball_path ) subject end - describe '#prepare_build' do + describe "#prepare_build" do before do allow(shell).to receive(:run) @@ -94,16 +94,16 @@ module Bosh::Stemcell original_cp_r.call(src, dst) end - stemcell_builder_etc_dir = File.join(stemcell_builder_source_dir, 'etc') + stemcell_builder_etc_dir = File.join(stemcell_builder_source_dir, "etc") FileUtils.mkdir_p(stemcell_builder_etc_dir) - File.open(File.join(stemcell_builder_etc_dir, 'settings.bash'), 'w') { |file| file.puts('some=var') } + File.open(File.join(stemcell_builder_etc_dir, "settings.bash"), "w") { |file| file.puts("some=var") } end - it 'cleans and prepares the environment' do - image_path = File.join(root_dir, 'work/work/mnt/tmp/grub/fake-root-disk-image.raw') + it "cleans and prepares the environment" do + image_path = File.join(root_dir, "work/work/mnt/tmp/grub/fake-root-disk-image.raw") unmount_img_command = "sudo umount #{image_path} 2> /dev/null" expect(shell).to receive(:run).with(unmount_img_command, run_options).ordered - unmount_dir_command = "sudo umount #{File.join(root_dir, 'work/work/mnt')} 2> /dev/null" + unmount_dir_command = "sudo umount #{File.join(root_dir, "work/work/mnt")} 2> /dev/null" expect(shell).to receive(:run).with(unmount_dir_command, run_options).ordered expect(shell).to receive(:run).with("sudo rm -rf #{root_dir}", run_options).ordered @@ -114,16 +114,16 @@ module Bosh::Stemcell expect(File.read(settings_file)).to match(/hello=world/) end - it 'removes any tgz files from current working directory' do - FileUtils.touch('leftover.tgz') + it "removes any tgz files from current working directory" do + FileUtils.touch("leftover.tgz") expect { subject.prepare_build - }.to change { Dir.glob('*.tgz').size }.to(0) + }.to change { Dir.glob("*.tgz").size }.to(0) end - it 'cleans the build path' do + it "cleans the build path" do FileUtils.mkdir_p(build_path) - leftover_file = File.join(build_path, 'some_file') + leftover_file = File.join(build_path, "some_file") FileUtils.touch(leftover_file) expect { @@ -131,30 +131,30 @@ module Bosh::Stemcell }.to change { File.exist?(leftover_file) }.from(true).to(false) end - it 'creates the work root' do + it "creates the work root" do expect { subject.prepare_build }.to change { Dir.exist?(work_root) }.from(false).to(true) end - it 'creates the stemcell path' do + it "creates the stemcell path" do expect { subject.prepare_build - }.to change { Dir.exist?(File.join(root_dir, 'work/work/stemcell')) }.from(false).to(true) + }.to change { Dir.exist?(File.join(root_dir, "work/work/stemcell")) }.from(false).to(true) end - context 'when resume_from is set' do + context "when resume_from is set" do before do - ENV['resume_from'] = 'stage_1' + ENV["resume_from"] = "stage_1" FileUtils.mkdir_p(build_path) end after do - ENV['resume_from'] = nil + ENV["resume_from"] = nil end - it 'does not run sanitize' do + it "does not run sanitize" do expect(shell).to_not receive(:run) subject.prepare_build @@ -162,15 +162,15 @@ module Bosh::Stemcell expect(Dir.exist?(build_path)).to be(true) end - it 'does not run prepare_build_path' do - leftover_file = File.join(build_path, 'some_file') + it "does not run prepare_build_path" do + leftover_file = File.join(build_path, "some_file") FileUtils.touch(leftover_file) subject.prepare_build expect(File.exist?(leftover_file)).to be(true) end - it 'still updates the settings file' do + it "still updates the settings file" do subject.prepare_build expect(File.read(settings_file)).to match(/some=var/) @@ -179,32 +179,32 @@ module Bosh::Stemcell end end - describe '#os_image_rspec_command' do - context 'when operating system has version' do - before { allow(operating_system).to receive(:version).and_return('fake-version') } + describe "#os_image_rspec_command" do + context "when operating system has version" do + before { allow(operating_system).to receive(:version).and_return("fake-version") } - it 'returns the correct command' do + it "returns the correct command" do expected_rspec_command = [ "cd #{stemcell_specs_dir};", - 'OS_IMAGE=/some/os_image.tgz', + "OS_IMAGE=/some/os_image.tgz", "bundle exec rspec -fd", - "spec/os_image/#{operating_system.name}_spec.rb", - ].join(' ') + "spec/os_image/#{operating_system.name}_spec.rb" + ].join(" ") expect(subject.os_image_rspec_command).to eq(expected_rspec_command) end end end - describe '#stemcell_rspec_command' do - before { allow(operating_system).to receive(:version).and_return('fake-version') } + describe "#stemcell_rspec_command" do + before { allow(operating_system).to receive(:version).and_return("fake-version") } before { allow(operating_system).to receive(:variant?).and_return(true) } - before { allow(operating_system).to receive(:variant).and_return('fips') } + before { allow(operating_system).to receive(:variant).and_return("fips") } - it 'returns the correct command' do + it "returns the correct command" do expected_rspec_command = [ "cd #{stemcell_specs_dir};", - "STEMCELL_IMAGE=#{File.join(work_path, 'fake-root-disk-image.raw')}", + "STEMCELL_IMAGE=#{File.join(work_path, "fake-root-disk-image.raw")}", "STEMCELL_WORKDIR=#{work_path}", "STEMCELL_INFRASTRUCTURE=#{infrastructure.name}", "OS_NAME=#{operating_system.name}", @@ -217,140 +217,140 @@ module Bosh::Stemcell "spec/stemcells/#{infrastructure.name}_spec.rb", "spec/stemcells/stig_spec.rb", "spec/stemcells/cis_spec.rb", - "spec/stemcells/fips_spec.rb", - ].join(' ') + "spec/stemcells/fips_spec.rb" + ].join(" ") expect(subject.stemcell_rspec_command).to eq(expected_rspec_command) end end - describe '#build_path' do - it 'returns the build path' do + describe "#build_path" do + it "returns the build path" do expect(subject.build_path).to eq(build_path) end end - describe '#chroot_dir' do - it 'returns the right directory' do - expect(subject.chroot_dir).to eq(File.join(work_path, 'chroot')) + describe "#chroot_dir" do + it "returns the right directory" do + expect(subject.chroot_dir).to eq(File.join(work_path, "chroot")) end end - describe '#stemcell_files' do - it 'returns the right file path' do - allow(definition).to receive(:disk_formats) { ['disk-format-1', 'disk-format-2'] } - allow(definition).to receive(:stemcell_name).with('disk-format-1') { 'infra-hypervisor-os-version' } - allow(definition).to receive(:stemcell_name). - with('disk-format-2') { 'infra-hypervisor-os-version-disk-format-2' } + describe "#stemcell_files" do + it "returns the right file path" do + allow(definition).to receive(:disk_formats) { ["disk-format-1", "disk-format-2"] } + allow(definition).to receive(:stemcell_name).with("disk-format-1") { "infra-hypervisor-os-version" } + allow(definition).to receive(:stemcell_name) + .with("disk-format-2") { "infra-hypervisor-os-version-disk-format-2" } expect(subject.stemcell_files).to eq([ File.join(work_path, "bosh-stemcell-007-infra-hypervisor-os-version.tgz"), - File.join(work_path, "bosh-stemcell-007-infra-hypervisor-os-version-disk-format-2.tgz"), + File.join(work_path, "bosh-stemcell-007-infra-hypervisor-os-version-disk-format-2.tgz") ]) end end - describe '#settings_path' do - it 'returns the settings path' do + describe "#settings_path" do + it "returns the settings path" do expect(subject.settings_path).to eq(settings_file) end end - describe '#work_path' do - it 'returns the work path' do + describe "#work_path" do + it "returns the work path" do expect(subject.work_path).to eq(work_path) end end - describe '#command_env' do - context 'when the environment does not have HTTP_PROXY, HTTPS_PROXY or NO_PROXY variables' do - it 'includes no variables' do - expect(subject.command_env).to eq('env ') + describe "#command_env" do + context "when the environment does not have HTTP_PROXY, HTTPS_PROXY or NO_PROXY variables" do + it "includes no variables" do + expect(subject.command_env).to eq("env ") end end - context 'when the environment has HTTP_PROXY and NO_PROXY variables' do + context "when the environment has HTTP_PROXY and NO_PROXY variables" do let(:env) do { - 'HTTP_PROXY' => 'some_proxy', - 'NO_PROXY' => 'no_proxy', - 'SOME_PROXY' => 'other_proxy', + "HTTP_PROXY" => "some_proxy", + "NO_PROXY" => "no_proxy", + "SOME_PROXY" => "other_proxy" } end - it 'includes those variables' do + it "includes those variables" do expect(subject.command_env).to eq("env HTTP_PROXY='some_proxy' NO_PROXY='no_proxy'") end end - context 'when the environment has http_proxy and no_proxy variables' do + context "when the environment has http_proxy and no_proxy variables" do let(:env) do { - 'http_proxy' => 'some_proxy', - 'no_proxy' => 'no_proxy', - 'some_proxy' => 'other_proxy', + "http_proxy" => "some_proxy", + "no_proxy" => "no_proxy", + "some_proxy" => "other_proxy" } end - it 'includes those variables' do + it "includes those variables" do expect(subject.command_env).to eq("env http_proxy='some_proxy' no_proxy='no_proxy'") end end - context 'when the environment has HTTP_PROXY, HTTPS_PROXY and NO_PROXY variables' do + context "when the environment has HTTP_PROXY, HTTPS_PROXY and NO_PROXY variables" do let(:env) do { - 'HTTP_PROXY' => 'fake-http-proxy', - 'HTTPS_PROXY' => 'fake-https-proxy', - 'NO_PROXY' => 'fake-no-proxy', - 'SOME_PROXY' => 'fake-other-proxy', + "HTTP_PROXY" => "fake-http-proxy", + "HTTPS_PROXY" => "fake-https-proxy", + "NO_PROXY" => "fake-no-proxy", + "SOME_PROXY" => "fake-other-proxy" } end - it 'includes those variables' do + it "includes those variables" do expect(subject.command_env).to eq( "env HTTP_PROXY='fake-http-proxy' HTTPS_PROXY='fake-https-proxy' NO_PROXY='fake-no-proxy'" ) end end - context 'when the environment has http_proxy, https_proxy and no_proxy variables' do + context "when the environment has http_proxy, https_proxy and no_proxy variables" do let(:env) do { - 'http_proxy' => 'fake-http-proxy', - 'https_proxy' => 'fake-https-proxy', - 'no_proxy' => 'fake-no-proxy', - 'some_proxy' => 'fake-other-proxy', + "http_proxy" => "fake-http-proxy", + "https_proxy" => "fake-https-proxy", + "no_proxy" => "fake-no-proxy", + "some_proxy" => "fake-other-proxy" } end - it 'includes those variables' do + it "includes those variables" do expect(subject.command_env).to eq( "env http_proxy='fake-http-proxy' https_proxy='fake-https-proxy' no_proxy='fake-no-proxy'" ) end end - context 'when a build time env var is configured' do + context "when a build time env var is configured" do let(:env) do { - 'BUILD_TIME' => 'timestamp_from_env', + "BUILD_TIME" => "timestamp_from_env" } end - it 'includes the timestamp from env' do + it "includes the timestamp from env" do expect(subject.command_env).to eq( "env BUILD_TIME='timestamp_from_env'" ) end - context 'when a build time marker file exists' do + context "when a build time marker file exists" do before do allow(File).to receive(:exist?).with(build_time_marker_file).and_return(true) - allow(File).to receive(:read).with(build_time_marker_file).and_return('timestamp_from_file') + allow(File).to receive(:read).with(build_time_marker_file).and_return("timestamp_from_file") end - it 'includes the timestamp from the file' do + it "includes the timestamp from the file" do expect(subject.command_env).to eq( "env BUILD_TIME='timestamp_from_file'" ) diff --git a/bosh-stemcell/spec/bosh/stemcell/builder_options_spec.rb b/bosh-stemcell/spec/bosh/stemcell/builder_options_spec.rb index 59fd4ace37..43818bbdb1 100644 --- a/bosh-stemcell/spec/bosh/stemcell/builder_options_spec.rb +++ b/bosh-stemcell/spec/bosh/stemcell/builder_options_spec.rb @@ -1,6 +1,6 @@ -require 'spec_helper' -require 'bosh/stemcell/builder_options' -require 'bosh/stemcell/definition' +require "spec_helper" +require "bosh/stemcell/builder_options" +require "bosh/stemcell/definition" module Bosh::Stemcell describe BuilderOptions do @@ -9,8 +9,8 @@ module Bosh::Stemcell { env: env, definition: definition, - version: '007', - os_image_tarball: 'fake/os_image.tgz', + version: "007", + os_image_tarball: "fake/os_image.tgz" } end @@ -18,131 +18,131 @@ module Bosh::Stemcell let(:definition) { instance_double( - 'Bosh::Stemcell::Definition', + "Bosh::Stemcell::Definition", infrastructure: infrastructure, - operating_system: operating_system, + operating_system: operating_system ) } - let(:infrastructure) { Infrastructure.for('aws') } - let(:operating_system) { OperatingSystem.for('ubuntu', 'penguin-bear') } - let(:expected_source_root) { File.expand_path('../../../../..', __FILE__) } - let(:archive_filename) { instance_double('Bosh::Stemcell::ArchiveFilename', to_s: 'FAKE_STEMCELL.tgz') } + let(:infrastructure) { Infrastructure.for("aws") } + let(:operating_system) { OperatingSystem.for("ubuntu", "penguin-bear") } + let(:expected_source_root) { File.expand_path("../../../../..", __FILE__) } + let(:archive_filename) { instance_double("Bosh::Stemcell::ArchiveFilename", to_s: "FAKE_STEMCELL.tgz") } before do allow(ArchiveFilename).to receive(:new).and_return(archive_filename) end - describe '#default' do + describe "#default" do let(:default_disk_size) { 2048 } let(:rake_args) { {} } - it 'sets stemcell_image_name' do + it "sets stemcell_image_name" do result = stemcell_builder_options.default expected_image_name = "#{infrastructure.name}-#{infrastructure.hypervisor}-#{operating_system.name}.raw" - expect(result['stemcell_image_name']).to eq(expected_image_name) + expect(result["stemcell_image_name"]).to eq(expected_image_name) end - it 'sets stemcell_version' do + it "sets stemcell_version" do result = stemcell_builder_options.default - expect(result['stemcell_version']).to eq('007') + expect(result["stemcell_version"]).to eq("007") end - it 'sets stemcell operating system version' do + it "sets stemcell operating system version" do result = stemcell_builder_options.default - expect(result['stemcell_operating_system_version']).to eq('penguin') + expect(result["stemcell_operating_system_version"]).to eq("penguin") end - it 'sets stemcell operating system variant' do + it "sets stemcell operating system variant" do result = stemcell_builder_options.default - expect(result['stemcell_operating_system_variant']).to eq('bear') + expect(result["stemcell_operating_system_variant"]).to eq("bear") end - # rubocop:disable MethodLength + # rubocop:disable Metrics/MethodLength def self.it_sets_correct_environment_variables - describe 'setting enviroment variables' do + describe "setting enviroment variables" do let(:env) do { - 'UBUNTU_ISO' => 'fake_ubuntu_iso', - 'UBUNTU_MIRROR' => 'fake_ubuntu_mirror', - 'RUBY_BIN' => 'fake_ruby_bin', + "UBUNTU_ISO" => "fake_ubuntu_iso", + "UBUNTU_MIRROR" => "fake_ubuntu_mirror", + "RUBY_BIN" => "fake_ruby_bin" } end - it 'sets default values for options based in hash' do + it "sets default values for options based in hash" do result = stemcell_builder_options.default - expect(result['stemcell_operating_system']).to eq(operating_system.name) - expect(result['stemcell_infrastructure']).to eq(infrastructure.name) - expect(result['stemcell_hypervisor']).to eq(infrastructure.hypervisor) - expect(result['UBUNTU_ISO']).to eq('fake_ubuntu_iso') - expect(result['UBUNTU_MIRROR']).to eq('fake_ubuntu_mirror') - expect(result['ruby_bin']).to eq('fake_ruby_bin') - expect(result['image_create_disk_size']).to eq(default_disk_size) - expect(result['os_image_tgz']).to eq('fake/os_image.tgz') + expect(result["stemcell_operating_system"]).to eq(operating_system.name) + expect(result["stemcell_infrastructure"]).to eq(infrastructure.name) + expect(result["stemcell_hypervisor"]).to eq(infrastructure.hypervisor) + expect(result["UBUNTU_ISO"]).to eq("fake_ubuntu_iso") + expect(result["UBUNTU_MIRROR"]).to eq("fake_ubuntu_mirror") + expect(result["ruby_bin"]).to eq("fake_ruby_bin") + expect(result["image_create_disk_size"]).to eq(default_disk_size) + expect(result["os_image_tgz"]).to eq("fake/os_image.tgz") end - context 'when RUBY_BIN is not set' do - before { env.delete('RUBY_BIN') } + context "when RUBY_BIN is not set" do + before { env.delete("RUBY_BIN") } before do - allow(RbConfig::CONFIG).to receive(:[]).with('bindir').and_return('/a/path/to/') - allow(RbConfig::CONFIG).to receive(:[]).with('ruby_install_name').and_return('ruby') + allow(RbConfig::CONFIG).to receive(:[]).with("bindir").and_return("/a/path/to/") + allow(RbConfig::CONFIG).to receive(:[]).with("ruby_install_name").and_return("ruby") end - it 'uses the RbConfig values' do + it "uses the RbConfig values" do result = stemcell_builder_options.default - expect(result['ruby_bin']).to eq('/a/path/to/ruby') + expect(result["ruby_bin"]).to eq("/a/path/to/ruby") end end - context 'when disk_size is not passed' do - it 'defaults to default disk size for infrastructure' do + context "when disk_size is not passed" do + it "defaults to default disk size for infrastructure" do result = stemcell_builder_options.default - expect(result['image_create_disk_size']).to eq(default_disk_size) + expect(result["image_create_disk_size"]).to eq(default_disk_size) end end - context 'when disk_size is passed' do + context "when disk_size is passed" do before { dependencies[:disk_size] = 1234 } - it 'allows user to override default disk_size' do + it "allows user to override default disk_size" do result = stemcell_builder_options.default - expect(result['image_create_disk_size']).to eq(1234) + expect(result["image_create_disk_size"]).to eq(1234) end end end end - # rubocop:enable MethodLength + # rubocop:enable Metrics/MethodLength - describe 'infrastructure variation' do - context 'when infrastruture is aws' do - let(:infrastructure) { Infrastructure.for('aws') } + describe "infrastructure variation" do + context "when infrastruture is aws" do + let(:infrastructure) { Infrastructure.for("aws") } let(:default_disk_size) { 5120 } it_sets_correct_environment_variables it 'has no "image_ovftool_path" key' do - expect(stemcell_builder_options.default).not_to have_key('image_ovftool_path') + expect(stemcell_builder_options.default).not_to have_key("image_ovftool_path") end end - context 'when infrastruture is google' do - let(:infrastructure) { Infrastructure.for('google') } + context "when infrastruture is google" do + let(:infrastructure) { Infrastructure.for("google") } let(:default_disk_size) { 5120 } it_sets_correct_environment_variables it 'has no "image_ovftool_path" key' do - expect(stemcell_builder_options.default).not_to have_key('image_ovftool_path') + expect(stemcell_builder_options.default).not_to have_key("image_ovftool_path") end end - context 'when infrastruture is vsphere' do - let(:infrastructure) { Infrastructure.for('vsphere') } + context "when infrastruture is vsphere" do + let(:infrastructure) { Infrastructure.for("vsphere") } let(:default_disk_size) { 5120 } it_sets_correct_environment_variables @@ -150,39 +150,39 @@ def self.it_sets_correct_environment_variables it 'has an "image_ovftool_path" key' do result = stemcell_builder_options.default - expect(result['image_ovftool_path']).to be_nil + expect(result["image_ovftool_path"]).to be_nil end - context 'if you have OVFTOOL set in the environment' do - let(:env) { { 'OVFTOOL' => 'fake_ovf_tool_path' } } + context "if you have OVFTOOL set in the environment" do + let(:env) { {"OVFTOOL" => "fake_ovf_tool_path"} } - it 'sets image_ovftool_path' do + it "sets image_ovftool_path" do result = stemcell_builder_options.default - expect(result['image_ovftool_path']).to eq('fake_ovf_tool_path') + expect(result["image_ovftool_path"]).to eq("fake_ovf_tool_path") end end end - context 'when infrastructure is openstack' do - let(:infrastructure) { Infrastructure.for('openstack') } + context "when infrastructure is openstack" do + let(:infrastructure) { Infrastructure.for("openstack") } let(:default_disk_size) { 5120 } it_sets_correct_environment_variables it 'has no "image_ovftool_path" key' do - expect(stemcell_builder_options.default).not_to have_key('image_ovftool_path') + expect(stemcell_builder_options.default).not_to have_key("image_ovftool_path") end end - context 'when infrastruture is azure' do - let(:infrastructure) { Infrastructure.for('azure') } + context "when infrastruture is azure" do + let(:infrastructure) { Infrastructure.for("azure") } let(:default_disk_size) { 5120 } it_sets_correct_environment_variables it 'has no "image_ovftool_path" key' do - expect(stemcell_builder_options.default).not_to have_key('image_ovftool_path') + expect(stemcell_builder_options.default).not_to have_key("image_ovftool_path") end end end diff --git a/bosh-stemcell/spec/bosh/stemcell/definition_spec.rb b/bosh-stemcell/spec/bosh/stemcell/definition_spec.rb index 1083ce7ef2..f66dbb1e10 100644 --- a/bosh-stemcell/spec/bosh/stemcell/definition_spec.rb +++ b/bosh-stemcell/spec/bosh/stemcell/definition_spec.rb @@ -1,5 +1,5 @@ -require 'spec_helper' -require 'bosh/stemcell/definition' +require "spec_helper" +require "bosh/stemcell/definition" module Bosh::Stemcell describe Definition do @@ -7,63 +7,63 @@ module Bosh::Stemcell let(:infrastructure) do instance_double( - 'Bosh::Stemcell::Infrastructure::Base', - name: 'infrastructure-name', - hypervisor: 'hypervisor-name', - default_disk_format: 'default-disk-format' + "Bosh::Stemcell::Infrastructure::Base", + name: "infrastructure-name", + hypervisor: "hypervisor-name", + default_disk_format: "default-disk-format" ) end let(:hypervisor) { "hypervisor" } - let(:operating_system_version) { 'operating_system_version' } + let(:operating_system_version) { "operating_system_version" } let(:operating_system_variant) { nil } let(:operating_system) do instance_double( - 'Bosh::Stemcell::OperatingSystem::Base', - name: 'operating-system-name', + "Bosh::Stemcell::OperatingSystem::Base", + name: "operating-system-name", version: operating_system_version, - variant: operating_system_variant, + variant: operating_system_variant ) end - describe '.for' do - it 'sets the infrastructure, hypervisor, os, and os version' do + describe ".for" do + it "sets the infrastructure, hypervisor, os, and os version" do expect(Bosh::Stemcell::Infrastructure) .to receive(:for) - .with('infrastructure-name') - .and_return(infrastructure) + .with("infrastructure-name") + .and_return(infrastructure) expect(Bosh::Stemcell::OperatingSystem) .to receive(:for) - .with('operating-system-name', 'operating-system-version') - .and_return(operating_system) + .with("operating-system-name", "operating-system-version") + .and_return(operating_system) - definition = instance_double('Bosh::Stemcell::Definition') + definition = instance_double("Bosh::Stemcell::Definition") expect(Bosh::Stemcell::Definition) .to receive(:new) - .with(infrastructure, hypervisor, operating_system) - .and_return(definition) + .with(infrastructure, hypervisor, operating_system) + .and_return(definition) Bosh::Stemcell::Definition.for( - 'infrastructure-name', + "infrastructure-name", hypervisor, - 'operating-system-name', - 'operating-system-version' + "operating-system-name", + "operating-system-version" ) end end - describe '#initialize' do + describe "#initialize" do its(:infrastructure) { should == infrastructure } its(:operating_system) { should == operating_system } its(:hypervisor_name) { should == hypervisor } end - describe '#==' do - it 'compares by value instead of reference' do + describe "#==" do + it "compares by value instead of reference" do expect_eq = [ - %w(aws xen ubuntu 7), - %w(vsphere esxi ubuntu penguin), + %w[aws xen ubuntu 7], + %w[vsphere esxi ubuntu penguin] ] expect_eq.each do |tuple| @@ -71,7 +71,7 @@ module Bosh::Stemcell end expect_not_equal = [ - [['aws', 'xen', 'ubuntu', 'version'], ['vsphere', 'xen', 'ubuntu', 'version']], + [["aws", "xen", "ubuntu", "version"], ["vsphere", "xen", "ubuntu", "version"]] ] expect_not_equal.each do |left, right| expect(Definition.for(*left)).to_not eq(Definition.for(*right)) @@ -79,47 +79,47 @@ module Bosh::Stemcell end end - describe '#stemcell_name' do - it 'builds a name from the infrastructure, hypervisor, os, and disk format' do - expect(definition.stemcell_name('disk-format')).to eq( - 'infrastructure-name-hypervisor-operating-system-name-operating_system_version-disk-format' + describe "#stemcell_name" do + it "builds a name from the infrastructure, hypervisor, os, and disk format" do + expect(definition.stemcell_name("disk-format")).to eq( + "infrastructure-name-hypervisor-operating-system-name-operating_system_version-disk-format" ) end - context 'the os doesnt have a version' do + context "the os doesnt have a version" do let(:operating_system_version) { nil } - it 'leaves off the os version' do - expect(definition.stemcell_name('disk-format')).to eq( - 'infrastructure-name-hypervisor-operating-system-name-disk-format' + it "leaves off the os version" do + expect(definition.stemcell_name("disk-format")).to eq( + "infrastructure-name-hypervisor-operating-system-name-disk-format" ) end end - context 'the os has a variant' do - let(:operating_system_variant) { 'variant' } + context "the os has a variant" do + let(:operating_system_variant) { "variant" } - it 'leaves off the os version' do - expect(definition.stemcell_name('disk-format')).to eq( - 'infrastructure-name-hypervisor-operating-system-name-operating_system_version-variant-disk-format' + it "leaves off the os version" do + expect(definition.stemcell_name("disk-format")).to eq( + "infrastructure-name-hypervisor-operating-system-name-operating_system_version-variant-disk-format" ) end end - context 'the disk format is the default' do - it 'leaves it off' do - expect(definition.stemcell_name('default-disk-format')).to eq( - 'infrastructure-name-hypervisor-operating-system-name-operating_system_version' + context "the disk format is the default" do + it "leaves it off" do + expect(definition.stemcell_name("default-disk-format")).to eq( + "infrastructure-name-hypervisor-operating-system-name-operating_system_version" ) end end end - describe 'disk_formats' do - it 'delegates to infrastructure#disk_formats' do - expect(infrastructure).to receive(:disk_formats).and_return(['format1', 'format2']) + describe "disk_formats" do + it "delegates to infrastructure#disk_formats" do + expect(infrastructure).to receive(:disk_formats).and_return(["format1", "format2"]) - expect(definition.disk_formats).to eq(['format1', 'format2']) + expect(definition.disk_formats).to eq(["format1", "format2"]) end end end diff --git a/bosh-stemcell/spec/bosh/stemcell/disk_image_spec.rb b/bosh-stemcell/spec/bosh/stemcell/disk_image_spec.rb index 3f2013b890..e9d94a5975 100644 --- a/bosh-stemcell/spec/bosh/stemcell/disk_image_spec.rb +++ b/bosh-stemcell/spec/bosh/stemcell/disk_image_spec.rb @@ -1,17 +1,17 @@ -require 'spec_helper' -require 'bosh/stemcell/disk_image' +require "spec_helper" +require "bosh/stemcell/disk_image" module Bosh::Stemcell describe DiskImage do - let(:shell) { instance_double('Bosh::Core::Shell', run: nil) } - let(:kpartx_map_output) { 'add map FAKE_LOOP1p1 (252:3): 0 3997984 linear /dev/loop1 63' } + let(:shell) { instance_double("Bosh::Core::Shell", run: nil) } + let(:kpartx_map_output) { "add map FAKE_LOOP1p1 (252:3): 0 3997984 linear /dev/loop1 63" } let(:kpartx_map_output_efi) { "add map FAKE_LOOP1p1 (252:3): 0 3997984 linear /dev/loop1 63\nadd map FAKE_LOOP1p2 (252:3): 0 3997984 linear /dev/loop1 63" } let(:options) do { - image_file_path: '/path/to/FAKE_IMAGE', - image_mount_point: '/fake/mnt' + image_file_path: "/path/to/FAKE_IMAGE", + image_mount_point: "/fake/mnt" } end @@ -21,56 +21,55 @@ module Bosh::Stemcell allow(Bosh::Core::Shell).to receive(:new).and_return(shell) end - describe '#initialize' do - it 'requires an image_file_path' do + describe "#initialize" do + it "requires an image_file_path" do options.delete(:image_file_path) expect { DiskImage.new(options) }.to raise_error(/key not found: :image_file_path/) end - it 'requires an mount_point' do + it "requires an mount_point" do options.delete(:image_mount_point) - dir_mock = class_double('Dir').as_stubbed_const - expect(dir_mock).to receive(:mktmpdir).and_return('/fake/tmpdir') + dir_mock = class_double("Dir").as_stubbed_const + expect(dir_mock).to receive(:mktmpdir).and_return("/fake/tmpdir") - expect(DiskImage.new(options).image_mount_point).to eq('/fake/tmpdir') + expect(DiskImage.new(options).image_mount_point).to eq("/fake/tmpdir") end end - describe '#mount' do - it 'maps the file to a loop device' do - losetup_commad = 'sudo losetup --show --find /path/to/FAKE_IMAGE' - allow(shell).to receive(:run).with(losetup_commad, output_command: false).and_return('/dev/loop0') - expect(shell).to receive(:run). - with('sudo kpartx -sav /dev/loop0', output_command: false).and_return(kpartx_map_output) + describe "#mount" do + it "maps the file to a loop device" do + losetup_commad = "sudo losetup --show --find /path/to/FAKE_IMAGE" + allow(shell).to receive(:run).with(losetup_commad, output_command: false).and_return("/dev/loop0") + expect(shell).to receive(:run) + .with("sudo kpartx -sav /dev/loop0", output_command: false).and_return(kpartx_map_output) disk_image.mount end - it 'mounts the loop device' do - losetup_commad = 'sudo losetup --show --find /path/to/FAKE_IMAGE' - allow(shell).to receive(:run).with(losetup_commad, output_command: false).and_return('/dev/loop0') - allow(shell).to receive(:run). - with('sudo kpartx -sav /dev/loop0', output_command: false).and_return(kpartx_map_output) - expect(shell).to receive(:run).with('sudo mount /dev/mapper/FAKE_LOOP1p1 /fake/mnt', output_command: false) + it "mounts the loop device" do + losetup_commad = "sudo losetup --show --find /path/to/FAKE_IMAGE" + allow(shell).to receive(:run).with(losetup_commad, output_command: false).and_return("/dev/loop0") + allow(shell).to receive(:run) + .with("sudo kpartx -sav /dev/loop0", output_command: false).and_return(kpartx_map_output) + expect(shell).to receive(:run).with("sudo mount /dev/mapper/FAKE_LOOP1p1 /fake/mnt", output_command: false) disk_image.mount end - - it 'mounts efi image on the loop device' do - losetup_commad = 'sudo losetup --show --find /path/to/FAKE_IMAGE' - allow(shell).to receive(:run).with(losetup_commad, output_command: false).and_return('/dev/loop0') - allow(shell).to receive(:run). - with('sudo kpartx -sav /dev/loop0', output_command: false).and_return(kpartx_map_output_efi) - expect(shell).to receive(:run).with('sudo mount /dev/mapper/FAKE_LOOP1p2 /fake/mnt', output_command: false) - expect(shell).to receive(:run).with('sudo mount -o umask=0177 /dev/mapper/FAKE_LOOP1p1 /fake/mnt/boot/efi', output_command: false) + it "mounts efi image on the loop device" do + losetup_commad = "sudo losetup --show --find /path/to/FAKE_IMAGE" + allow(shell).to receive(:run).with(losetup_commad, output_command: false).and_return("/dev/loop0") + allow(shell).to receive(:run) + .with("sudo kpartx -sav /dev/loop0", output_command: false).and_return(kpartx_map_output_efi) + expect(shell).to receive(:run).with("sudo mount /dev/mapper/FAKE_LOOP1p2 /fake/mnt", output_command: false) + expect(shell).to receive(:run).with("sudo mount -o umask=0177 /dev/mapper/FAKE_LOOP1p1 /fake/mnt/boot/efi", output_command: false) disk_image.mount end - context 'when the device does not exist' do - let(:mount_command) { 'sudo mount /dev/mapper/FAKE_LOOP1p1 /fake/mnt' } + context "when the device does not exist" do + let(:mount_command) { "sudo mount /dev/mapper/FAKE_LOOP1p1 /fake/mnt" } let(:mount_error) do "Failed: '#{mount_command}' from /fake/mnt/blah/blah/bosh-stemcell, with exit status 8192\n\n" end @@ -79,11 +78,11 @@ module Bosh::Stemcell allow(disk_image).to receive(:sleep) end - it 'runs mount a second time after sleeping long enough for the device node to be created' do - losetup_commad = 'sudo losetup --show --find /path/to/FAKE_IMAGE' - allow(shell).to receive(:run).with(losetup_commad, output_command: false).and_return('/dev/loop0') - allow(shell).to receive(:run). - with('sudo kpartx -sav /dev/loop0', output_command: false).and_return(kpartx_map_output) + it "runs mount a second time after sleeping long enough for the device node to be created" do + losetup_commad = "sudo losetup --show --find /path/to/FAKE_IMAGE" + allow(shell).to receive(:run).with(losetup_commad, output_command: false).and_return("/dev/loop0") + allow(shell).to receive(:run) + .with("sudo kpartx -sav /dev/loop0", output_command: false).and_return(kpartx_map_output) expect(shell).to receive(:run).with(mount_command, output_command: false).ordered.and_raise(mount_error) expect(disk_image).to receive(:sleep).with(0.5) expect(shell).to receive(:run).with(mount_command, output_command: false).ordered @@ -91,75 +90,75 @@ module Bosh::Stemcell disk_image.mount end - context 'when the second mount command fails' do - it 'raises an error' do - losetup_commad = 'sudo losetup --show --find /path/to/FAKE_IMAGE' - allow(shell).to receive(:run).with(losetup_commad, output_command: false).and_return('/dev/loop0') - allow(shell).to receive(:run). - with('sudo kpartx -sav /dev/loop0', output_command: false).and_return(kpartx_map_output) - expect(shell).to receive(:run). - with(mount_command, output_command: false).ordered.twice.and_raise(mount_error) + context "when the second mount command fails" do + it "raises an error" do + losetup_commad = "sudo losetup --show --find /path/to/FAKE_IMAGE" + allow(shell).to receive(:run).with(losetup_commad, output_command: false).and_return("/dev/loop0") + allow(shell).to receive(:run) + .with("sudo kpartx -sav /dev/loop0", output_command: false).and_return(kpartx_map_output) + expect(shell).to receive(:run) + .with(mount_command, output_command: false).ordered.twice.and_raise(mount_error) expect { disk_image.mount }.to raise_error(mount_error) end end end - context 'when the mount command fails' do - it 'runs mount a second time' do - losetup_commad = 'sudo losetup --show --find /path/to/FAKE_IMAGE' - allow(shell).to receive(:run).with(losetup_commad, output_command: false).and_return('/dev/loop0') - allow(shell).to receive(:run). - with('sudo kpartx -sav /dev/loop0', output_command: false).and_return(kpartx_map_output) - expect(shell).to receive(:run). - with('sudo mount /dev/mapper/FAKE_LOOP1p1 /fake/mnt', output_command: false).ordered. - and_raise(RuntimeError, 'UNEXEPECTED') - - expect { disk_image.mount }.to raise_error(RuntimeError, 'UNEXEPECTED') + context "when the mount command fails" do + it "runs mount a second time" do + losetup_commad = "sudo losetup --show --find /path/to/FAKE_IMAGE" + allow(shell).to receive(:run).with(losetup_commad, output_command: false).and_return("/dev/loop0") + allow(shell).to receive(:run) + .with("sudo kpartx -sav /dev/loop0", output_command: false).and_return(kpartx_map_output) + expect(shell).to receive(:run) + .with("sudo mount /dev/mapper/FAKE_LOOP1p1 /fake/mnt", output_command: false).ordered + .and_raise(RuntimeError, "UNEXEPECTED") + + expect { disk_image.mount }.to raise_error(RuntimeError, "UNEXEPECTED") end end end - describe '#unmount' do + describe "#unmount" do before do - allow(disk_image).to receive(:device).and_return('/dev/loop0') # pretend we've mounted + allow(disk_image).to receive(:device).and_return("/dev/loop0") # pretend we've mounted end - it 'unmounts the loop device and then unmaps the file' do - losetup_commad = 'sudo losetup --show --find /path/to/FAKE_IMAGE' - allow(shell).to receive(:run).with(losetup_commad, output_command: false).and_return('/dev/loop0') - expect(shell).to receive(:run). - with('sudo kpartx -sav /dev/loop0', output_command: false).and_return(kpartx_map_output) - expect(shell).to receive(:run).with('sudo umount /fake/mnt', output_command: false).ordered - expect(shell).to receive(:run).with('sudo kpartx -dv /dev/loop0', output_command: false).ordered - expect(shell).to receive(:run).with('sudo losetup -v -d /dev/loop0', output_command: false).ordered + it "unmounts the loop device and then unmaps the file" do + losetup_commad = "sudo losetup --show --find /path/to/FAKE_IMAGE" + allow(shell).to receive(:run).with(losetup_commad, output_command: false).and_return("/dev/loop0") + expect(shell).to receive(:run) + .with("sudo kpartx -sav /dev/loop0", output_command: false).and_return(kpartx_map_output) + expect(shell).to receive(:run).with("sudo umount /fake/mnt", output_command: false).ordered + expect(shell).to receive(:run).with("sudo kpartx -dv /dev/loop0", output_command: false).ordered + expect(shell).to receive(:run).with("sudo losetup -v -d /dev/loop0", output_command: false).ordered disk_image.unmount end - it 'unmounts efi image on the loop device and then unmaps the file' do - losetup_commad = 'sudo losetup --show --find /path/to/FAKE_IMAGE' - allow(shell).to receive(:run).with(losetup_commad, output_command: false).and_return('/dev/loop0') - expect(shell).to receive(:run). - with('sudo kpartx -sav /dev/loop0', output_command: false).and_return(kpartx_map_output_efi) - expect(shell).to receive(:run).with('sudo umount /fake/mnt', output_command: false).ordered - expect(shell).to receive(:run).with('sudo kpartx -dv /dev/loop0', output_command: false).ordered - expect(shell).to receive(:run).with('sudo losetup -v -d /dev/loop0', output_command: false).ordered + it "unmounts efi image on the loop device and then unmaps the file" do + losetup_commad = "sudo losetup --show --find /path/to/FAKE_IMAGE" + allow(shell).to receive(:run).with(losetup_commad, output_command: false).and_return("/dev/loop0") + expect(shell).to receive(:run) + .with("sudo kpartx -sav /dev/loop0", output_command: false).and_return(kpartx_map_output_efi) + expect(shell).to receive(:run).with("sudo umount /fake/mnt", output_command: false).ordered + expect(shell).to receive(:run).with("sudo kpartx -dv /dev/loop0", output_command: false).ordered + expect(shell).to receive(:run).with("sudo losetup -v -d /dev/loop0", output_command: false).ordered disk_image.unmount end - it 'unmaps the file even if unmounting the device fails' do - losetup_commad = 'sudo losetup --show --find /path/to/FAKE_IMAGE' - allow(shell).to receive(:run).with(losetup_commad, output_command: false).and_return('/dev/loop0') - expect(shell).to receive(:run). - with('sudo kpartx -sav /dev/loop0', output_command: false).and_return(kpartx_map_output) - expect(shell).to receive(:run).with('sudo umount /fake/mnt', output_command: false).and_raise - expect(shell).to receive(:run).with('sudo kpartx -dv /dev/loop0', output_command: false).ordered - expect(shell).to receive(:run).with('sudo losetup -v -d /dev/loop0', output_command: false).ordered + it "unmaps the file even if unmounting the device fails" do + losetup_commad = "sudo losetup --show --find /path/to/FAKE_IMAGE" + allow(shell).to receive(:run).with(losetup_commad, output_command: false).and_return("/dev/loop0") + expect(shell).to receive(:run) + .with("sudo kpartx -sav /dev/loop0", output_command: false).and_return(kpartx_map_output) + expect(shell).to receive(:run).with("sudo umount /fake/mnt", output_command: false).and_raise + expect(shell).to receive(:run).with("sudo kpartx -dv /dev/loop0", output_command: false).ordered + expect(shell).to receive(:run).with("sudo losetup -v -d /dev/loop0", output_command: false).ordered expect { disk_image.unmount }.to raise_error RuntimeError end end end -end \ No newline at end of file +end diff --git a/bosh-stemcell/spec/bosh/stemcell/helpers_sh_spec.rb b/bosh-stemcell/spec/bosh/stemcell/helpers_sh_spec.rb index 2747362df2..8268e8c47d 100644 --- a/bosh-stemcell/spec/bosh/stemcell/helpers_sh_spec.rb +++ b/bosh-stemcell/spec/bosh/stemcell/helpers_sh_spec.rb @@ -1,67 +1,69 @@ -require 'spec_helper' +require "spec_helper" -context 'helpers.sh' do +context "helpers.sh" do + before do + skip "This spec requires linux" unless RUBY_PLATFORM.downcase.include?("linux") + end - context 'add_on_exit runs cleanup commands in LIFO order' do + context "add_on_exit runs cleanup commands in LIFO order" do describe ShelloutTypes::Command.new( File.expand_path( - '../../../assets/on_exit_with_normal_completion.sh', + "../../../assets/on_exit_with_normal_completion.sh", __FILE__ ), - ShelloutTypes::Chroot.new('/') + ShelloutTypes::Chroot.new("/") ) do - it('describes the on_exit actions in that order') { expect(subject.stdout).to match < '/dev/sda1', 'boot_mode' => 'uefi-preferred'}) + it "has aws specific additional cloud properties" do + expect(subject.additional_cloud_properties).to eq({"root_device_name" => "/dev/sda1", "boot_mode" => "uefi-preferred"}) end end describe Infrastructure::Google do - its(:name) { should eq('google') } - its(:hypervisor) { should eq('kvm') } + its(:name) { should eq("google") } + its(:hypervisor) { should eq("kvm") } its(:default_disk_size) { should eq(5120) } - its(:disk_formats) { should eq(['rawdisk']) } - its(:stemcell_formats) { should eq(['google-rawdisk']) } + its(:disk_formats) { should eq(["rawdisk"]) } + its(:stemcell_formats) { should eq(["google-rawdisk"]) } - it { should eq Infrastructure.for('google') } - it { should_not eq Infrastructure.for('openstack') } + it { should eq Infrastructure.for("google") } + it { should_not eq Infrastructure.for("openstack") } - it 'has google specific additional cloud properties' do - expect(subject.additional_cloud_properties).to eq({'root_device_name' => '/dev/sda1'}) + it "has google specific additional cloud properties" do + expect(subject.additional_cloud_properties).to eq({"root_device_name" => "/dev/sda1"}) end end describe Infrastructure::OpenStack do - its(:name) { should eq('openstack') } - its(:hypervisor) { should eq('kvm') } + its(:name) { should eq("openstack") } + its(:hypervisor) { should eq("kvm") } its(:default_disk_size) { should eq(5120) } - its(:disk_formats) { should eq(['qcow2', 'raw']) } - its(:stemcell_formats) { should eq(['openstack-qcow2', 'openstack-raw']) } + its(:disk_formats) { should eq(["qcow2", "raw"]) } + its(:stemcell_formats) { should eq(["openstack-qcow2", "openstack-raw"]) } - it { should eq Infrastructure.for('openstack') } - it { should_not eq Infrastructure.for('vsphere') } + it { should eq Infrastructure.for("openstack") } + it { should_not eq Infrastructure.for("vsphere") } - it 'has openstack specific additional cloud properties' do - expect(subject.additional_cloud_properties).to eq({'auto_disk_config' => true}) + it "has openstack specific additional cloud properties" do + expect(subject.additional_cloud_properties).to eq({"auto_disk_config" => true}) end end describe Infrastructure::CloudStack do - its(:name) { should eq('cloudstack') } - its(:hypervisor) { should eq('xen') } + its(:name) { should eq("cloudstack") } + its(:hypervisor) { should eq("xen") } its(:default_disk_size) { should eq(5120) } - its(:disk_formats) {should eq(['vhdx'])} - its(:stemcell_formats) { should eq(['cloudstack-vhdx']) } + its(:disk_formats) { should eq(["vhdx"]) } + its(:stemcell_formats) { should eq(["cloudstack-vhdx"]) } - it { should eq Infrastructure.for('cloudstack') } - it { should_not eq Infrastructure.for('vsphere') } + it { should eq Infrastructure.for("cloudstack") } + it { should_not eq Infrastructure.for("vsphere") } - it 'has cloudstack specific additional cloud properties' do - expect(subject.additional_cloud_properties).to eq({'auto_disk_config' => true}) + it "has cloudstack specific additional cloud properties" do + expect(subject.additional_cloud_properties).to eq({"auto_disk_config" => true}) end end describe Infrastructure::Vsphere do - its(:name) { should eq('vsphere') } - its(:hypervisor) { should eq('esxi') } + its(:name) { should eq("vsphere") } + its(:hypervisor) { should eq("esxi") } its(:default_disk_size) { should eq(5120) } - its(:disk_formats) { should eq(['ovf']) } - its(:stemcell_formats) { should eq(['vsphere-ova', 'vsphere-ovf']) } + its(:disk_formats) { should eq(["ovf"]) } + its(:stemcell_formats) { should eq(["vsphere-ova", "vsphere-ovf"]) } - it { should eq Infrastructure.for('vsphere') } - it { should_not eq Infrastructure.for('aws') } + it { should eq Infrastructure.for("vsphere") } + it { should_not eq Infrastructure.for("aws") } - it 'has vsphere specific additional cloud properties' do - expect(subject.additional_cloud_properties).to eq({'root_device_name' => '/dev/sda1'}) + it "has vsphere specific additional cloud properties" do + expect(subject.additional_cloud_properties).to eq({"root_device_name" => "/dev/sda1"}) end end describe Infrastructure::Azure do - its(:name) { should eq('azure') } - its(:hypervisor) { should eq('hyperv') } + its(:name) { should eq("azure") } + its(:hypervisor) { should eq("hyperv") } its(:default_disk_size) { should eq(5120) } - its(:disk_formats) { should eq(['vhd']) } - its(:stemcell_formats) { should eq(['azure-vhd']) } + its(:disk_formats) { should eq(["vhd"]) } + its(:stemcell_formats) { should eq(["azure-vhd"]) } - it { should eq Infrastructure.for('azure') } + it { should eq Infrastructure.for("azure") } - it 'has azure specific additional cloud properties' do + it "has azure specific additional cloud properties" do expect(subject.additional_cloud_properties).to eq({ - 'root_device_name' => '/dev/sda1', - 'generation' => 'gen2', - 'accelerated_networking' => true, - 'hibernation' => true, - 'disk_controller_types' => ['scsi', 'nvme'], - 'security_type' => 'TrustedLaunchSupported' + "root_device_name" => "/dev/sda1", + "generation" => "gen2", + "accelerated_networking" => true, + "hibernation" => true, + "disk_controller_types" => ["scsi", "nvme"], + "security_type" => "TrustedLaunchSupported" }) end end - end diff --git a/bosh-stemcell/spec/bosh/stemcell/operating_system_spec.rb b/bosh-stemcell/spec/bosh/stemcell/operating_system_spec.rb index 2cf495e0ad..fba9bc768d 100644 --- a/bosh-stemcell/spec/bosh/stemcell/operating_system_spec.rb +++ b/bosh-stemcell/spec/bosh/stemcell/operating_system_spec.rb @@ -1,61 +1,61 @@ -require 'spec_helper' -require 'bosh/stemcell/operating_system' +require "spec_helper" +require "bosh/stemcell/operating_system" module Bosh::Stemcell describe OperatingSystem do - describe '.for' do - it 'returns the correct infrastrcture' do - expect(OperatingSystem.for('ubuntu', 'penguin')).to be_a(OperatingSystem::Ubuntu) + describe ".for" do + it "returns the correct infrastrcture" do + expect(OperatingSystem.for("ubuntu", "penguin")).to be_a(OperatingSystem::Ubuntu) end - it 'raises for unknown operating system' do + it "raises for unknown operating system" do expect { - OperatingSystem.for('BAD_OPERATING_SYSTEM', 'BAD_OS_VERSION') + OperatingSystem.for("BAD_OPERATING_SYSTEM", "BAD_OS_VERSION") }.to raise_error(ArgumentError, /invalid operating system: BAD_OPERATING_SYSTEM/) end end end describe OperatingSystem::Base do - describe '#initialize' do - it 'requires :name to be specified' do + describe "#initialize" do + it "requires :name to be specified" do expect { OperatingSystem::Base.new - }.to raise_error /key not found: :name/ + }.to raise_error(/key not found: :name/) end - it 'requires :version to be specified' do + it "requires :version to be specified" do expect { - OperatingSystem::Base.new(name: 'CLOUDY_PONY_OS') - }.to raise_error /key not found: :version/ + OperatingSystem::Base.new(name: "CLOUDY_PONY_OS") + }.to raise_error(/key not found: :version/) end end - describe '#name' do - subject { OperatingSystem::Base.new(name: 'CLOUDY_PONY_OS', version: 'HORSESHOE') } + describe "#name" do + subject { OperatingSystem::Base.new(name: "CLOUDY_PONY_OS", version: "HORSESHOE") } - its(:name) { should eq('CLOUDY_PONY_OS') } + its(:name) { should eq("CLOUDY_PONY_OS") } end - describe '#version' do - subject { OperatingSystem::Base.new(name: 'CLOUDY_PONY_OS', version: 'HORSESHOE') } + describe "#version" do + subject { OperatingSystem::Base.new(name: "CLOUDY_PONY_OS", version: "HORSESHOE") } - its(:version) { should eq('HORSESHOE') } + its(:version) { should eq("HORSESHOE") } end - describe '#variant' do - subject { OperatingSystem::Base.new(name: 'CLOUDY_PONY_OS', version: 'HORSESHOE', variant: 'DONKYTAIL') } + describe "#variant" do + subject { OperatingSystem::Base.new(name: "CLOUDY_PONY_OS", version: "HORSESHOE", variant: "DONKYTAIL") } - its(:variant) { should eq('DONKYTAIL') } + its(:variant) { should eq("DONKYTAIL") } end end describe OperatingSystem::Ubuntu do - subject { OperatingSystem::Ubuntu.new('penguin-gentoo') } + subject { OperatingSystem::Ubuntu.new("penguin-gentoo") } - its(:name) { should eq('ubuntu') } - its(:version) { should eq('penguin') } - its(:variant) { should eq('gentoo') } - it { should eq OperatingSystem.for('ubuntu', 'penguin-gentoo') } + its(:name) { should eq("ubuntu") } + its(:version) { should eq("penguin") } + its(:variant) { should eq("gentoo") } + it { should eq OperatingSystem.for("ubuntu", "penguin-gentoo") } end end diff --git a/bosh-stemcell/spec/bosh/stemcell/os_image_builder_spec.rb b/bosh-stemcell/spec/bosh/stemcell/os_image_builder_spec.rb index c4ccc11284..e5d0575244 100644 --- a/bosh-stemcell/spec/bosh/stemcell/os_image_builder_spec.rb +++ b/bosh-stemcell/spec/bosh/stemcell/os_image_builder_spec.rb @@ -1,9 +1,9 @@ -require 'spec_helper' -require 'bosh/stemcell/archive_handler' -require 'bosh/stemcell/build_environment' -require 'bosh/stemcell/stage_collection' -require 'bosh/stemcell/stage_runner' -require 'bosh/stemcell/os_image_builder' +require "spec_helper" +require "bosh/stemcell/archive_handler" +require "bosh/stemcell/build_environment" +require "bosh/stemcell/stage_collection" +require "bosh/stemcell/stage_runner" +require "bosh/stemcell/os_image_builder" describe Bosh::Stemcell::OsImageBuilder do subject(:builder) do @@ -11,32 +11,32 @@ environment: environment, collection: collection, runner: runner, - archive_handler: archive_handler, + archive_handler: archive_handler ) end - let(:environment) { instance_double('Bosh::Stemcell::BuildEnvironment', prepare_build: nil, chroot_dir: '/chroot') } - let(:collection) { instance_double('Bosh::Stemcell::StageCollection', operating_system_stages: nil) } - let(:runner) { instance_double('Bosh::Stemcell::StageRunner', configure_and_apply: nil) } - let(:archive_handler) { instance_double('Bosh::Stemcell::ArchiveHandler', compress: nil) } + let(:environment) { instance_double("Bosh::Stemcell::BuildEnvironment", prepare_build: nil, chroot_dir: "/chroot") } + let(:collection) { instance_double("Bosh::Stemcell::StageCollection", operating_system_stages: nil) } + let(:runner) { instance_double("Bosh::Stemcell::StageRunner", configure_and_apply: nil) } + let(:archive_handler) { instance_double("Bosh::Stemcell::ArchiveHandler", compress: nil) } - describe '#build' do - it 'prepares the build environment' do + describe "#build" do + it "prepares the build environment" do expect(environment).to receive(:prepare_build) - builder.build('/some/os_image_path.tgz') + builder.build("/some/os_image_path.tgz") end - it 'runs the operating system stages' do + it "runs the operating system stages" do allow(collection).to receive(:operating_system_stages).and_return([:some_stage]) expect(runner).to receive(:configure_and_apply).with([:some_stage], nil) - builder.build('/some/os_image_path.tgz') + builder.build("/some/os_image_path.tgz") end - it 'tars up the chroot dir' do - expect(archive_handler).to receive(:compress).with('/chroot', '/some/os_image_path.tgz') + it "tars up the chroot dir" do + expect(archive_handler).to receive(:compress).with("/chroot", "/some/os_image_path.tgz") - builder.build('/some/os_image_path.tgz') + builder.build("/some/os_image_path.tgz") end end end diff --git a/bosh-stemcell/spec/bosh/stemcell/stage_collection_spec.rb b/bosh-stemcell/spec/bosh/stemcell/stage_collection_spec.rb index 048d0451ca..b7ed65cc61 100644 --- a/bosh-stemcell/spec/bosh/stemcell/stage_collection_spec.rb +++ b/bosh-stemcell/spec/bosh/stemcell/stage_collection_spec.rb @@ -1,87 +1,87 @@ -require 'spec_helper' -require 'bosh/stemcell/arch' -require 'bosh/stemcell/stage_collection' +require "spec_helper" +require "bosh/stemcell/arch" +require "bosh/stemcell/stage_collection" module Bosh::Stemcell describe StageCollection do subject(:stage_collection) { StageCollection.new(definition) } let(:definition) do instance_double( - 'Bosh::Stemcell::Definition', + "Bosh::Stemcell::Definition", infrastructure: infrastructure, - operating_system: operating_system, + operating_system: operating_system ) end let(:agent) { double } let(:infrastructure) { double } let(:operating_system) { double } - describe '#operating_system_stages' do - let(:operating_system) { OperatingSystem.for('ubuntu') } + describe "#operating_system_stages" do + let(:operating_system) { OperatingSystem.for("ubuntu") } - it 'has the correct stages' do + it "has the correct stages" do expect(stage_collection.operating_system_stages).to eq( - [ - :base_debootstrap, - :base_ubuntu_firstboot, - :base_apt, - :base_ubuntu_build_essential, - :base_ubuntu_packages, - :bosh_systemd_resolved, - :base_file_permission, - :base_ssh, - :bosh_sysstat, - :bosh_environment, - :bosh_sysctl, - :bosh_limits, - :bosh_users, - :bosh_monit, - :bosh_ntp, - :bosh_sudoers, - :bosh_systemd, - :password_policies, - :restrict_su_command, - :tty_config, - :rsyslog_config, - :system_grub, - :vim_tiny, - :cron_config, - :escape_ctrl_alt_del, - :bosh_audit_ubuntu, - :bosh_log_audit_start, - :clean_machine_id, - ] - ) + [ + :base_debootstrap, + :base_ubuntu_firstboot, + :base_apt, + :base_ubuntu_build_essential, + :base_ubuntu_packages, + :bosh_systemd_resolved, + :base_file_permission, + :base_ssh, + :bosh_sysstat, + :bosh_environment, + :bosh_sysctl, + :bosh_limits, + :bosh_users, + :bosh_monit, + :bosh_ntp, + :bosh_sudoers, + :bosh_systemd, + :password_policies, + :restrict_su_command, + :tty_config, + :rsyslog_config, + :system_grub, + :vim_tiny, + :cron_config, + :escape_ctrl_alt_del, + :bosh_audit_ubuntu, + :bosh_log_audit_start, + :clean_machine_id + ] + ) end end - describe '#agent_stages' do + describe "#agent_stages" do let(:agent_stages) do [ :bosh_go_agent, :blobstore_clis, :logrotate_config, :dev_tools_config, - :static_libraries_config, + :static_libraries_config ] end - it 'returns the correct stages' do + it "returns the correct stages" do expect(stage_collection.agent_stages).to eq(agent_stages) end end - describe '#build_stemcell_image_stages' do + describe "#build_stemcell_image_stages" do let(:vmware_package_stemcell_steps) { [ :image_ovf_vmx, :image_ovf_generate, - :prepare_ovf_image_stemcell, + :prepare_ovf_image_stemcell ] } - context 'when using AWS' do - let(:infrastructure) { Infrastructure.for('aws') } + context "when using AWS" do + let(:infrastructure) { Infrastructure.for("aws") } let(:aws_build_stemcell_image_stages) { [ :system_network, @@ -96,24 +96,24 @@ module Bosh::Stemcell :image_install_grub, :sbom_create, :bosh_package_list, - :restore_apt_sources, + :restore_apt_sources ] } let(:aws_package_stemcell_stages) { [ - :prepare_raw_image_stemcell, + :prepare_raw_image_stemcell ] } - let(:operating_system) { OperatingSystem.for('ubuntu') } + let(:operating_system) { OperatingSystem.for("ubuntu") } - it 'returns the correct stages' do + it "returns the correct stages" do expect(stage_collection.build_stemcell_image_stages).to eq(aws_build_stemcell_image_stages) - expect(stage_collection.package_stemcell_stages('raw')).to eq(aws_package_stemcell_stages) + expect(stage_collection.package_stemcell_stages("raw")).to eq(aws_package_stemcell_stages) end end - context 'when using Alicloud' do - let(:infrastructure) { Infrastructure.for('alicloud') } + context "when using Alicloud" do + let(:infrastructure) { Infrastructure.for("alicloud") } let(:alicloud_build_stemcell_image_stages) { [ @@ -128,25 +128,25 @@ module Bosh::Stemcell :image_install_grub, :sbom_create, :bosh_package_list, - :restore_apt_sources, + :restore_apt_sources ] } let(:alicloud_package_stemcell_stages) { [ - :prepare_raw_image_stemcell, + :prepare_raw_image_stemcell ] } - let(:operating_system) { OperatingSystem.for('ubuntu') } + let(:operating_system) { OperatingSystem.for("ubuntu") } - it 'returns the correct stages' do + it "returns the correct stages" do expect(stage_collection.build_stemcell_image_stages).to eq(alicloud_build_stemcell_image_stages) - expect(stage_collection.package_stemcell_stages('raw')).to eq(alicloud_package_stemcell_stages) + expect(stage_collection.package_stemcell_stages("raw")).to eq(alicloud_package_stemcell_stages) end end - context 'when using Google' do - let(:infrastructure) { Infrastructure.for('google') } + context "when using Google" do + let(:infrastructure) { Infrastructure.for("google") } let(:google_build_stemcell_image_stages) { [ @@ -162,114 +162,114 @@ module Bosh::Stemcell :image_install_grub, :sbom_create, :bosh_package_list, - :restore_apt_sources, + :restore_apt_sources ] } let(:google_package_stemcell_stages) { [ - :prepare_rawdisk_image_stemcell, + :prepare_rawdisk_image_stemcell ] } - let(:operating_system) { OperatingSystem.for('ubuntu') } + let(:operating_system) { OperatingSystem.for("ubuntu") } - it 'returns the correct stages' do + it "returns the correct stages" do expect(stage_collection.build_stemcell_image_stages).to eq(google_build_stemcell_image_stages) - expect(stage_collection.package_stemcell_stages('rawdisk')).to eq(google_package_stemcell_stages) + expect(stage_collection.package_stemcell_stages("rawdisk")).to eq(google_package_stemcell_stages) end end - context 'when using OpenStack' do - let(:infrastructure) { Infrastructure.for('openstack') } - let(:operating_system) { OperatingSystem.for('ubuntu') } + context "when using OpenStack" do + let(:infrastructure) { Infrastructure.for("openstack") } + let(:operating_system) { OperatingSystem.for("ubuntu") } - it 'has the correct stages' do + it "has the correct stages" do expect(stage_collection.build_stemcell_image_stages).to eq( - [ - :system_network, - :system_openstack_clock, - :system_openstack_modules, - :system_parameters, - :bosh_clean, - :bosh_harden, - :bosh_openstack_agent_settings, - :bosh_clean_ssh, - :image_create_efi, - :image_install_grub, - :sbom_create, - :bosh_package_list, - :restore_apt_sources, - ] - ) - expect(stage_collection.package_stemcell_stages('qcow2')).to eq( - [ - :prepare_qcow2_image_stemcell, - ] - ) + [ + :system_network, + :system_openstack_clock, + :system_openstack_modules, + :system_parameters, + :bosh_clean, + :bosh_harden, + :bosh_openstack_agent_settings, + :bosh_clean_ssh, + :image_create_efi, + :image_install_grub, + :sbom_create, + :bosh_package_list, + :restore_apt_sources + ] + ) + expect(stage_collection.package_stemcell_stages("qcow2")).to eq( + [ + :prepare_qcow2_image_stemcell + ] + ) end end - context 'when using CloudStack' do - let(:infrastructure) { Infrastructure.for('cloudstack') } - let(:operating_system) { OperatingSystem.for('ubuntu') } + context "when using CloudStack" do + let(:infrastructure) { Infrastructure.for("cloudstack") } + let(:operating_system) { OperatingSystem.for("ubuntu") } - it 'has the correct stages' do + it "has the correct stages" do expect(stage_collection.build_stemcell_image_stages).to eq( - [ - :system_network, - :system_openstack_modules, - :bosh_cloudstack_ubuntu_vr_metadata, - :system_ubuntu_xen_tools, - :system_parameters, - :system_vhd_utils_tools, - :bosh_clean, - :bosh_harden, - :bosh_cloudstack_agent_settings, - :bosh_clean_ssh, - :image_create_efi, - :image_install_grub, - :sbom_create, - :bosh_package_list, - :restore_apt_sources, - ] - ) - expect(stage_collection.package_stemcell_stages('qcow2')).to eq( - [ - :prepare_qcow2_image_stemcell, - ] - ) + [ + :system_network, + :system_openstack_modules, + :bosh_cloudstack_ubuntu_vr_metadata, + :system_ubuntu_xen_tools, + :system_parameters, + :system_vhd_utils_tools, + :bosh_clean, + :bosh_harden, + :bosh_cloudstack_agent_settings, + :bosh_clean_ssh, + :image_create_efi, + :image_install_grub, + :sbom_create, + :bosh_package_list, + :restore_apt_sources + ] + ) + expect(stage_collection.package_stemcell_stages("qcow2")).to eq( + [ + :prepare_qcow2_image_stemcell + ] + ) end end - context 'when using vSphere' do - let(:infrastructure) { Infrastructure.for('vsphere') } - let(:operating_system) { OperatingSystem.for('ubuntu') } + context "when using vSphere" do + let(:infrastructure) { Infrastructure.for("vsphere") } + let(:operating_system) { OperatingSystem.for("ubuntu") } - it 'has the correct stages' do + it "has the correct stages" do expect(stage_collection.build_stemcell_image_stages).to eq( - [ - :system_network, - :system_open_vm_tools, - :system_vsphere_cdrom, - :system_parameters, - :bosh_clean, - :bosh_harden, - :bosh_vsphere_agent_settings, - :bosh_clean_ssh, - :image_create_efi, - :image_install_grub, - :sbom_create, - :bosh_package_list, - :restore_apt_sources, - ] - ) - expect(stage_collection.package_stemcell_stages('ovf')).to eq(vmware_package_stemcell_steps) + [ + :system_network, + :system_open_vm_tools, + :system_vsphere_cdrom, + :system_parameters, + :bosh_clean, + :bosh_harden, + :bosh_vsphere_agent_settings, + :bosh_clean_ssh, + :image_create_efi, + :image_install_grub, + :sbom_create, + :bosh_package_list, + :restore_apt_sources + ] + ) + expect(stage_collection.package_stemcell_stages("ovf")).to eq(vmware_package_stemcell_steps) end end - context 'when using Azure' do - let(:infrastructure) { Infrastructure.for('azure') } + context "when using Azure" do + let(:infrastructure) { Infrastructure.for("azure") } let(:azure_build_stemcell_image_stages) { [ @@ -286,25 +286,25 @@ module Bosh::Stemcell :image_install_grub, :sbom_create, :bosh_package_list, - :restore_apt_sources, + :restore_apt_sources ] } let(:azure_package_stemcell_stages) { [ - :prepare_vhd_image_stemcell, + :prepare_vhd_image_stemcell ] } - let(:operating_system) { OperatingSystem.for('ubuntu') } + let(:operating_system) { OperatingSystem.for("ubuntu") } - it 'returns the correct stages' do + it "returns the correct stages" do expect(stage_collection.build_stemcell_image_stages).to eq(azure_build_stemcell_image_stages) - expect(stage_collection.package_stemcell_stages('vhd')).to eq(azure_package_stemcell_stages) + expect(stage_collection.package_stemcell_stages("vhd")).to eq(azure_package_stemcell_stages) end end - context 'when using Warden' do - let(:infrastructure) { Infrastructure.for('warden') } + context "when using Warden" do + let(:infrastructure) { Infrastructure.for("warden") } let(:build_stemcell_image_stages) { [ :system_parameters, @@ -316,19 +316,19 @@ module Bosh::Stemcell :image_install_grub, :sbom_create, :bosh_package_list, - :restore_apt_sources, + :restore_apt_sources ] } let(:package_stemcell_stages) { [ - :prepare_files_image_stemcell, + :prepare_files_image_stemcell ] } - let(:operating_system) { OperatingSystem.for('ubuntu') } + let(:operating_system) { OperatingSystem.for("ubuntu") } - it 'returns the correct stages' do + it "returns the correct stages" do expect(stage_collection.build_stemcell_image_stages).to eq(build_stemcell_image_stages) - expect(stage_collection.package_stemcell_stages('files')).to eq(package_stemcell_stages) + expect(stage_collection.package_stemcell_stages("files")).to eq(package_stemcell_stages) end end end diff --git a/bosh-stemcell/spec/bosh/stemcell/stage_runner_spec.rb b/bosh-stemcell/spec/bosh/stemcell/stage_runner_spec.rb index 27e227cdcd..3967ca3454 100644 --- a/bosh-stemcell/spec/bosh/stemcell/stage_runner_spec.rb +++ b/bosh-stemcell/spec/bosh/stemcell/stage_runner_spec.rb @@ -1,24 +1,25 @@ -require 'spec_helper' -require 'timecop' -require 'bosh/stemcell/stage_runner' +require "spec_helper" +require "bosh/stemcell/stage_runner" +require "timecop" +require "fakefs/spec_helpers" module Bosh::Stemcell describe StageRunner do include FakeFS::SpecHelpers - let(:shell) { instance_double('Bosh::Core::Shell', run: nil) } + let(:shell) { instance_double("Bosh::Core::Shell", run: nil) } let(:stages) { [:stage_0, :stage_1] } - let(:build_path) { '/fake/path/to/build_dir' } - let(:command_env) { 'env FOO=bar' } - let(:settings_file) { '/fake/path/to/settings.bash' } - let(:work_path) { '/fake/path/to/work_dir/work' } + let(:build_path) { "/fake/path/to/build_dir" } + let(:command_env) { "env FOO=bar" } + let(:settings_file) { "/fake/path/to/settings.bash" } + let(:work_path) { "/fake/path/to/work_dir/work" } subject(:stage_runner) do described_class.new(build_path: build_path, - command_env: command_env, - settings_file: settings_file, - work_path: work_path) + command_env: command_env, + settings_file: settings_file, + work_path: work_path) end before do @@ -27,117 +28,117 @@ module Bosh::Stemcell allow(stage_runner).to receive(:puts) end - describe '#initialize' do - it 'requires :build_path' do + describe "#initialize" do + it "requires :build_path" do expect { - StageRunner.new(stages: 'FAKE', command_env: 'FAKE', settings_file: 'FAKE', work_path: 'FAKE') - }.to raise_error('key not found: :build_path') + StageRunner.new(stages: "FAKE", command_env: "FAKE", settings_file: "FAKE", work_path: "FAKE") + }.to raise_error("key not found: :build_path") end - it 'requires :command_env' do + it "requires :command_env" do expect { - StageRunner.new(stages: 'FAKE', build_path: 'FAKE', settings_file: 'FAKE', work_path: 'FAKE') - }.to raise_error('key not found: :command_env') + StageRunner.new(stages: "FAKE", build_path: "FAKE", settings_file: "FAKE", work_path: "FAKE") + }.to raise_error("key not found: :command_env") end - it 'requires :settings_file' do + it "requires :settings_file" do expect { - StageRunner.new(stages: 'FAKE', build_path: 'FAKE', command_env: 'FAKE', work_path: 'FAKE') - }.to raise_error('key not found: :settings_file') + StageRunner.new(stages: "FAKE", build_path: "FAKE", command_env: "FAKE", work_path: "FAKE") + }.to raise_error("key not found: :settings_file") end - it 'requires :work_path' do + it "requires :work_path" do expect { - StageRunner.new(stages: 'FAKE', build_path: 'FAKE', command_env: 'FAKE', settings_file: 'FAKE') - }.to raise_error('key not found: :work_path') + StageRunner.new(stages: "FAKE", build_path: "FAKE", command_env: "FAKE", settings_file: "FAKE") + }.to raise_error("key not found: :work_path") end end - describe '#configure' do + describe "#configure" do before do stages.each do |stage| - stage_dir = File.join(File.join(build_path, 'stages'), stage.to_s) + stage_dir = File.join(File.join(build_path, "stages"), stage.to_s) FileUtils.mkdir_p(stage_dir) - config_script = File.join(stage_dir, 'config.sh') + config_script = File.join(stage_dir, "config.sh") FileUtils.touch(config_script) - File.chmod(0700, config_script) + File.chmod(0o700, config_script) end allow(File).to receive(:executable?).and_return(true) # because FakeFs does not support :executable? end - it 'runs the configure script for each stage in order' do - expect(shell).to receive(:run). - with('sudo env FOO=bar /fake/path/to/build_dir/stages/stage_0/config.sh /fake/path/to/settings.bash 2>&1', - { output_command: true }) - expect(shell).to receive(:run). - with('sudo env FOO=bar /fake/path/to/build_dir/stages/stage_1/config.sh /fake/path/to/settings.bash 2>&1', - { output_command: true }) + it "runs the configure script for each stage in order" do + expect(shell).to receive(:run) + .with("sudo env FOO=bar /fake/path/to/build_dir/stages/stage_0/config.sh /fake/path/to/settings.bash 2>&1", + {output_command: true}) + expect(shell).to receive(:run) + .with("sudo env FOO=bar /fake/path/to/build_dir/stages/stage_1/config.sh /fake/path/to/settings.bash 2>&1", + {output_command: true}) stage_runner.configure(stages) end - context 'when a stage does not have a config.sh file' do + context "when a stage does not have a config.sh file" do before do - FileUtils.rm('/fake/path/to/build_dir/stages/stage_0/config.sh') + FileUtils.rm("/fake/path/to/build_dir/stages/stage_0/config.sh") end - it 'does not attempt to run the configure step which is missing a config.sh' do - expect(shell).not_to receive(:run). - with('sudo env FOO=bar /fake/path/to/build_dir/stages/stage_0/config.sh /fake/path/to/settings.bash 2>&1', - { output_command: true }) - expect(shell).to receive(:run). - with('sudo env FOO=bar /fake/path/to/build_dir/stages/stage_1/config.sh /fake/path/to/settings.bash 2>&1', - { output_command: true }) + it "does not attempt to run the configure step which is missing a config.sh" do + expect(shell).not_to receive(:run) + .with("sudo env FOO=bar /fake/path/to/build_dir/stages/stage_0/config.sh /fake/path/to/settings.bash 2>&1", + {output_command: true}) + expect(shell).to receive(:run) + .with("sudo env FOO=bar /fake/path/to/build_dir/stages/stage_1/config.sh /fake/path/to/settings.bash 2>&1", + {output_command: true}) stage_runner.configure(stages) end end - context 'when a stage has config.sh file which is not executable' do + context "when a stage has config.sh file which is not executable" do before do - allow(File).to receive(:executable?). - with('/fake/path/to/build_dir/stages/stage_1/config.sh').and_return(false) + allow(File).to receive(:executable?) + .with("/fake/path/to/build_dir/stages/stage_1/config.sh").and_return(false) end - it 'does not attempt to run the configure step which has a non-executable config.sh' do - expect(shell).to receive(:run). - with('sudo env FOO=bar /fake/path/to/build_dir/stages/stage_0/config.sh /fake/path/to/settings.bash 2>&1', - { output_command: true }) - expect(shell).not_to receive(:run). - with('sudo env FOO=bar /fake/path/to/build_dir/stages/stage_1/config.sh /fake/path/to/settings.bash 2>&1', - { output_command: true }) + it "does not attempt to run the configure step which has a non-executable config.sh" do + expect(shell).to receive(:run) + .with("sudo env FOO=bar /fake/path/to/build_dir/stages/stage_0/config.sh /fake/path/to/settings.bash 2>&1", + {output_command: true}) + expect(shell).not_to receive(:run) + .with("sudo env FOO=bar /fake/path/to/build_dir/stages/stage_1/config.sh /fake/path/to/settings.bash 2>&1", + {output_command: true}) stage_runner.configure(stages) end end end - describe '#apply' do - it 'runs the apply script for each stage in order' do + describe "#apply" do + it "runs the apply script for each stage in order" do expect(FileUtils).to receive(:mkdir_p).with(work_path).exactly(2).times - expect(shell).to receive(:run). - with('sudo env FOO=bar /fake/path/to/build_dir/stages/stage_0/apply.sh /fake/path/to/work_dir/work 2>&1', - { output_command: true }) - expect(shell).to receive(:run). - with('sudo env FOO=bar /fake/path/to/build_dir/stages/stage_1/apply.sh /fake/path/to/work_dir/work 2>&1', - { output_command: true }) + expect(shell).to receive(:run) + .with("sudo env FOO=bar /fake/path/to/build_dir/stages/stage_0/apply.sh /fake/path/to/work_dir/work 2>&1", + {output_command: true}) + expect(shell).to receive(:run) + .with("sudo env FOO=bar /fake/path/to/build_dir/stages/stage_1/apply.sh /fake/path/to/work_dir/work 2>&1", + {output_command: true}) stage_runner.apply(stages) end end - describe '#configure_and_apply' do + describe "#configure_and_apply" do before do stages.each do |stage| - stage_dir = File.join(File.join(build_path, 'stages'), stage.to_s) + stage_dir = File.join(File.join(build_path, "stages"), stage.to_s) FileUtils.mkdir_p(stage_dir) - config_script = File.join(stage_dir, 'config.sh') + config_script = File.join(stage_dir, "config.sh") FileUtils.touch(config_script) - File.chmod(0700, config_script) + File.chmod(0o700, config_script) end allow(File).to receive(:executable?).and_return(true) # because FakeFs does not support :executable? @@ -146,32 +147,32 @@ module Bosh::Stemcell allow(Process).to receive(:euid).and_return(1000) end - context 'when resume_from is set' do - it 'skips stages before resume_from ' do + context "when resume_from is set" do + it "skips stages before resume_from " do expect(FileUtils).to receive(:mkdir_p).with(work_path).exactly(1).times - expect(shell).to_not receive(:run). - with('sudo env FOO=bar /fake/path/to/build_dir/stages/stage_0/config.sh /fake/path/to/settings.bash 2>&1', - { output_command: true }) - expect(shell).to receive(:run). - with('sudo env FOO=bar /fake/path/to/build_dir/stages/stage_1/config.sh /fake/path/to/settings.bash 2>&1', - { output_command: true }) - - expect(shell).to_not receive(:run). - with('sudo env FOO=bar /fake/path/to/build_dir/stages/stage_0/apply.sh /fake/path/to/work_dir/work 2>&1', - { output_command: true }) - expect(shell).to receive(:run). - with('sudo env FOO=bar /fake/path/to/build_dir/stages/stage_1/apply.sh /fake/path/to/work_dir/work 2>&1', - { output_command: true }) - - stage_runner.configure_and_apply(stages, 'stage_1') + expect(shell).to_not receive(:run) + .with("sudo env FOO=bar /fake/path/to/build_dir/stages/stage_0/config.sh /fake/path/to/settings.bash 2>&1", + {output_command: true}) + expect(shell).to receive(:run) + .with("sudo env FOO=bar /fake/path/to/build_dir/stages/stage_1/config.sh /fake/path/to/settings.bash 2>&1", + {output_command: true}) + + expect(shell).to_not receive(:run) + .with("sudo env FOO=bar /fake/path/to/build_dir/stages/stage_0/apply.sh /fake/path/to/work_dir/work 2>&1", + {output_command: true}) + expect(shell).to receive(:run) + .with("sudo env FOO=bar /fake/path/to/build_dir/stages/stage_1/apply.sh /fake/path/to/work_dir/work 2>&1", + {output_command: true}) + + stage_runner.configure_and_apply(stages, "stage_1") end end - context 'when resume_from is set to an unknown stage name' do - it 'raises an error' do + context "when resume_from is set to an unknown stage name" do + it "raises an error" do expect { - stage_runner.configure_and_apply(stages, 'this_stage_totally_doesnt_exist') + stage_runner.configure_and_apply(stages, "this_stage_totally_doesnt_exist") }.to raise_error("Can't find stage 'this_stage_totally_doesnt_exist' to resume from. Aborting.") end end diff --git a/bosh-stemcell/spec/bosh/stemcell/stemcell_builder_spec.rb b/bosh-stemcell/spec/bosh/stemcell/stemcell_builder_spec.rb index ff8216b635..013ea462e4 100644 --- a/bosh-stemcell/spec/bosh/stemcell/stemcell_builder_spec.rb +++ b/bosh-stemcell/spec/bosh/stemcell/stemcell_builder_spec.rb @@ -1,10 +1,10 @@ -require 'spec_helper' -require 'bosh/stemcell/stemcell_builder' -require 'bosh/stemcell/build_environment' -require 'bosh/stemcell/stage_collection' -require 'bosh/stemcell/stage_runner' -require 'bosh/stemcell/stemcell_packager' -require 'yaml' +require "spec_helper" +require "bosh/stemcell/stemcell_builder" +require "bosh/stemcell/build_environment" +require "bosh/stemcell/stage_collection" +require "bosh/stemcell/stage_runner" +require "bosh/stemcell/stemcell_packager" +require "yaml" describe Bosh::Stemcell::StemcellBuilder do subject(:builder) do @@ -16,30 +16,30 @@ ) end - let(:packager) { instance_double('Bosh::Stemcell::StemcellPackager') } + let(:packager) { instance_double("Bosh::Stemcell::StemcellPackager") } let(:env) { {} } let(:infrastructure) do Bosh::Stemcell::Infrastructure::Base.new( - name: 'fake_infra', - hypervisor: 'fake_hypervisor', + name: "fake_infra", + hypervisor: "fake_hypervisor", default_disk_size: -1, - disk_formats: ['qcow2', 'raw'], - stemcell_formats: ['stemcell-format-a', 'stemcell-format-b'], + disk_formats: ["qcow2", "raw"], + stemcell_formats: ["stemcell-format-a", "stemcell-format-b"] ) end - let(:operating_system) { Bosh::Stemcell::OperatingSystem.for('ubuntu') } + let(:operating_system) { Bosh::Stemcell::OperatingSystem.for("ubuntu") } let(:definition) do Bosh::Stemcell::Definition.new( infrastructure, - 'fake_hypervisor', + "fake_hypervisor", operating_system ) end let(:version) { 1234 } - let(:os_image_tarball_path) { '/path/to/os-img.tgz' } - let(:gem_components) { double('Bosh::Dev::GemComponents', build_release_gems: nil) } + let(:os_image_tarball_path) { "/path/to/os-img.tgz" } + let(:gem_components) { double("Bosh::Dev::GemComponents", build_release_gems: nil) } let(:environment) do Bosh::Stemcell::BuildEnvironment.new( env, @@ -51,14 +51,14 @@ let(:collection) do instance_double( - 'Bosh::Stemcell::StageCollection', + "Bosh::Stemcell::StageCollection", extract_operating_system_stages: [:extract_stage], build_stemcell_image_stages: [:build_stage], package_stemcell_stages: [:package_stage], - agent_stages: [:agent_stage], + agent_stages: [:agent_stage] ) end - let(:runner) { instance_double('Bosh::Stemcell::StageRunner', configure_and_apply: nil) } + let(:runner) { instance_double("Bosh::Stemcell::StageRunner", configure_and_apply: nil) } let(:tmp_dir) { Dir.mktmpdir } before do allow(environment).to receive(:prepare_build) @@ -66,16 +66,16 @@ end after { FileUtils.rm_rf(tmp_dir) } - describe '#build' do + describe "#build" do before { allow(packager).to receive(:package) } before { allow(collection).to receive(:kernel_stages).and_return([]) } - it 'prepares the build environment' do + it "prepares the build environment" do expect(environment).to receive(:prepare_build) builder.build end - it 'runs the extract OS, agent, and infrastructure stages' do + it "runs the extract OS, agent, and infrastructure stages" do expect(runner).to receive(:configure_and_apply).with([:extract_stage, :agent_stage, :build_stage], nil) builder.build diff --git a/bosh-stemcell/spec/bosh/stemcell/stemcell_packager_spec.rb b/bosh-stemcell/spec/bosh/stemcell/stemcell_packager_spec.rb index a228ccda15..9476dcedf6 100644 --- a/bosh-stemcell/spec/bosh/stemcell/stemcell_packager_spec.rb +++ b/bosh-stemcell/spec/bosh/stemcell/stemcell_packager_spec.rb @@ -1,168 +1,169 @@ -require 'spec_helper' -require 'bosh/stemcell/stemcell_packager' -require 'bosh/stemcell/stage_collection' -require 'bosh/stemcell/stage_runner' -require 'bosh/stemcell/definition' -require 'bosh/stemcell/archive_filename' -require 'yaml' +require "spec_helper" +require "bosh/stemcell/stemcell_packager" +require "bosh/stemcell/stage_collection" +require "bosh/stemcell/stage_runner" +require "bosh/stemcell/definition" +require "bosh/stemcell/archive_filename" +require "yaml" + +class FakeInfrastructure < Bosh::Stemcell::Infrastructure::Base + def additional_cloud_properties + {"fake_infra_specific_property" => "some_value"} + end +end describe Bosh::Stemcell::StemcellPackager do subject(:packager) do Bosh::Stemcell::StemcellPackager.new( - definition: definition, - version: version, - work_path: work_dir, - tarball_path: tarball_dir, - disk_size: disk_size, - runner: runner, - collection: collection, + definition: definition, + version: version, + work_path: work_dir, + tarball_path: tarball_dir, + disk_size: disk_size, + runner: runner, + collection: collection ) end - class FakeInfrastructure < Bosh::Stemcell::Infrastructure::Base - def additional_cloud_properties - { 'fake_infra_specific_property' => 'some_value'} - end - end - - let(:runner) { instance_double('Bosh::Stemcell::StageRunner') } + let(:runner) { instance_double("Bosh::Stemcell::StageRunner") } let(:collection) { Bosh::Stemcell::StageCollection.new(definition) } let(:env) { {} } let(:infrastructure) do FakeInfrastructure.new( - name: 'fake_infra', - hypervisor: 'fake_hypervisor', + name: "fake_infra", + hypervisor: "fake_hypervisor", default_disk_size: -1, - disk_formats: ['qcow2', 'raw'], - stemcell_formats: ['stemcell-format-a', 'stemcell-format-b'] + disk_formats: ["qcow2", "raw"], + stemcell_formats: ["stemcell-format-a", "stemcell-format-b"] ) end - let(:operating_system) { Bosh::Stemcell::OperatingSystem.for('ubuntu', 'noble') } + let(:operating_system) { Bosh::Stemcell::OperatingSystem.for("ubuntu", "noble") } let(:definition) do Bosh::Stemcell::Definition.new( infrastructure, - 'fake_hypervisor', + "fake_hypervisor", operating_system ) end let(:version) { 1234 } - let(:release_tarball_path) { '/path/to/release.tgz' } - let(:os_image_tarball_path) { '/path/to/os-img.tgz' } - let(:gem_components) { double('Bosh::Dev::GemComponents', build_release_gems: nil) } + let(:release_tarball_path) { "/path/to/release.tgz" } + let(:os_image_tarball_path) { "/path/to/os-img.tgz" } + let(:gem_components) { double("Bosh::Dev::GemComponents", build_release_gems: nil) } let(:collection) do instance_double( - 'Bosh::Stemcell::StageCollection', + "Bosh::Stemcell::StageCollection", extract_operating_system_stages: [:extract_stage], build_stemcell_image_stages: [:build_stage], package_stemcell_stages: [:package_stage], - agent_stages: [:agent_stage], + agent_stages: [:agent_stage] ) end let(:tmp_dir) { Dir.mktmpdir } - let(:work_dir) { File.join(tmp_dir, 'stemcell-work').tap {|f| FileUtils.mkdir_p(f)} } - let(:tarball_dir) { File.join(tmp_dir, 'tarballs').tap {|f| FileUtils.mkdir_p(f)} } + let(:work_dir) { File.join(tmp_dir, "stemcell-work").tap { |f| FileUtils.mkdir_p(f) } } + let(:tarball_dir) { File.join(tmp_dir, "tarballs").tap { |f| FileUtils.mkdir_p(f) } } let(:disk_size) { 4096 } before do - FileUtils.mkdir_p(File.join(work_dir, 'stemcell')) + FileUtils.mkdir_p(File.join(work_dir, "stemcell")) allow(runner).to receive(:configure_and_apply) do - image_file = File.join(work_dir, 'stemcell/image') - raise 'this step fails if the image already exists!' if File.exist?(image_file) + image_file = File.join(work_dir, "stemcell/image") + raise "this step fails if the image already exists!" if File.exist?(image_file) File.write(image_file, "i'm an image!") end - packages = File.join(work_dir, 'stemcell/packages.txt') - File.write(packages, 'i am stemcell dpkg_l') - dev_tools_file_list = File.join(work_dir, 'stemcell/dev_tools_file_list.txt') - File.write(dev_tools_file_list, 'i am dev_tools_file_list') - spdx_sbom = File.join(work_dir, 'stemcell/sbom.spdx.json') - File.write(spdx_sbom, 'i am spdx sbom') - cyclonedx_sbom = File.join(work_dir, 'stemcell/sbom.cdx.json') - File.write(cyclonedx_sbom, 'i am cyclonedx sbom') + packages = File.join(work_dir, "stemcell/packages.txt") + File.write(packages, "i am stemcell dpkg_l") + dev_tools_file_list = File.join(work_dir, "stemcell/dev_tools_file_list.txt") + File.write(dev_tools_file_list, "i am dev_tools_file_list") + spdx_sbom = File.join(work_dir, "stemcell/sbom.spdx.json") + File.write(spdx_sbom, "i am spdx sbom") + cyclonedx_sbom = File.join(work_dir, "stemcell/sbom.cdx.json") + File.write(cyclonedx_sbom, "i am cyclonedx sbom") end after { FileUtils.rm_rf(tmp_dir) } - describe '#package' do - let(:disk_format) { 'qcow2' } + describe "#package" do + let(:disk_format) { "qcow2" } - it 'invokes packaging stages appropriate for the disk format' do - allow(collection).to receive(:package_stemcell_stages).with('qcow2').and_return([:package_qcow2]) + it "invokes packaging stages appropriate for the disk format" do + allow(collection).to receive(:package_stemcell_stages).with("qcow2").and_return([:package_qcow2]) expect(runner).to receive(:configure_and_apply).with([:package_qcow2]) packager.package(disk_format) end - it 'writes a stemcell.MF containing metadata' do - packager.package('raw') + it "writes a stemcell.MF containing metadata" do + packager.package("raw") - actual_manifest = YAML.load_file(File.join(work_dir, 'stemcell/stemcell.MF')) + actual_manifest = YAML.load_file(File.join(work_dir, "stemcell/stemcell.MF")) - architecture = 'x86_64' + architecture = "x86_64" expect(actual_manifest).to eq({ - 'name' => 'bosh-fake_infra-fake_hypervisor-ubuntu-noble-raw', - 'version' => '1234', - 'bosh_protocol' => 1, - 'api_version' => 3, - 'sha1' => 'c1ebdefc3f8282a9d7d47803fb5030b61ffc793d', # SHA-1 of image above - 'operating_system' => 'ubuntu-noble', - 'stemcell_formats' => ['stemcell-format-a', 'stemcell-format-b'], - 'cloud_properties' => { - 'name' => 'bosh-fake_infra-fake_hypervisor-ubuntu-noble-raw', - 'version' => '1234', - 'infrastructure' => 'fake_infra', - 'hypervisor' => 'fake_hypervisor', - 'disk' => 4096, - 'disk_format' => 'raw', - 'container_format' => 'bare', - 'os_type' => 'linux', - 'os_distro' => 'ubuntu', - 'architecture' => architecture, - 'fake_infra_specific_property' => 'some_value' + "name" => "bosh-fake_infra-fake_hypervisor-ubuntu-noble-raw", + "version" => "1234", + "bosh_protocol" => 1, + "api_version" => 3, + "sha1" => "c1ebdefc3f8282a9d7d47803fb5030b61ffc793d", # SHA-1 of image above + "operating_system" => "ubuntu-noble", + "stemcell_formats" => ["stemcell-format-a", "stemcell-format-b"], + "cloud_properties" => { + "name" => "bosh-fake_infra-fake_hypervisor-ubuntu-noble-raw", + "version" => "1234", + "infrastructure" => "fake_infra", + "hypervisor" => "fake_hypervisor", + "disk" => 4096, + "disk_format" => "raw", + "container_format" => "bare", + "os_type" => "linux", + "os_distro" => "ubuntu", + "architecture" => architecture, + "fake_infra_specific_property" => "some_value" } }) end - it 'returns the path of the created tarball' do + it "returns the path of the created tarball" do expect(packager.package(disk_format)).to eq( - File.join(tarball_dir, "bosh-stemcell-1234-fake_infra-fake_hypervisor-ubuntu-noble.tgz")) + File.join(tarball_dir, "bosh-stemcell-1234-fake_infra-fake_hypervisor-ubuntu-noble.tgz") + ) end - context 'if an image already exist in the stemcell dir' do + context "if an image already exist in the stemcell dir" do before do - FileUtils.mkdir_p(File.join(work_dir, 'stemcell')) - File.write(File.join(work_dir, 'stemcell/image'), 'bad image!') + FileUtils.mkdir_p(File.join(work_dir, "stemcell")) + File.write(File.join(work_dir, "stemcell/image"), "bad image!") end - it 'deletes it first so that applying the package_stemcell_stages doesnt blow up' do + it "deletes it first so that applying the package_stemcell_stages doesnt blow up" do expect { packager.package(disk_format) }.not_to raise_error end end - it 'archives the working dir' do + it "archives the working dir" do packager.package(disk_format) tarball_path = File.join(tarball_dir, "bosh-stemcell-1234-fake_infra-fake_hypervisor-ubuntu-noble.tgz") expect(File.exist?(tarball_path)).to eq(true) - stemcell_contents_path = File.join(tmp_dir, 'stemcell-contents') + stemcell_contents_path = File.join(tmp_dir, "stemcell-contents") FileUtils.mkdir_p(stemcell_contents_path) Dir.chdir(stemcell_contents_path) do Open3.capture3("tar xfz #{tarball_path}") end - extracted_image_path = File.join(stemcell_contents_path, 'image') + extracted_image_path = File.join(stemcell_contents_path, "image") expect(File.exist?(extracted_image_path)).to eq(true) expect(File.read(extracted_image_path)).to eq("i'm an image!") - actual_manifest = File.read(File.join(work_dir, 'stemcell/stemcell.MF')) - extracted_stemcell_mf = File.join(stemcell_contents_path, 'stemcell.MF') + actual_manifest = File.read(File.join(work_dir, "stemcell/stemcell.MF")) + extracted_stemcell_mf = File.join(stemcell_contents_path, "stemcell.MF") expect(File.exist?(extracted_stemcell_mf)).to eq(true) expect(File.read(extracted_stemcell_mf)).to eq(actual_manifest) end - it 'stemcell tarball contains files in proper order' do + it "stemcell tarball contains files in proper order" do packager.package(disk_format) tarball_path = File.join(tarball_dir, "bosh-stemcell-1234-fake_infra-fake_hypervisor-ubuntu-noble.tgz") @@ -177,26 +178,26 @@ def additional_cloud_properties sbom.spdx.json sbom.cdx.json ' - ) +) end - it 'fails if necessary files are not found in the stemcell working directory' do + it "fails if necessary files are not found in the stemcell working directory" do _, _, status = Open3.capture3("rm -f #{work_dir}/stemcell/dev_tools_file_list.txt #{work_dir}/stemcell/packages.txt") expect(status.success?).to be(true) - expect{ packager.package(disk_format) }.to raise_error(/Files are missing from stemcell directory: packages.txt dev_tools_file_list.txt/) + expect { packager.package(disk_format) }.to raise_error(/Files are missing from stemcell directory: packages.txt dev_tools_file_list.txt/) end - it 'fails if additional files are found in the stemcell working director' do - File.open("#{work_dir}/stemcell/my-extra-file", 'w') {} + it "fails if additional files are found in the stemcell working director" do + File.open("#{work_dir}/stemcell/my-extra-file", "w") {} - expect{ packager.package(disk_format) }.to raise_error(/Extra files found in stemcell directory: my-extra-file/) + expect { packager.package(disk_format) }.to raise_error(/Extra files found in stemcell directory: my-extra-file/) end - context 'when disk format is not the default for the infrastructure' do - let(:disk_format) { 'raw' } + context "when disk format is not the default for the infrastructure" do + let(:disk_format) { "raw" } - it 'archives the working dir with a different tarball name' do + it "archives the working dir with a different tarball name" do packager.package(disk_format) tarball_path = File.join(tarball_dir, "bosh-stemcell-1234-fake_infra-fake_hypervisor-ubuntu-noble-raw.tgz") @@ -204,22 +205,22 @@ def additional_cloud_properties end end - context 'when packaging a non standard os variant' do - let(:operating_system) { Bosh::Stemcell::OperatingSystem.for('ubuntu', 'FOO-fips') } + context "when packaging a non standard os variant" do + let(:operating_system) { Bosh::Stemcell::OperatingSystem.for("ubuntu", "FOO-fips") } - it 'archives the working dir with a different tarball name' do + it "archives the working dir with a different tarball name" do packager.package(disk_format) tarball_path = File.join(tarball_dir, "bosh-stemcell-1234-fake_infra-fake_hypervisor-ubuntu-FOO-fips.tgz") expect(File.exist?(tarball_path)).to eq(true) end - it 'writes the variant into the stemcell.MF' do - packager.package('raw') + it "writes the variant into the stemcell.MF" do + packager.package("raw") - actual_manifest = YAML.load_file(File.join(work_dir, 'stemcell/stemcell.MF')) + actual_manifest = YAML.load_file(File.join(work_dir, "stemcell/stemcell.MF")) - expect(actual_manifest['name']).to eq('bosh-fake_infra-fake_hypervisor-ubuntu-FOO-fips-raw') - expect(actual_manifest['operating_system']).to eq('ubuntu-FOO') + expect(actual_manifest["name"]).to eq("bosh-fake_infra-fake_hypervisor-ubuntu-FOO-fips-raw") + expect(actual_manifest["operating_system"]).to eq("ubuntu-FOO") end end end diff --git a/bosh-stemcell/spec/bosh/stemcell_spec.rb b/bosh-stemcell/spec/bosh/stemcell_spec.rb index b442d8f463..0128d26ea4 100644 --- a/bosh-stemcell/spec/bosh/stemcell_spec.rb +++ b/bosh-stemcell/spec/bosh/stemcell_spec.rb @@ -1,5 +1,5 @@ -require 'spec_helper' -require 'bosh/stemcell' +require "spec_helper" +require "bosh/stemcell" describe Bosh::Stemcell do it { should be_a(Module) } diff --git a/bosh-stemcell/spec/os_image/ubuntu_spec.rb b/bosh-stemcell/spec/os_image/ubuntu_spec.rb index aa63cb51ff..29c07fff84 100644 --- a/bosh-stemcell/spec/os_image/ubuntu_spec.rb +++ b/bosh-stemcell/spec/os_image/ubuntu_spec.rb @@ -1,53 +1,53 @@ -require 'bosh/stemcell/arch' -require 'spec_helper' -require 'shellout_types/file' +require "bosh/stemcell/arch" +require "spec_helper" +require "shellout_types/file" -describe 'Ubuntu 24.04 OS image', os_image: true do - it_behaves_like 'every OS image' do - let (:syslog_config) { file('/etc/audit/plugins.d/syslog.conf') } +describe "Ubuntu 24.04 OS image", os_image: true do + it_behaves_like "every OS image" do + let(:syslog_config) { file("/etc/audit/plugins.d/syslog.conf") } end - it_behaves_like 'an os with chrony' - it_behaves_like 'a systemd-based OS image' - it_behaves_like 'an Ubuntu-based OS image' + it_behaves_like "an os with chrony" + it_behaves_like "a systemd-based OS image" + it_behaves_like "an Ubuntu-based OS image" - describe package('rpm') do + describe package("rpm") do it { should_not be_installed } end - context 'The system must limit the ability of processes to have simultaneous write and execute access to memory. (stig: V-38597)' do + context "The system must limit the ability of processes to have simultaneous write and execute access to memory. (stig: V-38597)" do # Ubuntu relies on the system's hardware NX capabilities, or emulates NX if the hardware does not support it. # Ubuntu has had this capability since v 11.04 # https://wiki.ubuntu.com/Security/Features#nx - describe command('lsb_release -r') do - it 'should run an os that emulates or uses things' do + describe command("lsb_release -r") do + it "should run an os that emulates or uses things" do major_version = subject.stdout.match(/Release:\s+(\d+)(\.\d+)?/)[1].to_i expect(major_version).to be > 11 end end end - describe service('systemd-networkd') do + describe service("systemd-networkd") do it { should be_enabled } end - describe 'base_apt' do - describe file('/etc/apt/sources.list') do + describe "base_apt" do + describe file("/etc/apt/sources.list") do its(:content) { should match 'deb http:\/\/(archive|snapshot).ubuntu.com\/ubuntu(|\/\d*T\d*Z) noble main universe multiverse' } its(:content) { should match 'deb http:\/\/(archive|snapshot).ubuntu.com\/ubuntu(|\/\d*T\d*Z) noble-updates main universe multiverse' } its(:content) { should match 'deb http:\/\/(security|snapshot).ubuntu.com\/ubuntu(|\/\d*T\d*Z) noble-security main universe multiverse' } end - describe file('/lib/systemd/system/monit.service') do + describe file("/lib/systemd/system/monit.service") do it { should be_file } - its(:content) { should match 'Restart=always' } - its(:content) { should match 'KillMode=process' } + its(:content) { should match "Restart=always" } + its(:content) { should match "KillMode=process" } end end - context 'installed by base_ubuntu_packages' do - context 'zfs' do + context "installed by base_ubuntu_packages" do + context "zfs" do %w[ - /lib/modules/*/kernel/zfs/ + /lib/modules/*/kernel/zfs/ /usr/src/linux-headers-*/zfs ].each do |folder| describe file(folder) do @@ -57,21 +57,21 @@ end end - context 'installed by base_ssh' do - subject(:sshd_config) { file('/etc/ssh/sshd_config') } + context "installed by base_ssh" do + subject(:sshd_config) { file("/etc/ssh/sshd_config") } - it 'only allow 3DES and AES series ciphers (stig: V-38617)' do + it "only allow 3DES and AES series ciphers (stig: V-38617)" do ciphers = %w[ aes256-gcm@openssh.com aes128-gcm@openssh.com aes256-ctr aes192-ctr aes128-ctr - ].join(',') + ].join(",") expect(sshd_config.content).to match(/^Ciphers #{ciphers}$/) end - it 'allows only secure HMACs', exclude_on_fips: true do + it "allows only secure HMACs", exclude_on_fips: true do macs = %w[ hmac-sha2-512-etm@openssh.com hmac-sha2-256-etm@openssh.com @@ -79,12 +79,12 @@ hmac-sha2-512 hmac-sha2-256 umac-128@openssh.com - ].join(',') + ].join(",") expect(sshd_config.content).to match(/^MACs #{macs}$/) end end - context 'installed by system_grub' do + context "installed by system_grub" do %w[ grub2 ].each do |pkg| @@ -99,453 +99,452 @@ end end - context 'installed by bosh_user' do - describe file('/etc/passwd') do + context "installed by bosh_user" do + describe file("/etc/passwd") do it { should be_file } - its(:content) { should match '/home/vcap:/bin/bash' } + its(:content) { should match "/home/vcap:/bin/bash" } end end - context 'symlinked by vim_tiny' do - describe file('/usr/bin/vim') do - it { should be_linked_to '/usr/bin/vim.tiny' } + context "symlinked by vim_tiny" do + describe file("/usr/bin/vim") do + it { should be_linked_to "/usr/bin/vim.tiny" } end end - context 'configured by cron_config' do - describe file '/etc/cron.daily/man-db' do + context "configured by cron_config" do + describe file "/etc/cron.daily/man-db" do it { should_not be_file } end - describe file '/etc/cron.weekly/man-db' do + describe file "/etc/cron.weekly/man-db" do it { should_not be_file } end - describe file '/etc/apt/apt.conf.d/02periodic' do + describe file "/etc/apt/apt.conf.d/02periodic" do its(:content) { should match <<~EOF } APT::Periodic { Enable "0"; } -EOF + EOF end end - context 'created image should not contain machine id' do - describe file('/etc/machine-id') do - it { should be_file} - its(:content) { should match '' } + context "created image should not contain machine id" do + describe file("/etc/machine-id") do + it { should be_file } + its(:content) { should match "" } end - describe file('/var/lib/dbus/machine-id') do + describe file("/var/lib/dbus/machine-id") do it { should_not be_file } end end - context 'overriding control alt delete (stig: V-38668)' do - describe file('/etc/init/control-alt-delete.override') do + context "overriding control alt delete (stig: V-38668)" do + describe file("/etc/init/control-alt-delete.override") do it { should be_file } its(:content) { should match 'exec /usr/bin/logger -p security.info "Control-Alt-Delete pressed"' } end end - context 'package signature verification (stig: V-38462) (stig: V-38483)' do + context "package signature verification (stig: V-38462) (stig: V-38483)" do # verify default behavior was not changed - describe command('grep -R AllowUnauthenticated /etc/apt/apt.conf.d/') do - its (:stdout) { should eq('') } + describe command("grep -R AllowUnauthenticated /etc/apt/apt.conf.d/") do + its(:stdout) { should eq("") } end end - context 'official Ubuntu gpg key is installed (stig: V-38476)' do - describe command('apt-key list') do - its (:stdout) { should include('Ubuntu Archive Automatic Signing Key') } + context "official Ubuntu gpg key is installed (stig: V-38476)" do + describe command("apt-key list") do + its(:stdout) { should include("Ubuntu Archive Automatic Signing Key") } end end - context 'PAM configuration' do - describe file('/lib/x86_64-linux-gnu/security/pam_pwquality.so') do + context "PAM configuration" do + describe file("/lib/x86_64-linux-gnu/security/pam_pwquality.so") do it { should be_file } end - describe file('/etc/pam.d/common-password') do - it'must prohibit the reuse of passwords within twenty-four iterations (stig: V-38658)' do - expect(subject.content).to match /password.*pam_unix\.so.*remember=24/ + describe file("/etc/pam.d/common-password") do + it "must prohibit the reuse of passwords within twenty-four iterations (stig: V-38658)" do + expect(subject.content).to match(/password.*pam_unix\.so.*remember=24/) end - it'must prohibit new passwords shorter than 14 characters (stig: V-38475)' do - expect(subject.content).to match /password.*pam_unix\.so.*minlen=14/ + it "must prohibit new passwords shorter than 14 characters (stig: V-38475)" do + expect(subject.content).to match(/password.*pam_unix\.so.*minlen=14/) end - it'must use the pwquality library to set correct password requirements (CIS-9.2.1)' do - expect(subject.content).to match /password.*pam_pwquality\.so.*retry=3.*minlen=14.*dcredit=-1.*ucredit=-1.*ocredit=-1.*lcredit=-1/ + it "must use the pwquality library to set correct password requirements (CIS-9.2.1)" do + expect(subject.content).to match(/password.*pam_pwquality\.so.*retry=3.*minlen=14.*dcredit=-1.*ucredit=-1.*ocredit=-1.*lcredit=-1/) end end - describe file('/etc/pam.d/common-account') do - it 'must reset the tally of a user after successful login, esp. `sudo` (stig: V-38573)' do - expect(subject.content).to match /account.*required.*pam_faillock\.so/ + describe file("/etc/pam.d/common-account") do + it "must reset the tally of a user after successful login, esp. `sudo` (stig: V-38573)" do + expect(subject.content).to match(/account.*required.*pam_faillock\.so/) end end - describe file('/etc/pam.d/common-auth') do - it'must restrict a user account after 3 failed login attempts (stig: V-38573)' do - expect(subject.content).to match /auth.*pam_faillock\.so.*deny=3/ + describe file("/etc/pam.d/common-auth") do + it "must restrict a user account after 3 failed login attempts (stig: V-38573)" do + expect(subject.content).to match(/auth.*pam_faillock\.so.*deny=3/) end end end # V-38498 and V-38495 are the package defaults and cannot be configured - context 'ensure auditd is installed (stig: V-38498) (stig: V-38495)' do - describe package('auditd') do + context "ensure auditd is installed (stig: V-38498) (stig: V-38495)" do + describe package("auditd") do it { should be_installed } end end - context 'ensure auditd file permissions and ownership (stig: V-38663) (stig: V-38664) (stig: V-38665)' do - [[0o644, '/usr/share/lintian/overrides/auditd'], - [0o755, '/usr/bin/auvirt'], - [0o755, '/usr/bin/ausyscall'], - [0o755, '/usr/bin/aulastlog'], - [0o755, '/usr/bin/aulast'], - [0o750, '/var/log/audit'], - [0o755, '/sbin/aureport'], - [0o755, '/sbin/auditd'], - [0o755, '/sbin/autrace'], - [0o755, '/sbin/ausearch'], - [0o755, '/sbin/augenrules'], - [0o755, '/sbin/auditctl'], - [0o750, '/etc/audit/plugins.d'], - [0o640, '/etc/audit/plugins.d/af_unix.conf'], - [0o640, '/etc/audit/plugins.d/syslog.conf'], - [0o755, '/etc/init.d/auditd'], - [0o750, '/etc/audit'], - [0o750, '/etc/audit/rules.d'], - [0o640, '/etc/audit/rules.d/audit.rules'], - [0o640, '/etc/audit/audit.rules'], - [0o640, '/etc/audit/auditd.conf'], - [0o644, '/etc/default/auditd'], - [0o644, '/lib/systemd/system/auditd.service']].each do |tuple| + context "ensure auditd file permissions and ownership (stig: V-38663) (stig: V-38664) (stig: V-38665)" do + [[0o644, "/usr/share/lintian/overrides/auditd"], + [0o755, "/usr/bin/auvirt"], + [0o755, "/usr/bin/ausyscall"], + [0o755, "/usr/bin/aulastlog"], + [0o755, "/usr/bin/aulast"], + [0o750, "/var/log/audit"], + [0o755, "/sbin/aureport"], + [0o755, "/sbin/auditd"], + [0o755, "/sbin/autrace"], + [0o755, "/sbin/ausearch"], + [0o755, "/sbin/augenrules"], + [0o755, "/sbin/auditctl"], + [0o750, "/etc/audit/plugins.d"], + [0o640, "/etc/audit/plugins.d/af_unix.conf"], + [0o640, "/etc/audit/plugins.d/syslog.conf"], + [0o755, "/etc/init.d/auditd"], + [0o750, "/etc/audit"], + [0o750, "/etc/audit/rules.d"], + [0o640, "/etc/audit/rules.d/audit.rules"], + [0o640, "/etc/audit/audit.rules"], + [0o640, "/etc/audit/auditd.conf"], + [0o644, "/etc/default/auditd"], + [0o644, "/lib/systemd/system/auditd.service"]].each do |tuple| describe file(tuple[1]) do - its(:owner) { should eq('root') } - its(:mode) { should eq(tuple[0]) } - its(:group) { should eq('root') } + its(:owner) { should eq("root") } + its(:mode) { should eq(tuple[0]) } + its(:group) { should eq("root") } end end end - context 'auditd is configured to use augenrules' do - describe file('/etc/systemd/system/auditd.service') do + context "auditd is configured to use augenrules" do + describe file("/etc/systemd/system/auditd.service") do it { should be_file } its(:content) { should match(/^ExecStartPost=-\/sbin\/augenrules --load$/) } end end - context 'ensure audit package file have unmodified contents (stig: V-38637)' do + context "ensure audit package file have unmodified contents (stig: V-38637)" do # ignore auditd.conf, auditd, and audit.rules since we modify these files in # other stigs describe command("dpkg -V audit | grep -v 'auditd.conf' | grep -v 'default/auditd' | grep -v 'audit.rules' | grep -v 'syslog.conf' | grep '^..5'") do - its (:stdout) { should be_empty } + its(:stdout) { should be_empty } end end - context 'ensure sendmail is removed (stig: V-38671)' do - describe command('dpkg -s sendmail') do - it 'complains about non-installed sendmail' do - expect(subject.stderr).to include 'dpkg-query: package \'sendmail\' is not installed and no information is available' + context "ensure sendmail is removed (stig: V-38671)" do + describe command("dpkg -s sendmail") do + it "complains about non-installed sendmail" do + expect(subject.stderr).to include "dpkg-query: package 'sendmail' is not installed and no information is available" end end end - describe service('xinetd') do - it('should be disabled (stig: V-38582)') { should_not be_enabled } + describe service("xinetd") do + it("should be disabled (stig: V-38582)") { should_not be_enabled } end - context 'ensure cron is installed and enabled (stig: V-38605)' do - describe package('cron') do - it('should be installed') { should be_installed } + context "ensure cron is installed and enabled (stig: V-38605)" do + describe package("cron") do + it("should be installed") { should be_installed } end - describe service('cron') do - it('should be enabled') { should be_enabled } + describe service("cron") do + it("should be enabled") { should be_enabled } end end - context 'ensure ypbind is not running (stig: V-38604)' do - describe package('nis') do + context "ensure ypbind is not running (stig: V-38604)" do + describe package("nis") do it { should_not be_installed } end - describe file('/var/run/ypbind.pid') do + describe file("/var/run/ypbind.pid") do it { should_not be_file } end end - context 'ensure ypserv is not installed (stig: V-38603)' do - describe package('nis') do + context "ensure ypserv is not installed (stig: V-38603)" do + describe package("nis") do it { should_not be_installed } end end - context 'ensure snmp is not installed (stig: V-38660) (stig: V-38653)' do - describe package('snmp') do + context "ensure snmp is not installed (stig: V-38660) (stig: V-38653)" do + describe package("snmp") do it { should_not be_installed } end end - context 'display the number of unsuccessful logon/access attempts since the last successful logon/access (stig: V-51875)' do - describe file('/etc/pam.d/common-password') do - its(:content) { should match /session\toptional\t\t\tpam_lastlog2\.so showfailed/ } + context "display the number of unsuccessful logon/access attempts since the last successful logon/access (stig: V-51875)" do + describe file("/etc/pam.d/common-password") do + its(:content) { should match(/session\toptional\t\t\tpam_lastlog2\.so showfailed/) } end end - context 'ensure whoopsie and apport are not installed (CIS-4.1)' do - describe package('apport') do + context "ensure whoopsie and apport are not installed (CIS-4.1)" do + describe package("apport") do it { should_not be_installed } end - describe package('whoopsie') do + describe package("whoopsie") do it { should_not be_installed } end end - context 'restrict access to the su command CIS-9.5' do + context "restrict access to the su command CIS-9.5" do describe command('grep "^\s*auth\s*required\s*pam_wheel.so\s*use_uid" /etc/pam.d/su') do - it('exits 0') { expect(subject.exit_status).to eq(0) } + it("exits 0") { expect(subject.exit_status).to eq(0) } end - describe user('vcap') do + describe user("vcap") do it { should exist } - it { should be_in_group 'sudo' } + it { should be_in_group "sudo" } end end - describe 'logging and audit startup script' do - describe file('/var/vcap/bosh/bin/bosh-start-logging-and-auditing') do + describe "logging and audit startup script" do + describe file("/var/vcap/bosh/bin/bosh-start-logging-and-auditing") do it { should be_file } it { should be_executable } - its(:content) { should match('service auditd start') } + its(:content) { should match("service auditd start") } end end - describe 'rsyslog modifications' do - - describe file('/usr/local/bin/wait_for_var_log_to_be_mounted') do + describe "rsyslog modifications" do + describe file("/usr/local/bin/wait_for_var_log_to_be_mounted") do it { should be_file } its(:mode) { should eq(0o755) } end end - describe 'allowed user accounts' do - describe file('/etc/passwd') do - its(:content) { should eql(< 0 end - it 'returns an integer exit code' do - _, _, status = runner.run('cat /garbage') + it "returns an integer exit code" do + _, _, status = runner.run("cat /garbage") expect(status).to eq(1) end - it 'runs the command in the chroot dir' do - stdout, stderr, status = runner.run('pwd') - expect(stderr).to eq('') + it "runs the command in the chroot dir" do + stdout, stderr, status = runner.run("pwd") + expect(stderr).to eq("") expect(status).to eq(0) expect(stdout).to eq("/\n") end diff --git a/bosh-stemcell/spec/shellout_types/command_spec.rb b/bosh-stemcell/spec/shellout_types/command_spec.rb index 0cf7a5e92a..77473a7a81 100644 --- a/bosh-stemcell/spec/shellout_types/command_spec.rb +++ b/bosh-stemcell/spec/shellout_types/command_spec.rb @@ -1,5 +1,5 @@ -require_relative 'spec_helper' -require 'shellout_types/command' +require_relative "spec_helper" +require "shellout_types/command" module ShelloutTypes describe Command, shellout_types: true do @@ -11,25 +11,25 @@ module ShelloutTypes let(:long) { described_class.new("cat /etc/lsb-release", chroot) } let(:exit11) { described_class.new("exit 11", chroot) } - describe '#stdout' do - it 'returns stdout of running the command in the chroot dir' do + describe "#stdout" do + it "returns stdout of running the command in the chroot dir" do expect(echo.stdout).to eq("/\n") end end - describe '#exit_status' do - it 'returns the exit status of the command' do + describe "#exit_status" do + it "returns the exit status of the command" do expect(echo.exit_status).to eq(0) end - it 'returns the exit status even if the command fails' do + it "returns the exit status even if the command fails" do expect(exit11.exit_status).to eq(11) end end - describe '#stderr' do - it 'returns stderr of running the command in the chroot dir' do - expect(errorful.stderr).to match /potato: command not found/ + describe "#stderr" do + it "returns stderr of running the command in the chroot dir" do + expect(errorful.stderr).to match(/potato: command not found/) end end end diff --git a/bosh-stemcell/spec/shellout_types/file_spec.rb b/bosh-stemcell/spec/shellout_types/file_spec.rb index 88fe92a469..5d01f669fd 100644 --- a/bosh-stemcell/spec/shellout_types/file_spec.rb +++ b/bosh-stemcell/spec/shellout_types/file_spec.rb @@ -1,35 +1,35 @@ -require_relative 'spec_helper' -require 'tempfile' -require 'shellout_types/file' +require_relative "spec_helper" +require "tempfile" +require "shellout_types/file" module ShelloutTypes describe File, shellout_types: true do def chown(uid, gid, file_name) cmd = ["-c"] - chown_cmd = 'chown ' - chown_cmd += "#{uid}" unless uid.nil? + chown_cmd = "chown " + chown_cmd += uid.to_s unless uid.nil? chown_cmd += ":#{gid}" unless gid.nil? chown_cmd += " #{file_name}" - cmd.push("#{chown_cmd}") + cmd.push(chown_cmd.to_s) - _, stderr, status = Open3.capture3('sudo', 'chroot', chroot_dir, '/bin/bash', *cmd) + _, stderr, status = Open3.capture3("sudo", "chroot", chroot_dir, "/bin/bash", *cmd) fail(stderr) if status.exitstatus != 0 - return + nil end def chmod(mod, file_name) cmd = ["-c"] chmod_cmd = "chmod #{mod} #{file_name}" - cmd.push("#{chmod_cmd}") + cmd.push(chmod_cmd.to_s) - _, stderr, status = Open3.capture3('sudo', 'chroot', chroot_dir, '/bin/bash', *cmd) + _, stderr, status = Open3.capture3("sudo", "chroot", chroot_dir, "/bin/bash", *cmd) fail(stderr) if status.exitstatus != 0 - return + nil end def create_user(id) cmd = ["-c", "useradd -u #{id} --no-user-group user-#{id}"] - _, stderr, status = Open3.capture3('sudo', 'chroot', chroot_dir, '/bin/bash', *cmd) + _, stderr, status = Open3.capture3("sudo", "chroot", chroot_dir, "/bin/bash", *cmd) fail(stderr) if status.exitstatus != 0 id @@ -37,49 +37,49 @@ def create_user(id) def create_group(id) cmd = ["-c", "groupadd -g #{id} group-#{id}"] - _, stderr, status = Open3.capture3('sudo', 'chroot', chroot_dir, '/bin/bash', *cmd) + _, stderr, status = Open3.capture3("sudo", "chroot", chroot_dir, "/bin/bash", *cmd) fail(stderr) if status.exitstatus != 0 id end def add_user_to_group(random_gid, user_name) cmd = ["-c", "usermod -a -G group-#{random_gid} #{user_name}"] - _, stderr, status = Open3.capture3('sudo', 'chroot', chroot_dir, '/bin/bash', *cmd) + _, stderr, status = Open3.capture3("sudo", "chroot", chroot_dir, "/bin/bash", *cmd) fail(stderr) if status.exitstatus != 0 end def set_user_group(random_gid, user_name) cmd = ["-c", "usermod -g group-#{random_gid} #{user_name}"] - _, stderr, status = Open3.capture3('sudo', 'chroot', chroot_dir, '/bin/bash', *cmd) + _, stderr, status = Open3.capture3("sudo", "chroot", chroot_dir, "/bin/bash", *cmd) fail(stderr) if status.exitstatus != 0 end def delete_user_and_group(username, groupname) cmd = ["-c", "id #{username}"] - _, _, status = Open3.capture3('sudo', 'chroot', chroot_dir, '/bin/bash', *cmd) + _, _, status = Open3.capture3("sudo", "chroot", chroot_dir, "/bin/bash", *cmd) if status == 0 cmd = ["-c", "userdel #{username}"] - _, stderr, status = Open3.capture3('sudo', 'chroot', chroot_dir, '/bin/bash', *cmd) + _, stderr, status = Open3.capture3("sudo", "chroot", chroot_dir, "/bin/bash", *cmd) fail(stderr) if status.exitstatus != 0 end cmd = ["-c", "groupdel #{groupname}"] - _, stderr, status = Open3.capture3('sudo', 'chroot', chroot_dir, '/bin/bash', *cmd) + _, stderr, status = Open3.capture3("sudo", "chroot", chroot_dir, "/bin/bash", *cmd) fail(stderr) if status.exitstatus != 0 end let(:chroot) { ShelloutTypes::Chroot.new } let(:chroot_dir) { chroot.chroot_dir } - let(:regular_system_file) { Tempfile.new('a-file', chroot_dir) } + let(:regular_system_file) { Tempfile.new("a-file", chroot_dir) } let(:regular_system_filename) { ::File.basename(regular_system_file) } let(:regular_file) { described_class.new(regular_system_filename, chroot) } - let(:tmp_dirname) { ::File.basename(Dir.mktmpdir('a-dir', chroot_dir)) } + let(:tmp_dirname) { ::File.basename(Dir.mktmpdir("a-dir", chroot_dir)) } let(:directory_file) { described_class.new(tmp_dirname, chroot) } - let(:link_path) { ::File.join(tmp_dirname, 'link') } + let(:link_path) { ::File.join(tmp_dirname, "link") } let(:link) do - chroot.run('ln', '-s', "/#{regular_system_filename}", link_path) + chroot.run("ln", "-s", "/#{regular_system_filename}", link_path) described_class.new(link_path, chroot) end let(:nobody_uid) { 65534 } @@ -103,63 +103,63 @@ def delete_user_and_group(username, groupname) delete_user_and_group(ephemeral_user_name, ephemeral_group_name) end - describe '#file?' do - context 'when the file is a regular file' do - it 'returns true' do + describe "#file?" do + context "when the file is a regular file" do + it "returns true" do expect(regular_file.file?).to eq(true) end end - context 'when the file is not there' do - let(:absent_file) { described_class.new('not-real', chroot) } + context "when the file is not there" do + let(:absent_file) { described_class.new("not-real", chroot) } - it 'returns false' do + it "returns false" do expect(absent_file.file?).to eq(false) end end - context 'when the file is actually a directory' do - it 'returns false' do + context "when the file is actually a directory" do + it "returns false" do expect(directory_file.file?).to eq(false) end end - context 'when the file is a symlink' do - context 'that points to a real file' do - it 'follows the link and inspects the target' do + context "when the file is a symlink" do + context "that points to a real file" do + it "follows the link and inspects the target" do expect(link.file?).to eq(true) end end - context 'that points to a missing node' do + context "that points to a missing node" do before do link ::File.delete(::File.join(chroot_dir, regular_system_filename)) end - it 'returns false' do + it "returns false" do expect(link.file?).to eq(false) end end - context 'that points to a relatively located file' do - let(:file_in_dir) { Tempfile.new('link-target', ::File.join(chroot_dir, tmp_dirname)) } + context "that points to a relatively located file" do + let(:file_in_dir) { Tempfile.new("link-target", ::File.join(chroot_dir, tmp_dirname)) } let(:relative_path) { ::File.basename(file_in_dir.path) } let(:link_to_relative) do - chroot.run('ln', '-s', relative_path, link_path) + chroot.run("ln", "-s", relative_path, link_path) described_class.new(link_path, chroot) end - it 'can determine the absolute-in-chroot path of its target' do + it "can determine the absolute-in-chroot path of its target" do expect(link_to_relative.file?).to eq(true) end end end end - describe '#owned_by?' do - let(:owned_system_file) { Tempfile.new('a-file', chroot_dir) } + describe "#owned_by?" do + let(:owned_system_file) { Tempfile.new("a-file", chroot_dir) } let(:owned_file_path_relative_to_chroot) { ::File.basename(owned_system_file.path) } let(:owned_file) do chown(ephemeral_uid, nil, owned_file_path_relative_to_chroot) @@ -167,20 +167,20 @@ def delete_user_and_group(username, groupname) described_class.new(owned_file_path_relative_to_chroot, chroot) end - context 'when the provided user owns the file' do - it 'returns true' do + context "when the provided user owns the file" do + it "returns true" do expect(owned_file.owned_by?(ephemeral_user_name)).to eq(true) end end - context 'when the provided user does not own the file' do - it 'returns false' do - expect(owned_file.owned_by?('fake-user')).to eq(false) + context "when the provided user does not own the file" do + it "returns false" do + expect(owned_file.owned_by?("fake-user")).to eq(false) end end - context 'when the underlying file belongs to a user that does not exist' do - let(:system_file) { Tempfile.new('a-file', chroot_dir) } + context "when the underlying file belongs to a user that does not exist" do + let(:system_file) { Tempfile.new("a-file", chroot_dir) } let(:system_file_path_relative_to_chroot) { ::File.basename(system_file.path) } let(:file_with_unknown_owner) { random_uid = rand(100) + 1 * 65535 @@ -189,38 +189,38 @@ def delete_user_and_group(username, groupname) described_class.new(::File.basename(system_file.path), chroot) } - it('should raise an error') do + it("should raise an error") do expect { file_with_unknown_owner.owned_by?(ephemeral_user_name) }.to raise_error(RuntimeError, "user for file #{system_file.path} does not exist") end end - context 'when an unexpected error occurs' do + context "when an unexpected error occurs" do let(:stderr) { "cannot fork/exec for gid #{ephemeral_gid}" } - it 'should raise error' do - expect(chroot).to receive(:run).and_return(['', stderr, -1]) + it "should raise error" do + expect(chroot).to receive(:run).and_return(["", stderr, -1]) expect { owned_file.owned_by?(ephemeral_user_name) }.to raise_error(RuntimeError, "cannot fork/exec for gid #{ephemeral_gid}") end end - context 'when passwd entry is in an invalid format ' do - let(:stdout) { 'user:x:id:gid:GECOS:home-dir' } + context "when passwd entry is in an invalid format " do + let(:stdout) { "user:x:id:gid:GECOS:home-dir" } - it 'should raise error' do - expect(chroot).to receive(:run). - with('stat', '-c', '%u', owned_file_path_relative_to_chroot). - and_return(["#{ephemeral_uid}\n", '', 0]) - expect(chroot).to receive(:run).with("getent passwd #{ephemeral_uid}").and_return([stdout, '', 0]) + it "should raise error" do + expect(chroot).to receive(:run) + .with("stat", "-c", "%u", owned_file_path_relative_to_chroot) + .and_return(["#{ephemeral_uid}\n", "", 0]) + expect(chroot).to receive(:run).with("getent passwd #{ephemeral_uid}").and_return([stdout, "", 0]) - expect { owned_file.owned_by?(ephemeral_user_name) }.to raise_error(RuntimeError, 'passwd has an invalid format: user:x:id:gid:GECOS:home-dir') + expect { owned_file.owned_by?(ephemeral_user_name) }.to raise_error(RuntimeError, "passwd has an invalid format: user:x:id:gid:GECOS:home-dir") end end end - describe '#content' do + describe "#content" do let(:file_with_content_temp_file) do - a_file = Tempfile.new('a-file', chroot_dir) + a_file = Tempfile.new("a-file", chroot_dir) a_file.write("here is\nmy content") a_file.flush a_file @@ -229,14 +229,14 @@ def delete_user_and_group(username, groupname) described_class.new(::File.basename(file_with_content_temp_file), chroot) end - it 'returns the file content' do + it "returns the file content" do expect(file_with_content.content).to eq("here is\nmy content") end end - describe '#content_as_lines' do + describe "#content_as_lines" do let(:file_with_content_temp_file) do - a_file = Tempfile.new('a-file', chroot_dir) + a_file = Tempfile.new("a-file", chroot_dir) a_file.write("here is\nmy content") a_file.flush a_file @@ -245,28 +245,28 @@ def delete_user_and_group(username, groupname) described_class.new(::File.basename(file_with_content_temp_file), chroot) end - it 'returns the file content as an array of lines' do - expect(file_with_content.content_as_lines).to eq(["here is","my content"]) + it "returns the file content as an array of lines" do + expect(file_with_content.content_as_lines).to eq(["here is", "my content"]) end end - describe '#mode?' do - context 'when the file mode has matching u/g/o bits' do - it 'returns true' do - expect(regular_file.mode?(0600)).to eq(true) + describe "#mode?" do + context "when the file mode has matching u/g/o bits" do + it "returns true" do + expect(regular_file.mode?(0o600)).to eq(true) end end - context 'when the file mode has some other u/g/o bits' do - it 'returns false' do - expect(regular_file.mode?(0777)).to eq(false) + context "when the file mode has some other u/g/o bits" do + it "returns false" do + expect(regular_file.mode?(0o777)).to eq(false) end end end - describe '#group' do + describe "#group" do let(:group_temp_file) do - group_file = Tempfile.new('a-file', chroot_dir) + group_file = Tempfile.new("a-file", chroot_dir) group_file_path_relative_to_chroot = ::File.basename(group_file.path) chown(nil, ephemeral_gid, group_file_path_relative_to_chroot) group_file @@ -275,24 +275,24 @@ def delete_user_and_group(username, groupname) described_class.new(::File.basename(group_temp_file.path), chroot) end - it 'returns the group of the file' do + it "returns the group of the file" do expect(group_file.group).to eq(ephemeral_group_name) end - context('when the group entry is in an invalid format') do - let (:stdout) { 'has-no-gid-or-members:x' } + context("when the group entry is in an invalid format") do + let(:stdout) { "has-no-gid-or-members:x" } - it 'should raise' do - allow(chroot).to receive(:run).and_return([stdout, '', 0]) + it "should raise" do + allow(chroot).to receive(:run).and_return([stdout, "", 0]) - expect { group_file.group }.to raise_error(RuntimeError, 'group entry is an invalid format: has-no-gid-or-members:x') + expect { group_file.group }.to raise_error(RuntimeError, "group entry is an invalid format: has-no-gid-or-members:x") end end - context('when the group belonging to the file does not exist') do + context("when the group belonging to the file does not exist") do let(:current_group) { rand(100) + 1 * 65535 } let(:testgroup_temp_file) do - testgroup_file = Tempfile.new('a-file', chroot_dir) + testgroup_file = Tempfile.new("a-file", chroot_dir) testgroup_file_path_relative_to_chroot = ::File.basename(testgroup_file.path) chown(nil, current_group, testgroup_file_path_relative_to_chroot) testgroup_file @@ -301,83 +301,83 @@ def delete_user_and_group(username, groupname) described_class.new(::File.basename(testgroup_temp_file.path), chroot) end - it 'should raise' do + it "should raise" do expect { testgroup_file.group }.to raise_error(RuntimeError, "group #{current_group} does not exist") end end - context 'when an unexpected error occurs' do - let (:stderr) { "cannot fork/exec for gid #{ephemeral_gid}" } + context "when an unexpected error occurs" do + let(:stderr) { "cannot fork/exec for gid #{ephemeral_gid}" } - it 'should raise an error containing the stderr' do - expect(chroot).to receive(:run).and_return(['', stderr, -1]) + it "should raise an error containing the stderr" do + expect(chroot).to receive(:run).and_return(["", stderr, -1]) expect { group_file.group }.to raise_error(RuntimeError, "cannot fork/exec for gid #{ephemeral_gid}") end end end - describe '#readable_by_user?' do - let(:some_system_file) { Tempfile.new('a-file', chroot_dir) } + describe "#readable_by_user?" do + let(:some_system_file) { Tempfile.new("a-file", chroot_dir) } let(:some_system_file_path_chroot) { ::File.basename(some_system_file.path) } let(:some_file) { described_class.new(some_system_file_path_chroot, chroot) } - context 'when the file is owned by the specific user' do + context "when the file is owned by the specific user" do let(:user_file_gid) { rand(100) + 1 * 65535 } before do chown(ephemeral_uid, user_file_gid, some_system_file_path_chroot) end - context 'and readable' do + context "and readable" do before do chmod("0400", some_system_file_path_chroot) end - it 'returns true' do + it "returns true" do expect(some_file.readable_by_user?(ephemeral_user_name)).to eq(true) end end - context 'and not readable' do + context "and not readable" do before do chmod("0200", some_system_file_path_chroot) end - it 'returns false' do + it "returns false" do expect(some_file.readable_by_user?(ephemeral_user_name)).to eq(false) end end end - context 'when the user does not own the file but has the same group id' do + context "when the user does not own the file but has the same group id" do before do chown(nobody_uid, ephemeral_gid, some_system_file_path_chroot) end - context 'and the file is group readable' do + context "and the file is group readable" do before do chmod("0040", some_system_file_path_chroot) end - it 'returns true' do + it "returns true" do expect(some_file.readable_by_user?(ephemeral_user_name)).to eq(true) end end - context 'and the file is not group readable' do + context "and the file is not group readable" do before do chmod("0020", some_system_file_path_chroot) end - it 'returns false' do + it "returns false" do expect(some_file.readable_by_user?(ephemeral_user_name)).to eq(false) end end end - context 'and the user belongs to the file group members' do + context "and the user belongs to the file group members" do let(:group_with_members_id) { 9999 } let(:group_name_with_members) { "group-#{group_with_members_id}" } @@ -392,57 +392,57 @@ def delete_user_and_group(username, groupname) delete_user_and_group(ephemeral_user_name, group_name_with_members) end - context 'and the file is group readable' do + context "and the file is group readable" do before do chmod("0040", some_system_file_path_chroot) end - it 'returns true' do + it "returns true" do expect(some_file.readable_by_user?(ephemeral_user_name)).to eq(true) end end - context 'and the file is not group readable' do + context "and the file is not group readable" do before do chmod("0020", some_system_file_path_chroot) end - it 'returns false' do + it "returns false" do expect(some_file.readable_by_user?(ephemeral_user_name)).to eq(false) end end end - context 'when the user is not the owner or file group member' do + context "when the user is not the owner or file group member" do before do chown(nobody_uid, nogroup_gid, some_system_file_path_chroot) end - context 'and the file is world readable' do + context "and the file is world readable" do before do chmod("0004", some_system_file_path_chroot) end - it 'returns true' do + it "returns true" do expect(some_file.readable_by_user?(ephemeral_user_name)).to eq(true) end end - context 'and the file is not world readable' do + context "and the file is not world readable" do before do chmod("0002", some_system_file_path_chroot) end - it 'returns false' do + it "returns false" do expect(some_file.readable_by_user?(ephemeral_user_name)).to eq(false) end end end - context 'when the group belonging to the file does not exist' do + context "when the group belonging to the file does not exist" do let(:fake_group) { rand(100) + 1 * 65535 } let(:fake_group_temp_file) do - fake_group_file = Tempfile.new('a-file', chroot_dir) + fake_group_file = Tempfile.new("a-file", chroot_dir) fake_group_file_path_chroot = ::File.basename(fake_group_file.path) chown(nobody_uid, fake_group, fake_group_file_path_chroot) fake_group_file @@ -451,93 +451,93 @@ def delete_user_and_group(username, groupname) described_class.new(::File.basename(fake_group_temp_file.path), chroot) } - it 'should raise' do + it "should raise" do expect { fake_group_file.readable_by_user?(ephemeral_user_name) }.to raise_error(RuntimeError, "group #{fake_group} does not exist") end end - context 'when asking whether a nonexistent user can read the file' do + context "when asking whether a nonexistent user can read the file" do let(:invalid_user) { "invalid-user" } - it 'should raise' do + it "should raise" do expect { some_file.readable_by_user?(invalid_user) }.to raise_error(RuntimeError, "user #{invalid_user} does not exist") end end - context 'when an error occurs trying to determine the mode' do + context "when an error occurs trying to determine the mode" do before do - expect(chroot).to receive(:run). - with('stat', '-c', '%a', some_system_file_path_chroot). - and_return(['', 'mode error occurs', -1]) + expect(chroot).to receive(:run) + .with("stat", "-c", "%a", some_system_file_path_chroot) + .and_return(["", "mode error occurs", -1]) end - it 'raises a relevant error' do - expect { some_file.readable_by_user?(ephemeral_user_name) }.to raise_error(RuntimeError, 'mode error occurs') + it "raises a relevant error" do + expect { some_file.readable_by_user?(ephemeral_user_name) }.to raise_error(RuntimeError, "mode error occurs") end end - context 'when able to determine the mode for the file' do + context "when able to determine the mode for the file" do before do - expect(chroot).to receive(:run). - with('stat', '-c', '%a', some_system_file_path_chroot). - and_return(['0777', '', 0]) + expect(chroot).to receive(:run) + .with("stat", "-c", "%a", some_system_file_path_chroot) + .and_return(["0777", "", 0]) end - context 'when able to determine the user for the file' do + context "when able to determine the user for the file" do let(:getent_passwd_nobody_stdout) { "nobody:x:#{nobody_uid}:#{nobody_uid}:nobody:/nonexistent:/usr/sbin/nologin" } before do chown(nobody_uid, ephemeral_gid, some_system_file_path_chroot) - expect(chroot).to receive(:run). - with('stat', '-c', '%u', some_system_file_path_chroot). - and_return(["#{nobody_uid}", '', 0]) - expect(chroot).to receive(:run).with("getent passwd #{nobody_uid}").and_return([getent_passwd_nobody_stdout, '', 0]) + expect(chroot).to receive(:run) + .with("stat", "-c", "%u", some_system_file_path_chroot) + .and_return([nobody_uid.to_s, "", 0]) + expect(chroot).to receive(:run).with("getent passwd #{nobody_uid}").and_return([getent_passwd_nobody_stdout, "", 0]) end - context 'when an unexpected error occurs while fetching the group' do + context "when an unexpected error occurs while fetching the group" do let(:group_err) { "cannot fork/exec for gid #{ephemeral_gid}" } before do - expect(chroot).to receive(:run). - with('stat', '-c', '%g', some_system_file_path_chroot). - and_return(["#{ephemeral_gid}", '', 0]) - expect(chroot).to receive(:run).with("getent group #{ephemeral_gid}").and_return(['', group_err, -1]) + expect(chroot).to receive(:run) + .with("stat", "-c", "%g", some_system_file_path_chroot) + .and_return([ephemeral_gid.to_s, "", 0]) + expect(chroot).to receive(:run).with("getent group #{ephemeral_gid}").and_return(["", group_err, -1]) end - it 'should raise an error containing the stderr' do + it "should raise an error containing the stderr" do expect { some_file.readable_by_user?(ephemeral_user_name) }.to raise_error(RuntimeError, group_err) end end - context 'when able to fetch the group for the file' do + context "when able to fetch the group for the file" do let(:getent_group_ephemeral_stdout) { "#{ephemeral_group_name}:x:#{ephemeral_gid}:" } before do - expect(chroot).to receive(:run). - with('stat', '-c', '%g', some_system_file_path_chroot). - and_return(["#{ephemeral_gid}", '', 0]) - expect(chroot).to receive(:run). - with("getent group #{ephemeral_gid}"). - and_return([getent_group_ephemeral_stdout, '', 0]) + expect(chroot).to receive(:run) + .with("stat", "-c", "%g", some_system_file_path_chroot) + .and_return([ephemeral_gid.to_s, "", 0]) + expect(chroot).to receive(:run) + .with("getent group #{ephemeral_gid}") + .and_return([getent_group_ephemeral_stdout, "", 0]) end - context 'when an unexpected error occurs while fetching the passwd entry for the specific username' do + context "when an unexpected error occurs while fetching the passwd entry for the specific username" do let(:passwd_error) { "cannot fork/exec for uid #{ephemeral_uid}" } before do - expect(chroot).to receive(:run).with("getent passwd #{ephemeral_user_name}").and_return(['', passwd_error, -1]) + expect(chroot).to receive(:run).with("getent passwd #{ephemeral_user_name}").and_return(["", passwd_error, -1]) end - it 'should raise an error containing the stderr' do + it "should raise an error containing the stderr" do expect { some_file.readable_by_user?(ephemeral_user_name) }.to raise_error(RuntimeError, passwd_error) end end - context 'when able to fetch passwd entry but its format is invalid' do + context "when able to fetch passwd entry but its format is invalid" do let(:getent_passwd_with_bad_format_stdout) { "#{ephemeral_user_name}:x:#{ephemeral_uid}:#{ephemeral_gid}:GECOS:home-dir" } - it 'should raise an error' do - expect(chroot).to receive(:run).with("getent passwd #{ephemeral_user_name}").and_return([getent_passwd_with_bad_format_stdout, '', 0]) + it "should raise an error" do + expect(chroot).to receive(:run).with("getent passwd #{ephemeral_user_name}").and_return([getent_passwd_with_bad_format_stdout, "", 0]) expect { some_file.readable_by_user?(ephemeral_user_name) }.to raise_error(RuntimeError, "passwd has an invalid format: #{getent_passwd_with_bad_format_stdout}") end @@ -547,69 +547,68 @@ def delete_user_and_group(username, groupname) end end - describe '#writable_by?' do + describe "#writable_by?" do let(:base_file) do - Tempfile.new('a-file', chroot_dir) + Tempfile.new("a-file", chroot_dir) end let(:base_file_path_chroot) { ::File.basename(base_file.path) } - - context 'when the file is writeable by its group' do + context "when the file is writeable by its group" do let(:group_writable_file) do chmod("0020", base_file_path_chroot) described_class.new(::File.basename(base_file.path), chroot) end - it 'returns true' do - expect(group_writable_file.writable_by?('group')).to eq(true) + it "returns true" do + expect(group_writable_file.writable_by?("group")).to eq(true) end end - context 'when the file is not writeable by its group' do + context "when the file is not writeable by its group" do let(:group_unwritable_file) do chmod("0000", base_file_path_chroot) described_class.new(::File.basename(base_file.path), chroot) end - it 'returns false' do - expect(group_unwritable_file.writable_by?('group')).to eq(false) + it "returns false" do + expect(group_unwritable_file.writable_by?("group")).to eq(false) end end - context 'when the file is writeable by others' do + context "when the file is writeable by others" do let(:other_writable_file) do chmod("0002", base_file_path_chroot) described_class.new(::File.basename(base_file.path), chroot) end - it 'returns true' do - expect(other_writable_file.writable_by?('other')).to eq(true) + it "returns true" do + expect(other_writable_file.writable_by?("other")).to eq(true) end end - context 'when the file is not writeable by other' do + context "when the file is not writeable by other" do let(:other_unwritable_file) do chmod("0000", base_file_path_chroot) described_class.new(::File.basename(base_file.path), chroot) end - it 'returns false' do - expect(other_unwritable_file.writable_by?('other')).to eq(false) + it "returns false" do + expect(other_unwritable_file.writable_by?("other")).to eq(false) end end - context 'when an anything other than group or other is supplied' do - it 'returns an error' do - name="somebody-#{rand(100)}" + context "when an anything other than group or other is supplied" do + it "returns an error" do + name = "somebody-#{rand(100)}" expect { regular_file.writable_by?(name) }.to raise_error(RuntimeError, "#{name} is an invalid input to writable_by?, please specify one of: ['group', 'other']") end end end - describe '#executable?' do - context 'when the file is executable' do + describe "#executable?" do + context "when the file is executable" do let(:executable_temp_file) do - file = Tempfile.new('a-file', chroot_dir) + file = Tempfile.new("a-file", chroot_dir) chmod("0700", ::File.basename(file.path)) file end @@ -617,57 +616,57 @@ def delete_user_and_group(username, groupname) described_class.new(::File.basename(executable_temp_file.path), chroot) end - it 'returns true' do + it "returns true" do expect(executable_file.executable?).to eq(true) end end - context 'when the file is not executable' do - it 'returns false' do + context "when the file is not executable" do + it "returns false" do expect(regular_file.executable?).to eq(false) end end end - describe '#directory?' do - context 'when the file is a directory' do - it 'returns true' do + describe "#directory?" do + context "when the file is a directory" do + it "returns true" do expect(directory_file.directory?).to eq(true) end end - context 'when the file is not a directory' do - it 'returns false' do + context "when the file is not a directory" do + it "returns false" do expect(regular_file.directory?).to eq(false) end end end - describe '#linked_to?' do - let(:target) { Tempfile.new('target-file', chroot_dir) } + describe "#linked_to?" do + let(:target) { Tempfile.new("target-file", chroot_dir) } - context 'when the file is a symbolic link' do + context "when the file is a symbolic link" do let(:source) do - file_path = target.path.gsub(/target/, 'source') + file_path = target.path.gsub("target", "source") ::File.symlink(target.path, file_path) described_class.new(::File.basename(file_path), chroot) end - it 'returns true when the file links to the specified target' do + it "returns true when the file links to the specified target" do expect(source.linked_to?(target.path)).to eq(true) end - it 'returns false when the file links to a different target' do - expect(source.linked_to?('/path/to/foo')).to eq(false) + it "returns false when the file links to a different target" do + expect(source.linked_to?("/path/to/foo")).to eq(false) end end - context 'when the file is not a symbolic link' do - let(:source_temp_file) { Tempfile.new('a-file', chroot_dir) } + context "when the file is not a symbolic link" do + let(:source_temp_file) { Tempfile.new("a-file", chroot_dir) } let(:source) do described_class.new(::File.basename(source_temp_file.path), chroot) end - it 'returns false' do + it "returns false" do expect(source.linked_to?(target.path)).to eq(false) end end diff --git a/bosh-stemcell/spec/shellout_types/group_spec.rb b/bosh-stemcell/spec/shellout_types/group_spec.rb index 5a1afd0ddd..3af923981a 100644 --- a/bosh-stemcell/spec/shellout_types/group_spec.rb +++ b/bosh-stemcell/spec/shellout_types/group_spec.rb @@ -1,24 +1,24 @@ -require_relative 'spec_helper' -require 'shellout_types/group' +require_relative "spec_helper" +require "shellout_types/group" module ShelloutTypes describe Group, shellout_types: true do - describe '#exists?' do + describe "#exists?" do let(:chroot) { ShelloutTypes::Chroot.new } let(:group) { described_class.new(group_name, chroot) } - context 'when the group exists' do - let(:group_name) { 'root' } + context "when the group exists" do + let(:group_name) { "root" } - it 'returns true' do + it "returns true" do expect(group.exists?).to eq(true) end end - context 'when the group does not exist' do - let(:group_name) { 'potato' } + context "when the group does not exist" do + let(:group_name) { "potato" } - it 'returns false' do + it "returns false" do expect(group.exists?).to eq(false) end end diff --git a/bosh-stemcell/spec/shellout_types/package_spec.rb b/bosh-stemcell/spec/shellout_types/package_spec.rb index a8068b3879..b5ea763af5 100644 --- a/bosh-stemcell/spec/shellout_types/package_spec.rb +++ b/bosh-stemcell/spec/shellout_types/package_spec.rb @@ -1,5 +1,5 @@ -require_relative 'spec_helper' -require 'shellout_types/package' +require_relative "spec_helper" +require "shellout_types/package" module ShelloutTypes describe Package, shellout_types: true do @@ -8,19 +8,19 @@ module ShelloutTypes ShelloutTypes::Chroot.new } - describe '#installed?' do - context 'when a package is installed' do - let(:package_name) { 'dpkg' } + describe "#installed?" do + context "when a package is installed" do + let(:package_name) { "dpkg" } - it 'returns true' do + it "returns true" do expect(package.installed?).to eq(true) end end - context 'when a package is not_installed' do - let(:package_name) { 'non-existent-package' } + context "when a package is not_installed" do + let(:package_name) { "non-existent-package" } - it 'returns false' do + it "returns false" do expect(package.installed?).to eq(false) end end diff --git a/bosh-stemcell/spec/shellout_types/service_spec.rb b/bosh-stemcell/spec/shellout_types/service_spec.rb index 0a1ee3cf07..d060f14256 100644 --- a/bosh-stemcell/spec/shellout_types/service_spec.rb +++ b/bosh-stemcell/spec/shellout_types/service_spec.rb @@ -1,27 +1,26 @@ -require_relative 'spec_helper' -require 'shellout_types/service' +require_relative "spec_helper" +require "shellout_types/service" module ShelloutTypes describe Service, shellout_types: true do let(:chroot) { ShelloutTypes::Chroot.new } - describe '#enabled?' do - context 'when the service is enabled' do - let(:service) { described_class.new('networking', chroot) } + describe "#enabled?" do + context "when the service is enabled" do + let(:service) { described_class.new("networking", chroot) } - it 'returns true' do + it "returns true" do expect(service.enabled?).to eq(true) end end - context 'when the service is not enabled' do - let(:service) { described_class.new('auditd', chroot) } + context "when the service is not enabled" do + let(:service) { described_class.new("auditd", chroot) } - it 'returns false' do + it "returns false" do expect(service.enabled?).to eq(false) end end end end end - diff --git a/bosh-stemcell/spec/shellout_types/spec_helper.rb b/bosh-stemcell/spec/shellout_types/spec_helper.rb index fe47dc7170..8a468bcb51 100644 --- a/bosh-stemcell/spec/shellout_types/spec_helper.rb +++ b/bosh-stemcell/spec/shellout_types/spec_helper.rb @@ -1,33 +1,36 @@ -require 'bosh/core/shell' -require 'rspec' -require 'shellout_types/chroot' -require 'tmpdir' +require "bosh/core/shell" +require "rspec" +require "shellout_types/chroot" +require "tmpdir" +def supported_testing_os? + RUBY_PLATFORM.downcase.include?("linux") +end RSpec.configure do |config| if config.inclusion_filter[:shellout_types] - if ENV['OS_IMAGE'] - @os_image_dir = Dir.mktmpdir('os-image-rspec') + config.before(:suite) do + raise "Running 'shellout_types' specs on '#{RUBY_PLATFORM}' is not supported" unless supported_testing_os? + end + + if ENV["OS_IMAGE"] + @os_image_dir = Dir.mktmpdir("os-image-rspec") ShelloutTypes::Chroot.chroot_dir = @os_image_dir config.add_setting(:os_image_dir, default: @os_image_dir) config.before(:suite) do - Bosh::Core::Shell.new.run("sudo tar zxf #{ENV['OS_IMAGE']} -C #{config.os_image_dir}") + Bosh::Core::Shell.new.run("sudo tar zxf #{ENV["OS_IMAGE"]} -C #{config.os_image_dir}") Bosh::Core::Shell.new.run("sudo chgrp -Rh $(id -g) #{config.os_image_dir}") Bosh::Core::Shell.new.run("sudo chmod 775 #{config.os_image_dir}") - if ENV['OSX'] - Bosh::Core::Shell.new.run("sudo chroot #{config.os_image_dir} /bin/bash -c \"useradd --uid $(id -u) -G nogroup shellout\"") - else - Bosh::Core::Shell.new.run("sudo chroot #{config.os_image_dir} /bin/bash -c 'useradd -G nogroup shellout'") - end + Bosh::Core::Shell.new.run("sudo chroot #{config.os_image_dir} /bin/bash -c 'useradd -G nogroup shellout'") end config.after(:suite) do ShelloutTypes::Chroot.unmount_proc Bosh::Core::Shell.new.run("sudo rm -rf #{config.os_image_dir}") end - elsif ENV['SHELLOUT_CHROOT_DIR'] - ShelloutTypes::Chroot.chroot_dir = ENV['SHELLOUT_CHROOT_DIR'] + elsif ENV["SHELLOUT_CHROOT_DIR"] + ShelloutTypes::Chroot.chroot_dir = ENV["SHELLOUT_CHROOT_DIR"] else warning = 'Both ENV["OS_IMAGE"] and ENV["SHELLOUT_CHROOT_DIR"] are not set, shellout types test cases are being skipped.' puts RSpec::Core::Formatters::ConsoleCodes.wrap(warning, :yellow) diff --git a/bosh-stemcell/spec/shellout_types/user_spec.rb b/bosh-stemcell/spec/shellout_types/user_spec.rb index 3ac1a09832..ce81637080 100644 --- a/bosh-stemcell/spec/shellout_types/user_spec.rb +++ b/bosh-stemcell/spec/shellout_types/user_spec.rb @@ -1,78 +1,78 @@ -require_relative 'spec_helper' -require 'shellout_types/user' +require_relative "spec_helper" +require "shellout_types/user" module ShelloutTypes describe User, shellout_types: true do let(:runner) { ShelloutTypes::Chroot.new } let(:user) { described_class.new(user_name, runner) } - describe '#exists?' do - context 'when the user exists' do - let(:user_name) { 'root' } + describe "#exists?" do + context "when the user exists" do + let(:user_name) { "root" } - it 'returns true' do + it "returns true" do expect(user.exists?).to eq(true) end end - context 'when the user does not exist' do - let(:user_name) { 'garbage' } + context "when the user does not exist" do + let(:user_name) { "garbage" } - it 'returns false' do + it "returns false" do expect(user.exists?).to eq(false) end end end - describe '#in_group?' do + describe "#in_group?" do # before do # allow(runner).to receive(:run).with("id #{user_name}").and_return([nil, nil, user_exists_status]) # end - context 'when the user exists' do - let(:user_name) { 'root' } + context "when the user exists" do + let(:user_name) { "root" } # let(:user_exists_status) { 0 } # before do # expect(runner).to receive(:run).with("id -Gn #{user_name}").and_return([group_stdout, nil, group_status]) # end - context 'when the group exists' do + context "when the group exists" do # let(:group_status) { 0 } - let(:group) { 'root' } + let(:group) { "root" } # let(:group_stdout) { 'root' } - context 'and the user belongs to the group' do - it 'returns true' do + context "and the user belongs to the group" do + it "returns true" do expect(user.in_group?(group)).to eq(true) end end - context 'and the user does not belong to the group' do - let(:group) { 'nogroup' } + context "and the user does not belong to the group" do + let(:group) { "nogroup" } - it 'returns false' do + it "returns false" do expect(user.in_group?(group)).to eq(false) end end end - context 'when the group does not exist' do - let(:group) { 'garbage' } + context "when the group does not exist" do + let(:group) { "garbage" } # let(:group_stdout) { '' } # let(:group_status) { 1 } - it 'returns false' do + it "returns false" do expect(user.in_group?(group)).to eq(false) end end end - context 'when the user does not exist' do - let(:user_name) { 'garbage' } - let(:group) { 'root' } + context "when the user does not exist" do + let(:user_name) { "garbage" } + let(:group) { "root" } - it 'returns false' do + it "returns false" do expect(user.in_group?(group)).to eq(false) end end diff --git a/bosh-stemcell/spec/spec_helper.rb b/bosh-stemcell/spec/spec_helper.rb index b59e73a2fd..73e07c23e9 100644 --- a/bosh-stemcell/spec/spec_helper.rb +++ b/bosh-stemcell/spec/spec_helper.rb @@ -1,10 +1,9 @@ -require 'rspec' -require 'rspec/its' -require 'fakefs/spec_helpers' -require 'support/shellout_type_assertions.rb' -require 'tmpdir' +require "rspec" +require "rspec/its" +require "support/shellout_type_assertions" +require "tmpdir" -Dir.glob(File.expand_path('../support/**/*.rb', __FILE__)).each { |f| require(f) } +Dir.glob(File.expand_path("../support/**/*.rb", __FILE__)).each { |f| require(f) } # do not truncate array comparison RSpec.configure do |rspec| @@ -14,9 +13,9 @@ end def grub_cfg_path - if %w[aws google vsphere].include?(ENV['STEMCELL_INFRASTRUCTURE']) - '/boot/efi/EFI/grub/grub.cfg' + if %w[aws google vsphere].include?(ENV["STEMCELL_INFRASTRUCTURE"]) + "/boot/efi/EFI/grub/grub.cfg" else - '/boot/grub/grub.cfg' + "/boot/grub/grub.cfg" end end diff --git a/bosh-stemcell/spec/stemcells/alicloud_spec.rb b/bosh-stemcell/spec/stemcells/alicloud_spec.rb index 7156157bf1..f1002ca0dc 100644 --- a/bosh-stemcell/spec/stemcells/alicloud_spec.rb +++ b/bosh-stemcell/spec/stemcells/alicloud_spec.rb @@ -1,27 +1,27 @@ -require 'spec_helper' +require "spec_helper" -describe 'AliCloud Stemcell', stemcell_image: true do - it_behaves_like 'udf module is disabled' +describe "AliCloud Stemcell", stemcell_image: true do + it_behaves_like "udf module is disabled" - context 'installed by system_parameters' do - describe file('/var/vcap/bosh/etc/infrastructure') do - its(:content) { should match('alicloud') } + context "installed by system_parameters" do + describe file("/var/vcap/bosh/etc/infrastructure") do + its(:content) { should match("alicloud") } end end - context 'installed by base_ssh' do - describe 'disallows password authentication' do - subject { file('/etc/ssh/sshd_config') } + context "installed by base_ssh" do + describe "disallows password authentication" do + subject { file("/etc/ssh/sshd_config") } - its(:content) { should match /^PasswordAuthentication no$/ } + its(:content) { should match(/^PasswordAuthentication no$/) } end end - context 'ext4 filesystems' do - describe 'should not contain ext4 feature metadata_csum' do - subject { file('/etc/mke2fs.conf') } + context "ext4 filesystems" do + describe "should not contain ext4 feature metadata_csum" do + subject { file("/etc/mke2fs.conf") } - its(:content) { should_not match /metadata_csum/ } + its(:content) { should_not match(/metadata_csum/) } end end end diff --git a/bosh-stemcell/spec/stemcells/aws_spec.rb b/bosh-stemcell/spec/stemcells/aws_spec.rb index b562ac5f8b..8a9309fd5b 100644 --- a/bosh-stemcell/spec/stemcells/aws_spec.rb +++ b/bosh-stemcell/spec/stemcells/aws_spec.rb @@ -1,40 +1,40 @@ -require 'spec_helper' +require "spec_helper" -describe 'AWS Stemcell', stemcell_image: true do - it_behaves_like 'udf module is disabled' +describe "AWS Stemcell", stemcell_image: true do + it_behaves_like "udf module is disabled" - context 'installed by system_parameters' do - describe file('/var/vcap/bosh/etc/infrastructure') do - its(:content) { should match('aws') } + context "installed by system_parameters" do + describe file("/var/vcap/bosh/etc/infrastructure") do + its(:content) { should match("aws") } end end - context 'installed by base_ssh' do - describe 'disallows password authentication' do - subject { file('/etc/ssh/sshd_config') } + context "installed by base_ssh" do + describe "disallows password authentication" do + subject { file("/etc/ssh/sshd_config") } - its(:content) { should match /^PasswordAuthentication no$/ } + its(:content) { should match(/^PasswordAuthentication no$/) } end end - context 'installed by image_install_grub' do + context "installed by image_install_grub" do describe file(grub_cfg_path) do it { should be_file } - its(:content) { should match ' nvme_core.io_timeout=4294967295' } + its(:content) { should match " nvme_core.io_timeout=4294967295" } end end - describe 'nvme' do - describe 'nvme-id finder' do - subject { file('/sbin/nvme-id') } + describe "nvme" do + describe "nvme-id finder" do + subject { file("/sbin/nvme-id") } it { should be_file } it { should be_executable } its(:content) { should match(/nvme id-ctrl/) } end - describe 'udev rules' do - subject { file('/etc/udev/rules.d/70-ec2-nvme-devices.rules') } + describe "udev rules" do + subject { file("/etc/udev/rules.d/70-ec2-nvme-devices.rules") } it { should be_file } its(:content) { should match %r{/sbin/nvme-id} } diff --git a/bosh-stemcell/spec/stemcells/azure_spec.rb b/bosh-stemcell/spec/stemcells/azure_spec.rb index bc6d784931..c893b4a99c 100755 --- a/bosh-stemcell/spec/stemcells/azure_spec.rb +++ b/bosh-stemcell/spec/stemcells/azure_spec.rb @@ -1,34 +1,34 @@ -require 'spec_helper' +require "spec_helper" -describe 'Azure Stemcell', stemcell_image: true do - context 'installed by system_parameters' do - describe file('/var/vcap/bosh/etc/infrastructure') do - its(:content) { should include('azure') } +describe "Azure Stemcell", stemcell_image: true do + context "installed by system_parameters" do + describe file("/var/vcap/bosh/etc/infrastructure") do + its(:content) { should include("azure") } end end - context 'installed by base_ssh' do - describe 'disallows password authentication' do - subject { file('/etc/ssh/sshd_config') } - its(:content) { should match /^PasswordAuthentication no$/ } + context "installed by base_ssh" do + describe "disallows password authentication" do + subject { file("/etc/ssh/sshd_config") } + its(:content) { should match(/^PasswordAuthentication no$/) } end end - context 'udf module should be enabled' do - describe file('/etc/modprobe.d/blacklist.conf') do - its(:content) { should_not match 'install udf /bin/true' } + context "udf module should be enabled" do + describe file("/etc/modprobe.d/blacklist.conf") do + its(:content) { should_not match "install udf /bin/true" } end end - context 'installed by bosh_azure_agent_settings', { + context "installed by bosh_azure_agent_settings", { exclude_on_alicloud: true, exclude_on_aws: true, exclude_on_google: true, exclude_on_vsphere: true, exclude_on_warden: true, - exclude_on_openstack: true, + exclude_on_openstack: true } do - describe file('/var/vcap/bosh/agent.json') do + describe file("/var/vcap/bosh/agent.json") do it { should be_valid_json_file } its(:content) { should include('"Type": "File"') } its(:content) { should include('"MetaDataPath": ""') } @@ -41,19 +41,19 @@ end end - context 'cloud-init Azure APT mirror configuration' do - describe file('/etc/cloud/cloud.cfg.d/90-azure-apt-sources.cfg') do + context "cloud-init Azure APT mirror configuration" do + describe file("/etc/cloud/cloud.cfg.d/90-azure-apt-sources.cfg") do it { should be_file } - its(:content) { should include('http://azure.archive.ubuntu.com/ubuntu/') } + its(:content) { should include("http://azure.archive.ubuntu.com/ubuntu/") } end - describe file('/etc/cloud/cloud.cfg') do + describe file("/etc/cloud/cloud.cfg") do it { should be_file } - its(:content) { should include('apt-configure') } + its(:content) { should include("apt-configure") } end end - context 'installed by system_azure_init', { + context "installed by system_azure_init", { exclude_on_alicloud: true, exclude_on_aws: true, exclude_on_google: true, @@ -61,29 +61,29 @@ exclude_on_vsphere: true, exclude_on_warden: true, exclude_on_openstack: true, - exclude_on_softlayer: true, + exclude_on_softlayer: true } do - describe 'Hyper-V KVP daemon' do - describe command('which hv_kvp_daemon') do + describe "Hyper-V KVP daemon" do + describe command("which hv_kvp_daemon") do its(:exit_status) { should eq 0 } end - describe service('hv-kvp-daemon') do + describe service("hv-kvp-daemon") do it { should be_enabled } end end - describe 'WALinuxAgent configuration' do - describe file('/etc/waagent.conf') do - it { should be_owned_by('root') } + describe "WALinuxAgent configuration" do + describe file("/etc/waagent.conf") do + it { should be_owned_by("root") } end - describe file('/lib/systemd/system/walinuxagent.service') do - it { should be_mode(0644) } - it { should be_owned_by('root') } + describe file("/lib/systemd/system/walinuxagent.service") do + it { should be_mode(0o644) } + it { should be_owned_by("root") } end - describe service('walinuxagent') do + describe service("walinuxagent") do it { should be_enabled } end end diff --git a/bosh-stemcell/spec/stemcells/cis_spec.rb b/bosh-stemcell/spec/stemcells/cis_spec.rb index 0d852d403f..187307099a 100644 --- a/bosh-stemcell/spec/stemcells/cis_spec.rb +++ b/bosh-stemcell/spec/stemcells/cis_spec.rb @@ -1,55 +1,55 @@ -require 'spec_helper' +require "spec_helper" -describe 'CIS test case verification', {stemcell_image: true, security_spec: true} do - let(:base_cis_test_cases) do %W{ - CIS-2.18 - CIS-2.19 - CIS-2.20 - CIS-2.21 - CIS-2.22 - CIS-2.23 - CIS-3.2.4 - CIS-4.1 - CIS-7.2.5 - CIS-7.2.6 - CIS-7.2.7 - CIS-7.5.3 - CIS-11.1 - CIS-8.1.3 - CIS-8.1.4 - CIS-8.1.5 - CIS-4.1.6 - CIS-4.1.7 - CIS-8.1.8 - CIS-8.1.9 - CIS-8.1.10 - CIS-8.1.11 - CIS-8.1.12 - CIS-8.1.13 - CIS-8.1.14 - CIS-8.1.15 - CIS-8.1.16 - CIS-8.1.18 - CIS-9.1.2 - CIS-9.1.3 - CIS-9.1.4 - CIS-9.1.5 - CIS-9.1.6 - CIS-9.1.7 - CIS-9.1.8 - CIS-9.2.1 - CIS-9.4 - CIS-9.5 - CIS-10.2 - CIS-5.2.12 - CIS-5.2.13 - } +describe "CIS test case verification", {stemcell_image: true, security_spec: true} do + let(:base_cis_test_cases) do + %W[ + CIS-2.18 + CIS-2.19 + CIS-2.20 + CIS-2.21 + CIS-2.22 + CIS-2.23 + CIS-3.2.4 + CIS-4.1 + CIS-7.2.5 + CIS-7.2.6 + CIS-7.2.7 + CIS-7.5.3 + CIS-11.1 + CIS-8.1.3 + CIS-8.1.4 + CIS-8.1.5 + CIS-4.1.6 + CIS-4.1.7 + CIS-8.1.8 + CIS-8.1.9 + CIS-8.1.10 + CIS-8.1.11 + CIS-8.1.12 + CIS-8.1.13 + CIS-8.1.14 + CIS-8.1.15 + CIS-8.1.16 + CIS-8.1.18 + CIS-9.1.2 + CIS-9.1.3 + CIS-9.1.4 + CIS-9.1.5 + CIS-9.1.6 + CIS-9.1.7 + CIS-9.1.8 + CIS-9.2.1 + CIS-9.4 + CIS-9.5 + CIS-10.2 + CIS-5.2.12 + CIS-5.2.13 + ] end - - context "For all infrastructure except Azure and Cloudstack", {exclude_on_azure:true, exclude_on_cloudstack:true} do - it 'confirms that all CIS test cases ran' do - expect($cis_test_cases.to_a).to match_array(base_cis_test_cases + ['CIS-2.24']) + context "For all infrastructure except Azure and Cloudstack", {exclude_on_azure: true, exclude_on_cloudstack: true} do + it "confirms that all CIS test cases ran" do + expect($cis_test_cases.to_a).to match_array(base_cis_test_cases + ["CIS-2.24"]) # standard:disable Style/GlobalVars end end @@ -60,10 +60,10 @@ exclude_on_vsphere: true, exclude_on_warden: true, exclude_on_openstack: true, - exclude_on_cloudstack: true, + exclude_on_cloudstack: true } do - it 'confirms that all CIS test cases ran' do - expect($cis_test_cases.to_a).to match_array(base_cis_test_cases) + it "confirms that all CIS test cases ran" do + expect($cis_test_cases.to_a).to match_array(base_cis_test_cases) # standard:disable Style/GlobalVars end end end diff --git a/bosh-stemcell/spec/stemcells/cloudstack_spec.rb b/bosh-stemcell/spec/stemcells/cloudstack_spec.rb index 353a6c4a80..cc9de5fecc 100644 --- a/bosh-stemcell/spec/stemcells/cloudstack_spec.rb +++ b/bosh-stemcell/spec/stemcells/cloudstack_spec.rb @@ -1,18 +1,17 @@ -require 'spec_helper' +require "spec_helper" -describe 'CloudStack Stemcell', stemcell_image: true do - context 'installed by system_parameters' do - describe file('/var/vcap/bosh/etc/infrastructure') do - its(:content) { should match('cloudstack') } +describe "CloudStack Stemcell", stemcell_image: true do + context "installed by system_parameters" do + describe file("/var/vcap/bosh/etc/infrastructure") do + its(:content) { should match("cloudstack") } end end + context "installed by base_ssh" do + describe "disallows password authentication" do + subject { file("/etc/ssh/sshd_config") } - context 'installed by base_ssh' do - describe 'disallows password authentication' do - subject { file('/etc/ssh/sshd_config') } - - its(:content) { should match /^PasswordAuthentication no$/ } + its(:content) { should match(/^PasswordAuthentication no$/) } end end end diff --git a/bosh-stemcell/spec/stemcells/fips_spec.rb b/bosh-stemcell/spec/stemcells/fips_spec.rb index 1420882745..a8fe0b9b93 100644 --- a/bosh-stemcell/spec/stemcells/fips_spec.rb +++ b/bosh-stemcell/spec/stemcells/fips_spec.rb @@ -1,41 +1,41 @@ -require 'spec_helper' +require "spec_helper" -describe 'FIPS Stemcell', os_image: true do - use_iaas_kernel = ENV.fetch('UBUNTU_FIPS_USE_IAAS_KERNEL', 'false') == 'true' - context 'installed by system_kernel' do - infrastructure = ENV['STEMCELL_INFRASTRUCTURE'] +describe "FIPS Stemcell", os_image: true do + use_iaas_kernel = ENV.fetch("UBUNTU_FIPS_USE_IAAS_KERNEL", "false") == "true" + context "installed by system_kernel" do + infrastructure = ENV["STEMCELL_INFRASTRUCTURE"] describe package(use_iaas_kernel ? "linux-image-#{infrastructure}-fips" : "linux-image-fips") do it { should be_installed } end - describe package('linux-generic') do + describe package("linux-generic") do it { should_not be_installed } end - describe package('linux-image-5.19.0-109-generic') do + describe package("linux-image-5.19.0-109-generic") do it { should_not be_installed } end end - context 'installed by base_ssh' do - subject(:sshd_config) { file('/etc/ssh/sshd_config') } + context "installed by base_ssh" do + subject(:sshd_config) { file("/etc/ssh/sshd_config") } - it 'allows only secure HMACs' do + it "allows only secure HMACs" do macs = %w[ - hmac-sha2-512-etm@openssh.com - hmac-sha2-256-etm@openssh.com - hmac-sha2-512 - hmac-sha2-256 - ].join(',') + hmac-sha2-512-etm@openssh.com + hmac-sha2-256-etm@openssh.com + hmac-sha2-512 + hmac-sha2-256 + ].join(",") expect(sshd_config.content).to match(/^MACs #{macs}$/) end - it 'enables RSA, ECDSA host keys' do + it "enables RSA, ECDSA host keys" do matches = sshd_config.content.scan(/^HostKey.*/) - expect(matches).to contain_exactly('HostKey /etc/ssh/ssh_host_rsa_key', 'HostKey /etc/ssh/ssh_host_ecdsa_key') + expect(matches).to contain_exactly("HostKey /etc/ssh/ssh_host_rsa_key", "HostKey /etc/ssh/ssh_host_ecdsa_key") end end - context 'installed by image_install_grub for fips kernel' do + context "installed by image_install_grub for fips kernel" do describe file(grub_cfg_path) do it { should be_file } its(:content) { should match %r{linux\t/boot/vmlinuz-\S+-fips root=UUID=\S* ro } } @@ -49,18 +49,18 @@ linux_version_regex = 's/linux-(.+)-([0-9]+).([0-9]+).([0-9]+)-([0-9]+)/linux-\1-\2.\3/' - describe 'installed packages' do + describe "installed packages" do dpkg_list_packages = "dpkg --get-selections | cut -f1 | sed -E '#{linux_version_regex}'" # TODO: maby we can use awk "dpkg --get-selections | awk '!/linux-(.+)-([0-9]+.+)/&&/linux/{print $1}'" - let(:dpkg_list_ubuntu) { File.readlines(spec_asset('dpkg-list-ubuntu.txt')).map(&:chop) } - let(:dpkg_list_fips_ubuntu) { File.readlines(spec_asset('dpkg-list-ubuntu-fips.txt')).map(&:chop) } - let(:dpkg_list_aws_fips_ubuntu) { File.readlines(spec_asset('dpkg-list-ubuntu-aws-fips.txt')).map(&:chop) } - let(:dpkg_list_google_ubuntu) { File.readlines(spec_asset('dpkg-list-ubuntu-google-additions.txt')).map(&:chop) } - let(:dpkg_list_vsphere_ubuntu) { File.readlines(spec_asset('dpkg-list-ubuntu-vsphere-additions.txt')).map(&:chop) } - let(:dpkg_list_azure_ubuntu) { File.readlines(spec_asset('dpkg-list-ubuntu-azure-additions.txt')).map(&:chop) } - let(:dpkg_list_cloudstack_ubuntu) { File.readlines(spec_asset('dpkg-list-ubuntu-cloudstack-additions.txt')).map(&:chop) } - let(:infrastructure) { ENV['STEMCELL_INFRASTRUCTURE'] } + let(:dpkg_list_ubuntu) { File.readlines(spec_asset("dpkg-list-ubuntu.txt")).map(&:chop) } + let(:dpkg_list_fips_ubuntu) { File.readlines(spec_asset("dpkg-list-ubuntu-fips.txt")).map(&:chop) } + let(:dpkg_list_aws_fips_ubuntu) { File.readlines(spec_asset("dpkg-list-ubuntu-aws-fips.txt")).map(&:chop) } + let(:dpkg_list_google_ubuntu) { File.readlines(spec_asset("dpkg-list-ubuntu-google-additions.txt")).map(&:chop) } + let(:dpkg_list_vsphere_ubuntu) { File.readlines(spec_asset("dpkg-list-ubuntu-vsphere-additions.txt")).map(&:chop) } + let(:dpkg_list_azure_ubuntu) { File.readlines(spec_asset("dpkg-list-ubuntu-azure-additions.txt")).map(&:chop) } + let(:dpkg_list_cloudstack_ubuntu) { File.readlines(spec_asset("dpkg-list-ubuntu-cloudstack-additions.txt")).map(&:chop) } + let(:infrastructure) { ENV["STEMCELL_INFRASTRUCTURE"] } describe command(dpkg_list_packages), { exclude_on_alicloud: true, @@ -68,13 +68,13 @@ exclude_on_vsphere: true, exclude_on_warden: true, exclude_on_azure: true, - exclude_on_openstack: true, + exclude_on_openstack: true } do - it 'contains only the base set of packages plus aws-specific kernel packages' do + it "contains only the base set of packages plus aws-specific kernel packages" do skip "Test skipped due to generic kernel" unless use_iaas_kernel pkg_list = dpkg_list_ubuntu.concat(dpkg_list_aws_fips_ubuntu) - pkg_list.delete('linux-firmware') - pkg_list.delete('wireless-regdb') + pkg_list.delete("linux-firmware") + pkg_list.delete("wireless-regdb") expect(subject.stdout.split("\n")).to match_array(pkg_list) end end @@ -83,9 +83,9 @@ exclude_on_cloudstack: true, exclude_on_google: true, exclude_on_vsphere: true, - exclude_on_azure: true, + exclude_on_azure: true } do - it 'contains only the base set of packages for alicloud, aws, openstack, warden' do + it "contains only the base set of packages for alicloud, aws, openstack, warden" do skip "Test skipped due to IAAS-specific kernel" if use_iaas_kernel expect(subject.stdout.split("\n")).to match_array(dpkg_list_ubuntu.concat(dpkg_list_fips_ubuntu)) end @@ -98,9 +98,9 @@ exclude_on_vsphere: true, exclude_on_warden: true, exclude_on_azure: true, - exclude_on_openstack: true, + exclude_on_openstack: true } do - it 'contains only the base set of packages plus google-specific packages' do + it "contains only the base set of packages plus google-specific packages" do expect(subject.stdout.split("\n")).to match_array(dpkg_list_ubuntu.concat(dpkg_list_fips_ubuntu, dpkg_list_google_ubuntu)) end end @@ -112,9 +112,9 @@ exclude_on_google: true, exclude_on_warden: true, exclude_on_azure: true, - exclude_on_openstack: true, + exclude_on_openstack: true } do - it 'contains only the base set of packages plus vsphere-specific packages' do + it "contains only the base set of packages plus vsphere-specific packages" do expect(subject.stdout.split("\n")).to match_array(dpkg_list_ubuntu.concat(dpkg_list_fips_ubuntu, dpkg_list_vsphere_ubuntu)) end end @@ -126,9 +126,9 @@ exclude_on_vsphere: true, exclude_on_google: true, exclude_on_warden: true, - exclude_on_openstack: true, + exclude_on_openstack: true } do - it 'contains only the base set of packages plus azure-specific packages' do + it "contains only the base set of packages plus azure-specific packages" do expect(subject.stdout.split("\n")).to match_array(dpkg_list_ubuntu.concat(dpkg_list_fips_ubuntu, dpkg_list_azure_ubuntu)) end end @@ -140,12 +140,11 @@ exclude_on_google: true, exclude_on_warden: true, exclude_on_azure: true, - exclude_on_openstack: true, + exclude_on_openstack: true } do - it 'contains only the base set of packages plus cloudstack-specific packages' do + it "contains only the base set of packages plus cloudstack-specific packages" do expect(subject.stdout.split("\n")).to match_array(dpkg_list_ubuntu.concat(dpkg_list_fips_ubuntu, dpkg_list_cloudstack_ubuntu)) end end - end end diff --git a/bosh-stemcell/spec/stemcells/go_agent_spec.rb b/bosh-stemcell/spec/stemcells/go_agent_spec.rb index 29e05bcf4e..4cc6762f4f 100644 --- a/bosh-stemcell/spec/stemcells/go_agent_spec.rb +++ b/bosh-stemcell/spec/stemcells/go_agent_spec.rb @@ -1,85 +1,84 @@ -require 'spec_helper' +require "spec_helper" -describe 'Stemcell with Go Agent', stemcell_image: true do - describe 'installed by bosh_go_agent' do - %w(bosh-agent bosh-agent-rc bosh-blobstore-dav bosh-blobstore-gcs bosh-blobstore-s3 bosh-blobstore-azure-storage).each do |binary| +describe "Stemcell with Go Agent", stemcell_image: true do + describe "installed by bosh_go_agent" do + %w[bosh-agent bosh-agent-rc bosh-blobstore-dav bosh-blobstore-gcs bosh-blobstore-s3 bosh-blobstore-azure-storage].each do |binary| describe file("/var/vcap/bosh/bin/#{binary}") do it { should be_file } it { should be_executable } end end - describe file('/var/vcap/bosh/agent.json') do + describe file("/var/vcap/bosh/agent.json") do it { should be_valid_json_file } end - describe 'set user/group owner and permission on /etc/crontab (CIS-9.1.2)' do - context file('/etc/crontab') do - it { should be_mode(0600) } - it { should be_owned_by('root') } - its(:group) { should eq('root') } + describe "set user/group owner and permission on /etc/crontab (CIS-9.1.2)" do + context file("/etc/crontab") do + it { should be_mode(0o600) } + it { should be_owned_by("root") } + its(:group) { should eq("root") } end end - describe 'set user/group owner and permission on /etc/cron.hourly (CIS-9.1.3)' do - context file('/etc/cron.hourly') do + describe "set user/group owner and permission on /etc/cron.hourly (CIS-9.1.3)" do + context file("/etc/cron.hourly") do it { should be_directory } - it { should be_mode(0700) } - it { should be_owned_by('root') } - its(:group) { should eq('root') } + it { should be_mode(0o700) } + it { should be_owned_by("root") } + its(:group) { should eq("root") } end end - describe 'set user/group owner and permission on /etc/cron.daily (CIS-9.1.4)' do - context file('/etc/cron.daily') do + describe "set user/group owner and permission on /etc/cron.daily (CIS-9.1.4)" do + context file("/etc/cron.daily") do it { should be_directory } - it { should be_mode(0700) } - it { should be_owned_by('root') } - its(:group) { should eq('root') } + it { should be_mode(0o700) } + it { should be_owned_by("root") } + its(:group) { should eq("root") } end end - describe 'set user/group owner and permission on /etc/cron.weekly (CIS-9.1.5)' do - context file('/etc/cron.weekly') do + describe "set user/group owner and permission on /etc/cron.weekly (CIS-9.1.5)" do + context file("/etc/cron.weekly") do it { should be_directory } - it { should be_mode(0700) } - it { should be_owned_by('root') } - its(:group) { should eq('root') } + it { should be_mode(0o700) } + it { should be_owned_by("root") } + its(:group) { should eq("root") } end end - describe 'set user/group owner and permission on /etc/cron.monthly (CIS-9.1.6)' do - context file('/etc/cron.monthly') do + describe "set user/group owner and permission on /etc/cron.monthly (CIS-9.1.6)" do + context file("/etc/cron.monthly") do it { should be_directory } - it { should be_mode(0700) } - it { should be_owned_by('root') } - its(:group) { should eq('root') } + it { should be_mode(0o700) } + it { should be_owned_by("root") } + its(:group) { should eq("root") } end end - describe 'set user/group owner and permission on /etc/cron.d (CIS-9.1.7)' do - context file('/etc/cron.d') do + describe "set user/group owner and permission on /etc/cron.d (CIS-9.1.7)" do + context file("/etc/cron.d") do it { should be_directory } - it { should be_mode(0700) } - it { should be_owned_by('root') } - its(:group) { should eq('root') } + it { should be_mode(0o700) } + it { should be_owned_by("root") } + its(:group) { should eq("root") } end end - describe 'restrict at/cron to authorized users (CIS-9.1.8)' do - context file('/etc/cron.deny') do + describe "restrict at/cron to authorized users (CIS-9.1.8)" do + context file("/etc/cron.deny") do it { should_not be_file } end - context file('/etc/at.deny') do + context file("/etc/at.deny") do it { should_not be_file } end { - '/etc/cron.allow' => { mode: 0600, owner: 'root', group: 'root' }, - '/etc/at.allow' => { mode: 0600, owner: 'root', group: 'root' }, + "/etc/cron.allow" => {mode: 0o600, owner: "root", group: "root"}, + "/etc/at.allow" => {mode: 0o600, owner: "root", group: "root"} }.each do |file_name, properties| - context file(file_name) do it { should be_mode(properties[:mode]) } it { should be_owned_by(properties[:owner]) } @@ -88,40 +87,40 @@ end end - describe '/var/lock' do + describe "/var/lock" do subject do output = command("stat -L -c %#{operator} /var/lock") output.stdout.split.first end - describe 'owned by' do - let(:operator) { 'U' } - it { should eq('root') } + describe "owned by" do + let(:operator) { "U" } + it { should eq("root") } end - describe 'mode' do - let(:operator) { 'a' } - it { should eq('770') } + describe "mode" do + let(:operator) { "a" } + it { should eq("770") } end - describe 'grouped into' do - let(:operator) { 'G' } - it { should eq('vcap') } + describe "grouped into" do + let(:operator) { "G" } + it { should eq("vcap") } end end - %w(/etc/cron.allow /etc/at.allow).each do |allow_file| + %w[/etc/cron.allow /etc/at.allow].each do |allow_file| describe file(allow_file) do - it('contains exactly vcap') { expect(subject.content).to match(/\Avcap\Z/)} + it("contains exactly vcap") { expect(subject.content).to match(/\Avcap\Z/) } end end - describe file('/var/vcap/data') do + describe file("/var/vcap/data") do it { should_not be_directory } end - describe file('/var/vcap/monit/alerts.monitrc') do - its(:content) { should match('set alert agent@local') } + describe file("/var/vcap/monit/alerts.monitrc") do + its(:content) { should match("set alert agent@local") } end end end diff --git a/bosh-stemcell/spec/stemcells/google_spec.rb b/bosh-stemcell/spec/stemcells/google_spec.rb index 6d519fb5c4..84ea6d2034 100644 --- a/bosh-stemcell/spec/stemcells/google_spec.rb +++ b/bosh-stemcell/spec/stemcells/google_spec.rb @@ -1,95 +1,85 @@ -require 'spec_helper' +require "spec_helper" -describe 'Google Stemcell', stemcell_image: true do - it_behaves_like 'udf module is disabled' - - context 'rsyslog conf directory only contains files installed by rsyslog_config stage and google-compute-engine package' do - describe command('ls -A /etc/rsyslog.d') do - it 'match expected list of rsyslog configs' do - expected_rsyslog_confs = %w(50-default.conf 90-bosh-agent.conf 90-google.conf -) +describe "Google Stemcell", stemcell_image: true do + it_behaves_like "udf module is disabled" + context "rsyslog conf directory only contains files installed by rsyslog_config stage and google-compute-engine package" do + describe command("ls -A /etc/rsyslog.d") do + it "match expected list of rsyslog configs" do + expected_rsyslog_confs = %w[50-default.conf 90-bosh-agent.conf 90-google.conf] expect(subject.stdout.split("\n")).to match_array(expected_rsyslog_confs) end end end - context 'installed by system_parameters' do - describe file('/var/vcap/bosh/etc/infrastructure') do - its(:content) { should include('google') } + context "installed by system_parameters" do + describe file("/var/vcap/bosh/etc/infrastructure") do + its(:content) { should include("google") } end end - context 'growroot should be disabled by create file' do - describe file('/etc/growroot-disabled') do + context "growroot should be disabled by create file" do + describe file("/etc/growroot-disabled") do it { should be_file } - it { should be_owned_by('root') } - its(:group) { should eq('root') } + it { should be_owned_by("root") } + its(:group) { should eq("root") } end end - context 'installed by base_ssh' do - describe 'disallows password authentication' do - subject { file('/etc/ssh/sshd_config') } + context "installed by base_ssh" do + describe "disallows password authentication" do + subject { file("/etc/ssh/sshd_config") } - its(:content) { should match /^PasswordAuthentication no$/ } + its(:content) { should match(/^PasswordAuthentication no$/) } end end - context 'installed by system_google_packages' do - describe 'Google agent has configuration file' do - subject { file('/etc/default/instance_configs.cfg.template') } + context "installed by system_google_packages" do + describe "Google agent has configuration file" do + subject { file("/etc/default/instance_configs.cfg.template") } it { should be_file } - it { should be_owned_by('root') } - its(:group) { should eq('root') } + it { should be_owned_by("root") } + its(:group) { should eq("root") } end usrbin = [ - '/usr/bin/google_authorized_keys', - '/usr/bin/google_guest_agent', - '/usr/bin/google_metadata_script_runner', - '/usr/bin/google_optimize_local_ssd', - '/usr/bin/google_oslogin_nss_cache', - '/usr/bin/google_set_hostname', - '/usr/bin/google_set_multiqueue' - ] - - upstart_configs = [ - '/etc/init/google-accounts-daemon.conf', - '/etc/init/google-clock-skew-daemon.conf', - '/etc/init/google-instance-setup.conf', - '/etc/init/google-shutdown-scripts.conf', - '/etc/init/google-startup-scripts.conf' + "/usr/bin/google_authorized_keys", + "/usr/bin/google_guest_agent", + "/usr/bin/google_metadata_script_runner", + "/usr/bin/google_optimize_local_ssd", + "/usr/bin/google_oslogin_nss_cache", + "/usr/bin/google_set_hostname", + "/usr/bin/google_set_multiqueue" ] systemd_configs = [ - '{lib_path}/systemd/system-preset/90-google-compute-engine-oslogin.preset', - '{lib_path}/systemd/system/google-guest-agent.service', - '{lib_path}/systemd/system/google-oslogin-cache.service', - '{lib_path}/systemd/system/google-oslogin-cache.timer', - '{lib_path}/systemd/system/google-shutdown-scripts.service', - '{lib_path}/systemd/system/google-startup-scripts.service' + "{lib_path}/systemd/system-preset/90-google-compute-engine-oslogin.preset", + "{lib_path}/systemd/system/google-guest-agent.service", + "{lib_path}/systemd/system/google-oslogin-cache.service", + "{lib_path}/systemd/system/google-oslogin-cache.timer", + "{lib_path}/systemd/system/google-shutdown-scripts.service", + "{lib_path}/systemd/system/google-startup-scripts.service" ] configs = usrbin - configs += if ENV['OS_NAME'] == 'ubuntu' - systemd_configs.map do |config| - config.gsub('{lib_path}', '/lib') - end - else - systemd_configs.map do |config| - config.gsub('{lib_path}', '/usr/lib') - end - end + configs += if ENV["OS_NAME"] == "ubuntu" + systemd_configs.map do |config| + config.gsub("{lib_path}", "/lib") + end + else + systemd_configs.map do |config| + config.gsub("{lib_path}", "/usr/lib") + end + end configs.each do |conf_file| describe file(conf_file) do it { should be_file } - it { should be_owned_by('root') } - its(:group) { should eq('root') } + it { should be_owned_by("root") } + its(:group) { should eq("root") } end end end diff --git a/bosh-stemcell/spec/stemcells/openstack_spec.rb b/bosh-stemcell/spec/stemcells/openstack_spec.rb index 1ada40d900..b2396dabd5 100644 --- a/bosh-stemcell/spec/stemcells/openstack_spec.rb +++ b/bosh-stemcell/spec/stemcells/openstack_spec.rb @@ -1,21 +1,21 @@ -require 'spec_helper' +require "spec_helper" -describe 'OpenStack Stemcell', stemcell_image: true do - it_behaves_like 'udf module is disabled' +describe "OpenStack Stemcell", stemcell_image: true do + it_behaves_like "udf module is disabled" - context 'installed by system_parameters' do - describe file('/var/vcap/bosh/etc/infrastructure') do - its(:content) { should include('openstack') } + context "installed by system_parameters" do + describe file("/var/vcap/bosh/etc/infrastructure") do + its(:content) { should include("openstack") } end end - context 'installed by package_qcow2_image stage' do - describe 'converts to qcow2 0.10 compat' do + context "installed by package_qcow2_image stage" do + describe "converts to qcow2 0.10 compat" do # environment is cleaned up inside rspec context - stemcell_image = ENV['STEMCELL_IMAGE'] + stemcell_image = ENV["STEMCELL_IMAGE"] subject do - cmd = "qemu-img info #{File.join(File.dirname(stemcell_image), 'root.qcow2')}" + cmd = "qemu-img info #{File.join(File.dirname(stemcell_image), "root.qcow2")}" `#{cmd}` end @@ -23,11 +23,11 @@ end end - context 'installed by base_ssh' do - describe 'disallows password authentication' do - subject { file('/etc/ssh/sshd_config') } + context "installed by base_ssh" do + describe "disallows password authentication" do + subject { file("/etc/ssh/sshd_config") } - its(:content) { should match /^PasswordAuthentication no$/ } + its(:content) { should match(/^PasswordAuthentication no$/) } end end end diff --git a/bosh-stemcell/spec/stemcells/stig_spec.rb b/bosh-stemcell/spec/stemcells/stig_spec.rb index 95ceab4f36..5756e630ad 100644 --- a/bosh-stemcell/spec/stemcells/stig_spec.rb +++ b/bosh-stemcell/spec/stemcells/stig_spec.rb @@ -1,7 +1,7 @@ -require 'spec_helper' +require "spec_helper" -describe 'Stig test case verification', stemcell_image: true, security_spec: true do - it 'confirms all stig test cases ran' do +describe "Stig test case verification", stemcell_image: true, security_spec: true do + it "confirms all stig test cases ran" do expected_base_stig_test_cases = %w[ V-38443 V-38445 @@ -135,13 +135,13 @@ ] expected_stig_test_cases = expected_base_stig_test_cases - case ENV['OS_NAME'] - when 'ubuntu' + case ENV["OS_NAME"] + when "ubuntu" expected_stig_test_cases = expected_base_stig_test_cases + [ - 'V-38668' + "V-38668" ] end - expect($stig_test_cases.to_a).to match_array expected_stig_test_cases + expect($stig_test_cases.to_a).to match_array expected_stig_test_cases # standard:disable Style/GlobalVars end end diff --git a/bosh-stemcell/spec/stemcells/ubuntu_spec.rb b/bosh-stemcell/spec/stemcells/ubuntu_spec.rb index 9f7d58de2d..dd705c9cc7 100644 --- a/bosh-stemcell/spec/stemcells/ubuntu_spec.rb +++ b/bosh-stemcell/spec/stemcells/ubuntu_spec.rb @@ -1,50 +1,50 @@ -require 'spec_helper' +require "spec_helper" -describe 'Ubuntu 24.04 stemcell image', stemcell_image: true do - it_behaves_like 'All Stemcells' - it_behaves_like 'a Linux kernel based OS image' - it_behaves_like 'a Linux kernel module configured OS image' +describe "Ubuntu 24.04 stemcell image", stemcell_image: true do + it_behaves_like "All Stemcells" + it_behaves_like "a Linux kernel based OS image" + it_behaves_like "a Linux kernel module configured OS image" # linux_version_regex = '/linux-(.+)-([0-9]+.+)/d' linux_version_regex = 's/linux-(.+)-([0-9]+).([0-9]+).([0-9]+)-([0-9]+)/linux-\1-\2.\3/' - context 'installed by image_install_grub', { + context "installed by image_install_grub", { exclude_on_vsphere: true, exclude_on_google: true, exclude_on_aws: true, exclude_on_azure: true, exclude_on_openstack: true, exclude_on_alicloud: true, - exclude_on_warden: true, + exclude_on_warden: true } do - context 'for cloudstack infrastructure and xen hypervisor', { + context "for cloudstack infrastructure and xen hypervisor", { exclude_on_alicloud: true, exclude_on_warden: true, exclude_on_azure: true, - exclude_on_openstack: true, + exclude_on_openstack: true } do describe file(grub_cfg_path) do - its(:content) { should match ' console=hvc0' } + its(:content) { should match " console=hvc0" } end end describe file(grub_cfg_path) do it { should be_file } its(:content) { should match 'set default="0"' } its(:content) { should match(/^set root=\(hd0,0\)$/) } - its(:content) { should match ' selinux=0' } - its(:content) { should match ' cgroup_enable=memory swapaccount=1' } - its(:content) { should match ' console=ttyS0,115200n8' } - its(:content) { should match ' earlyprintk=ttyS0 rootdelay=300' } - its(:content) { should match ' apparmor=1 security=apparmor' } + its(:content) { should match " selinux=0" } + its(:content) { should match " cgroup_enable=memory swapaccount=1" } + its(:content) { should match " console=ttyS0,115200n8" } + its(:content) { should match " earlyprintk=ttyS0 rootdelay=300" } + its(:content) { should match " apparmor=1 security=apparmor" } - it('should set the grub menu password (stig: V-38585)') { expect(subject.content).to match /password_pbkdf2 vcap/ } - it('should be of mode 600 (stig: V-38583)') { expect(subject).to be_mode(0600) } - it('should be owned by root (stig: V-38579)') { expect(subject).to be_owned_by('root') } - it('should be grouped into root (stig: V-38581)') { expect(subject.group).to eq('root') } - it('audits processes that start prior to auditd (CIS-8.1.3)') { expect(subject.content).to match ' audit=1' } + it("should set the grub menu password (stig: V-38585)") { expect(subject.content).to match(/password_pbkdf2 vcap/) } + it("should be of mode 600 (stig: V-38583)") { expect(subject).to be_mode(0o600) } + it("should be owned by root (stig: V-38579)") { expect(subject).to be_owned_by("root") } + it("should be grouped into root (stig: V-38581)") { expect(subject.group).to eq("root") } + it("audits processes that start prior to auditd (CIS-8.1.3)") { expect(subject.content).to match " audit=1" } end - context 'for default kernel', exclude_on_fips: true do + context "for default kernel", exclude_on_fips: true do describe file(grub_cfg_path) do it { should be_file } its(:content) { should match %r{linux\t/boot/vmlinuz-\S+-generic root=UUID=\S* ro } } @@ -52,239 +52,238 @@ end end - describe file('/boot/grub/menu.lst') do + describe file("/boot/grub/menu.lst") do before { skip 'until alicloud/aws/openstack stop clobbering the symlink with "update-grub"' } - it { should be_linked_to('./grub.cfg') } + it { should be_linked_to("./grub.cfg") } end end - context 'installed by image_install_grub' do - describe file('/boot/efi/EFI/grub/grub.cfg') do + context "installed by image_install_grub" do + describe file("/boot/efi/EFI/grub/grub.cfg") do it { should be_file } its(:content) { should match 'set default="0"' } - its(:content) { should match ' selinux=0' } - its(:content) { should match ' cgroup_enable=memory swapaccount=1' } - its(:content) { should match ' console=ttyS0,115200n8' } - its(:content) { should match ' earlyprintk=ttyS0 rootdelay=300' } - its(:content) { should match ' apparmor=1 security=apparmor' } + its(:content) { should match " selinux=0" } + its(:content) { should match " cgroup_enable=memory swapaccount=1" } + its(:content) { should match " console=ttyS0,115200n8" } + its(:content) { should match " earlyprintk=ttyS0 rootdelay=300" } + its(:content) { should match " apparmor=1 security=apparmor" } - it('should set the grub menu password (stig: V-38585)') { expect(subject.content).to match /password_pbkdf2 vcap/ } - it('should be of mode 600 (stig: V-38583)') { expect(subject).to be_mode(0600) } - it('should be owned by root (stig: V-38579)') { expect(subject).to be_owned_by('root') } - it('should be grouped into root (stig: V-38581)') { expect(subject.group).to eq('root') } - it('audits processes that start prior to auditd (CIS-8.1.3)') { expect(subject.content).to match ' audit=1' } + it("should set the grub menu password (stig: V-38585)") { expect(subject.content).to match(/password_pbkdf2 vcap/) } + it("should be of mode 600 (stig: V-38583)") { expect(subject).to be_mode(0o600) } + it("should be owned by root (stig: V-38579)") { expect(subject).to be_owned_by("root") } + it("should be grouped into root (stig: V-38581)") { expect(subject.group).to eq("root") } + it("audits processes that start prior to auditd (CIS-8.1.3)") { expect(subject.content).to match " audit=1" } end - context 'for default kernel', exclude_on_fips: true do - describe file('/boot/efi/EFI/grub/grub.cfg') do + context "for default kernel", exclude_on_fips: true do + describe file("/boot/efi/EFI/grub/grub.cfg") do it { should be_file } its(:content) { should match %r{linux\t/boot/vmlinuz-\S+-generic root=UUID=\S* ro } } its(:content) { should match %r{initrd\t/boot/initrd.img-\S+-generic} } end end - describe file('/boot/grub/menu.lst') do + describe file("/boot/grub/menu.lst") do before { skip 'until alicloud/aws/openstack stop clobbering the symlink with "update-grub"' } - it { should be_linked_to('./grub.cfg') } + it { should be_linked_to("./grub.cfg") } end end - context 'installed by system_parameters' do - describe file('/var/vcap/bosh/etc/operating_system') do - its(:content) { should match('ubuntu') } + context "installed by system_parameters" do + describe file("/var/vcap/bosh/etc/operating_system") do + its(:content) { should match("ubuntu") } end end - context 'installed by dev_tools_config' do - describe file('/var/vcap/bosh/etc/dev_tools_file_list') do - its(:content) { should match('/usr/bin/gcc') } + context "installed by dev_tools_config" do + describe file("/var/vcap/bosh/etc/dev_tools_file_list") do + its(:content) { should match("/usr/bin/gcc") } end end - context 'static libraries to remove' do - describe file('/var/vcap/bosh/etc/static_libraries_list') do + context "static libraries to remove" do + describe file("/var/vcap/bosh/etc/static_libraries_list") do it { should be_file } - it 'should be a proper superset of the installed static libraries' do + it "should be a proper superset of the installed static libraries" do libraries_to_remove = subject.content.split("\n") - found_libraries = command('find / -iname "*.a" | sort | uniq' ).stdout.split("\n") + found_libraries = command('find / -iname "*.a" | sort | uniq').stdout.split("\n") expect(libraries_to_remove).to include(*found_libraries) end end end - context 'modified by base_file_permissions' do - describe 'disallow unsafe setuid binaries' do - subject { command('find -L / -xdev -perm /ug=s -type f') } + context "modified by base_file_permissions" do + describe "disallow unsafe setuid binaries" do + subject { command("find -L / -xdev -perm /ug=s -type f") } - it ('includes the correct binaries') do + it("includes the correct binaries") do # expect(subject.stdout.split).to match_array(%w(/bin/su /usr/bin/sudo /usr/bin/sudoedit)) - expect(subject.stdout.split).to match_array(%w(/bin/su /bin/sudo /bin/sudoedit /usr/bin/su /usr/bin/sudo /usr/bin/sudoedit)) - + expect(subject.stdout.split).to match_array(%w[/bin/su /bin/sudo /bin/sudoedit /usr/bin/su /usr/bin/sudo /usr/bin/sudoedit]) end end end - context 'installed by system-network', { + context "installed by system-network", { exclude_on_warden: true } do - describe file('/etc/hostname') do + describe file("/etc/hostname") do it { should be_file } - its (:content) { should eq('bosh-stemcell') } + its(:content) { should eq("bosh-stemcell") } end end - context 'installed by system-network on some IaaSes', { + context "installed by system-network on some IaaSes", { exclude_on_vsphere: true, exclude_on_warden: true, - exclude_on_azure: true, + exclude_on_azure: true } do - describe file('/etc/network/interfaces') do + describe file("/etc/network/interfaces") do it { should be_file } - its(:content) { should match 'auto lo' } - its(:content) { should match 'iface lo inet loopback' } + its(:content) { should match "auto lo" } + its(:content) { should match "iface lo inet loopback" } end end - context 'installed by system-azure-network', { + context "installed by system-azure-network", { exclude_on_alicloud: true, exclude_on_aws: true, exclude_on_cloudstack: true, exclude_on_google: true, exclude_on_vsphere: true, exclude_on_warden: true, - exclude_on_openstack: true, + exclude_on_openstack: true } do - describe file('/etc/network/interfaces') do + describe file("/etc/network/interfaces") do it { should be_file } - its(:content) { should match 'auto eth0' } - its(:content) { should match 'iface eth0 inet dhcp' } + its(:content) { should match "auto eth0" } + its(:content) { should match "iface eth0 inet dhcp" } end end - context 'installed by system_open_vm_tools', { + context "installed by system_open_vm_tools", { exclude_on_alicloud: true, exclude_on_aws: true, exclude_on_cloudstack: true, exclude_on_google: true, exclude_on_warden: true, exclude_on_openstack: true, - exclude_on_azure: true, + exclude_on_azure: true } do - describe package('open-vm-tools') do + describe package("open-vm-tools") do it { should be_installed } end - describe file('/etc/vmware-tools/tools.conf') do + describe file("/etc/vmware-tools/tools.conf") do it { should be_file } its(:content) { should match '\[guestinfo\]' } its(:content) { should match 'exclude-nics=veth\*,docker\*,virbr\*,silk-vtep,s-\*,ovs\*,erspan\*,nsx-container,antrea\*,\?\?\?\?\?\?\?\?\?\?\?\?\?\?\?' } end end - context 'installed by image_vsphere_cdrom stage', { + context "installed by image_vsphere_cdrom stage", { exclude_on_alicloud: true, exclude_on_aws: true, exclude_on_cloudstack: true, exclude_on_google: true, exclude_on_warden: true, exclude_on_openstack: true, - exclude_on_azure: true, + exclude_on_azure: true } do - describe file('/etc/udev/rules.d/60-cdrom_id.rules') do + describe file("/etc/udev/rules.d/60-cdrom_id.rules") do it { should be_file } - its(:content) { should eql(< e - @error = e - false - end + @content = file.content + JSON.parse(@content) + true + rescue JSON::ParserError => e + @error = e + false end failure_message do diff --git a/bosh-stemcell/spec/support/cis.rb b/bosh-stemcell/spec/support/cis.rb index 0ba8336e67..b7fa04fbd2 100644 --- a/bosh-stemcell/spec/support/cis.rb +++ b/bosh-stemcell/spec/support/cis.rb @@ -1,11 +1,9 @@ -require 'set' - -$cis_test_cases = Set.new +$cis_test_cases = Set.new # standard:disable Style/GlobalVars RSpec.configure do |config| config.before(:each) do |example| if example.full_description.include? "CIS-" - $cis_test_cases += example.full_description.scan /CIS-(?:\d+\.?)+/ + $cis_test_cases += example.full_description.scan(/CIS-(?:\d+\.?)+/) # standard:disable Style/GlobalVars end end end diff --git a/bosh-stemcell/spec/support/os_image.rb b/bosh-stemcell/spec/support/os_image.rb index e44ddb1047..fafe2de0fe 100644 --- a/bosh-stemcell/spec/support/os_image.rb +++ b/bosh-stemcell/spec/support/os_image.rb @@ -1,32 +1,30 @@ -require 'rspec/core/formatters/console_codes' -require 'shellout_types/chroot' -require_relative 'shellout_type_assertions' +require "rspec/core/formatters/console_codes" +require "shellout_types/chroot" +require_relative "shellout_type_assertions" RSpec.configure do |config| # shellout types tests support env variable 'OS_IMAGE', therefore check that os image tests # will not be executed when testing shellout types. unless config.inclusion_filter[:shellout_types] - if ENV['OS_IMAGE'] + if ENV["OS_IMAGE"] config.filter_run_including os_image: true - @os_image_dir = Dir.mktmpdir('os-image-rspec') + @os_image_dir = Dir.mktmpdir("os-image-rspec") ShelloutTypes::Chroot.chroot_dir = @os_image_dir config.add_setting(:os_image_dir, default: @os_image_dir) config.before(:suite) do - Bosh::Core::Shell.new.run("sudo tar xf #{ENV['OS_IMAGE']} -C #{config.os_image_dir}") + Bosh::Core::Shell.new.run("sudo tar xf #{ENV["OS_IMAGE"]} -C #{config.os_image_dir}") end config.after(:suite) do ShelloutTypes::Chroot.unmount_proc Bosh::Core::Shell.new.run("sudo rm -rf #{config.os_image_dir}") end - else + elsif ENV["STEMCELL_IMAGE"] # when running stemcell testings, we need also run the os image testings again - if ENV['STEMCELL_IMAGE'] - config.filter_run_including os_image: true - else - warning = 'Both ENV["OS_IMAGE"] and ENV["STEMCELL_IMAGE"] are not set, os_image test cases are being skipped.' - puts RSpec::Core::Formatters::ConsoleCodes.wrap(warning, :yellow) - end + config.filter_run_including os_image: true + else + warning = 'Both ENV["OS_IMAGE"] and ENV["STEMCELL_IMAGE"] are not set, os_image test cases are being skipped.' + puts RSpec::Core::Formatters::ConsoleCodes.wrap(warning, :yellow) end end # explicitly disable os image tests when running 'bundle exec rspec spec/' for diff --git a/bosh-stemcell/spec/support/os_image_chrony_shared_examples.rb b/bosh-stemcell/spec/support/os_image_chrony_shared_examples.rb index 40551e43ff..4d96b868b0 100644 --- a/bosh-stemcell/spec/support/os_image_chrony_shared_examples.rb +++ b/bosh-stemcell/spec/support/os_image_chrony_shared_examples.rb @@ -1,12 +1,12 @@ -shared_examples_for 'an os with chrony' do - describe '(stig: V-38620 V-38621)' do - describe file('/var/vcap/bosh/bin/sync-time') do +shared_examples_for "an os with chrony" do + describe "(stig: V-38620 V-38621)" do + describe file("/var/vcap/bosh/bin/sync-time") do it { should be_file } its(:content) { should match(/chronyc reload sources/) } its(:content) { should match(/chronyc waitsync 10/) } end - describe file('/etc/chrony/chrony.conf') do + describe file("/etc/chrony/chrony.conf") do it { should be_file } its(:content) { should match(/makestep 1 3/) } end diff --git a/bosh-stemcell/spec/support/os_image_linux_kernel_modules_shared_examples.rb b/bosh-stemcell/spec/support/os_image_linux_kernel_modules_shared_examples.rb index a82f7598f2..b146558e6c 100644 --- a/bosh-stemcell/spec/support/os_image_linux_kernel_modules_shared_examples.rb +++ b/bosh-stemcell/spec/support/os_image_linux_kernel_modules_shared_examples.rb @@ -1,87 +1,86 @@ -shared_examples_for 'a Linux kernel module configured OS image' do - context 'prevent bluetooth module from being loaded (stig: V-38682)' do - describe file('/etc/modprobe.d/blacklist.conf') do +shared_examples_for "a Linux kernel module configured OS image" do + context "prevent bluetooth module from being loaded (stig: V-38682)" do + describe file("/etc/modprobe.d/blacklist.conf") do it { should be_file } - its(:content) { should match 'install bluetooth /bin/true' } + its(:content) { should match "install bluetooth /bin/true" } end end - context 'prevent tipc module from being loaded (stig: V-38517)' do - describe file('/etc/modprobe.d/blacklist.conf') do - its(:content) { should match 'install tipc /bin/true' } + context "prevent tipc module from being loaded (stig: V-38517)" do + describe file("/etc/modprobe.d/blacklist.conf") do + its(:content) { should match "install tipc /bin/true" } end end - context 'prevent sctp module from being loaded (stig: V-38515)' do - describe file('/etc/modprobe.d/blacklist.conf') do - its(:content) { should match 'install sctp /bin/true' } + context "prevent sctp module from being loaded (stig: V-38515)" do + describe file("/etc/modprobe.d/blacklist.conf") do + its(:content) { should match "install sctp /bin/true" } end end - context 'prevent dccp module from being loaded (stig: V-38514)' do - describe file('/etc/modprobe.d/blacklist.conf') do - its(:content) { should match 'install dccp /bin/true' } + context "prevent dccp module from being loaded (stig: V-38514)" do + describe file("/etc/modprobe.d/blacklist.conf") do + its(:content) { should match "install dccp /bin/true" } end end - context 'prevent bluetooth service from being enabled (stig: V-38691)' do - describe service('bluetooth') do + context "prevent bluetooth service from being enabled (stig: V-38691)" do + describe service("bluetooth") do it { should_not be_enabled } end end - context 'prevent USB module from being loaded (stig: V-38490)' do - describe file('/etc/modprobe.d/blacklist.conf') do - its(:content) { should match 'install usb-storage /bin/true' } + context "prevent USB module from being loaded (stig: V-38490)" do + describe file("/etc/modprobe.d/blacklist.conf") do + its(:content) { should match "install usb-storage /bin/true" } end end - - context 'prevent cramfs module from being loaded (CIS-2.18)' do - describe file('/etc/modprobe.d/blacklist.conf') do - its(:content) { should match 'install cramfs /bin/true' } + context "prevent cramfs module from being loaded (CIS-2.18)" do + describe file("/etc/modprobe.d/blacklist.conf") do + its(:content) { should match "install cramfs /bin/true" } end end - context 'prevent freevxfs module from being loaded (CIS-2.19)' do - describe file('/etc/modprobe.d/blacklist.conf') do - its(:content) { should match 'install freevxfs /bin/true' } + context "prevent freevxfs module from being loaded (CIS-2.19)" do + describe file("/etc/modprobe.d/blacklist.conf") do + its(:content) { should match "install freevxfs /bin/true" } end end - context 'prevent jffs2 module from being loaded (CIS-2.20)' do - describe file('/etc/modprobe.d/blacklist.conf') do - its(:content) { should match 'install jffs2 /bin/true' } + context "prevent jffs2 module from being loaded (CIS-2.20)" do + describe file("/etc/modprobe.d/blacklist.conf") do + its(:content) { should match "install jffs2 /bin/true" } end end - context 'prevent hfs module from being loaded (CIS-2.21)' do - describe file('/etc/modprobe.d/blacklist.conf') do - its(:content) { should match 'install hfs /bin/true' } + context "prevent hfs module from being loaded (CIS-2.21)" do + describe file("/etc/modprobe.d/blacklist.conf") do + its(:content) { should match "install hfs /bin/true" } end end - context 'prevent hfsplus module from being loaded (CIS-2.22)' do - describe file('/etc/modprobe.d/blacklist.conf') do - its(:content) { should match 'install hfsplus /bin/true' } + context "prevent hfsplus module from being loaded (CIS-2.22)" do + describe file("/etc/modprobe.d/blacklist.conf") do + its(:content) { should match "install hfsplus /bin/true" } end end - context 'prevent squashfs module from being loaded (CIS-2.23)' do - describe file('/etc/modprobe.d/blacklist.conf') do - its(:content) { should match 'install squashfs /bin/true' } + context "prevent squashfs module from being loaded (CIS-2.23)" do + describe file("/etc/modprobe.d/blacklist.conf") do + its(:content) { should match "install squashfs /bin/true" } end end - context 'disable RDS (CIS-7.5.3)' do - describe file('/etc/modprobe.d/blacklist.conf') do - its(:content) { should match 'install rds /bin/true' } + context "disable RDS (CIS-7.5.3)" do + describe file("/etc/modprobe.d/blacklist.conf") do + its(:content) { should match "install rds /bin/true" } end end - context 'prevent floppy module from being loaded' do - describe file('/etc/modprobe.d/blacklist.conf') do - its(:content) { should match 'install floppy /bin/true' } + context "prevent floppy module from being loaded" do + describe file("/etc/modprobe.d/blacklist.conf") do + its(:content) { should match "install floppy /bin/true" } end end end diff --git a/bosh-stemcell/spec/support/os_image_linux_kernel_shared_examples.rb b/bosh-stemcell/spec/support/os_image_linux_kernel_shared_examples.rb index ab54de9b2a..92f6e731dc 100644 --- a/bosh-stemcell/spec/support/os_image_linux_kernel_shared_examples.rb +++ b/bosh-stemcell/spec/support/os_image_linux_kernel_shared_examples.rb @@ -1,81 +1,78 @@ -shared_examples_for 'a Linux kernel based OS image' do - +shared_examples_for "a Linux kernel based OS image" do def kernel_version - command('ls -rt /lib/modules | tail -1').stdout.chomp + command("ls -rt /lib/modules | tail -1").stdout.chomp end - context 'installed by bosh_sysctl' do - describe file('/etc/sysctl.d/60-bosh-sysctl.conf') do + context "installed by bosh_sysctl" do + describe file("/etc/sysctl.d/60-bosh-sysctl.conf") do it { should be_file } - it 'must not accept ICMPv4 secure redirect packets on any interface (stig: V-38526)' do - expect(subject.content).to match /^net.ipv4.conf.all.secure_redirects=0$/ + it "must not accept ICMPv4 secure redirect packets on any interface (stig: V-38526)" do + expect(subject.content).to match(/^net.ipv4.conf.all.secure_redirects=0$/) end - it 'must not accept ICMPv4 redirect packets on any interface (stig: V-38524)' do - expect(subject.content).to match /^net.ipv4.conf.all.accept_redirects=0$/ + it "must not accept ICMPv4 redirect packets on any interface (stig: V-38524)" do + expect(subject.content).to match(/^net.ipv4.conf.all.accept_redirects=0$/) end - it 'must not accept IPv4 source-routed packets by default (stig: V-38529)' do - expect(subject.content).to match /^net.ipv4.conf.default.accept_source_route=0$/ + it "must not accept IPv4 source-routed packets by default (stig: V-38529)" do + expect(subject.content).to match(/^net.ipv4.conf.default.accept_source_route=0$/) end - it 'must not accept IPv4 source-routed packets on any interface (stig: V-38523)' do - expect(subject.content).to match /^net.ipv4.conf.all.accept_source_route=0$/ + it "must not accept IPv4 source-routed packets on any interface (stig: V-38523)" do + expect(subject.content).to match(/^net.ipv4.conf.all.accept_source_route=0$/) end - - it 'must not accept ICMPv4 secure redirect packets by default (stig: V-38532)' do - expect(subject.content).to match /^net.ipv4.conf.default.secure_redirects=0$/ + it "must not accept ICMPv4 secure redirect packets by default (stig: V-38532)" do + expect(subject.content).to match(/^net.ipv4.conf.default.secure_redirects=0$/) end - it 'must not send ICMPv4 redirects by default (stig: V-38600)' do - expect(subject.content).to match /^net.ipv4.conf.default.send_redirects=0$/ + it "must not send ICMPv4 redirects by default (stig: V-38600)" do + expect(subject.content).to match(/^net.ipv4.conf.default.send_redirects=0$/) end - it 'must not send ICMPv4 redirects from any interface. (stig: V-38601)' do - expect(subject.content).to match /^net.ipv4.conf.all.send_redirects=0$/ + it "must not send ICMPv4 redirects from any interface. (stig: V-38601)" do + expect(subject.content).to match(/^net.ipv4.conf.all.send_redirects=0$/) end - it 'must use reverse path filtering for IPv4 network traffic on all interfaces. (stig: V-38542) (CIS-7.2.7)' do - expect(subject.content).to match /^net.ipv4.conf.all.rp_filter=1$/ + it "must use reverse path filtering for IPv4 network traffic on all interfaces. (stig: V-38542) (CIS-7.2.7)" do + expect(subject.content).to match(/^net.ipv4.conf.all.rp_filter=1$/) end - it 'must use reverse path filtering for IPv4 network traffic by default. (stig: V-38544) (CIS-7.2.7)' do - expect(subject.content).to match /^net.ipv4.conf.default.rp_filter=1$/ + it "must use reverse path filtering for IPv4 network traffic by default. (stig: V-38544) (CIS-7.2.7)" do + expect(subject.content).to match(/^net.ipv4.conf.default.rp_filter=1$/) end - it 'must log suspicious packets on all interfaces (CIS-3.2.4)' do - expect(subject.content).to match /^net.ipv4.conf.all.log_martians=1$/ + it "must log suspicious packets on all interfaces (CIS-3.2.4)" do + expect(subject.content).to match(/^net.ipv4.conf.all.log_martians=1$/) end - it 'must log suspicious packets by default (CIS-3.2.4)' do - expect(subject.content).to match /^net.ipv4.conf.default.log_martians=1$/ + it "must log suspicious packets by default (CIS-3.2.4)" do + expect(subject.content).to match(/^net.ipv4.conf.default.log_martians=1$/) end - - it 'should disable response to broadcast requests (CIS-7.2.5)' do - expect(subject.content).to match /^net.ipv4.icmp_echo_ignore_broadcasts=1$/ + it "should disable response to broadcast requests (CIS-7.2.5)" do + expect(subject.content).to match(/^net.ipv4.icmp_echo_ignore_broadcasts=1$/) end - it 'enables bad error message protection (CIS-7.2.6)' do - expect(subject.content).to match /^net.ipv4.icmp_ignore_bogus_error_responses=1$/ + it "enables bad error message protection (CIS-7.2.6)" do + expect(subject.content).to match(/^net.ipv4.icmp_ignore_bogus_error_responses=1$/) end - it 'sets tcp syncookies' do - expect(subject.content).to match /^net.ipv4.tcp_syncookies=1$/ + it "sets tcp syncookies" do + expect(subject.content).to match(/^net.ipv4.tcp_syncookies=1$/) end - it 'increases tcp_max_syn_backlog to 1280' do - expect(subject.content).to match /^net.ipv4.tcp_max_syn_backlog=1280$/ + it "increases tcp_max_syn_backlog to 1280" do + expect(subject.content).to match(/^net.ipv4.tcp_max_syn_backlog=1280$/) end - it 'should disable core dumps (CIS-4.1)' do - expect(subject.content).to match /^fs.suid_dumpable=0$/ + it "should disable core dumps (CIS-4.1)" do + expect(subject.content).to match(/^fs.suid_dumpable=0$/) end end - describe file('/etc/sysctl.d/60-bosh-sysctl-neigh-fix.conf') do + describe file("/etc/sysctl.d/60-bosh-sysctl-neigh-fix.conf") do it { should be_file } end end diff --git a/bosh-stemcell/spec/support/os_image_shared_examples.rb b/bosh-stemcell/spec/support/os_image_shared_examples.rb index 13d5eb3bd5..d919e57bb5 100644 --- a/bosh-stemcell/spec/support/os_image_shared_examples.rb +++ b/bosh-stemcell/spec/support/os_image_shared_examples.rb @@ -1,108 +1,107 @@ -shared_examples_for 'every OS image' do - let(:sshd_config) { file('/etc/ssh/sshd_config') } - let(:etc_environment) { file('/etc/environment') } - let(:syslog_config) { file('/etc/audisp/plugins.d/syslog.conf') } +shared_examples_for "every OS image" do + let(:sshd_config) { file("/etc/ssh/sshd_config") } + let(:etc_environment) { file("/etc/environment") } + let(:syslog_config) { file("/etc/audisp/plugins.d/syslog.conf") } - context 'etc_environment' do - it 'should have /var/vcap/bosh/bin on the PATH' do + context "etc_environment" do + it "should have /var/vcap/bosh/bin on the PATH" do expect(etc_environment.content).to match( - %r{PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/var/vcap/bosh/bin"}, + %r{PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/var/vcap/bosh/bin"} ) end end - context 'installed by base_' do - describe command('dig -v') do # required by agent - it('has exit status of 0') { expect(subject.exit_status).to eq 0 } + context "installed by base_" do + describe command("dig -v") do # required by agent + it("has exit status of 0") { expect(subject.exit_status).to eq 0 } end - describe command('which crontab') do - it('has exit status of 0') { expect(subject.exit_status).to eq 0 } + describe command("which crontab") do + it("has exit status of 0") { expect(subject.exit_status).to eq 0 } end end - context 'installed by bosh_sudoers' do - describe file('/etc/sudoers') do + context "installed by bosh_sudoers" do + describe file("/etc/sudoers") do it { should be_file } - its(:content) { should match /%bosh_sudoers ALL=\(ALL\) NOPASSWD: ALL/m } - its(:content) { should match '#includedir /etc/sudoers.d' } + its(:content) { should match(/%bosh_sudoers ALL=\(ALL\) NOPASSWD: ALL/m) } + its(:content) { should match "#includedir /etc/sudoers.d" } end end - context 'effective GID for UID vcap' do + context "effective GID for UID vcap" do describe command("id -gn vcap") do - its (:stdout) { should eq "vcap\n" } + its(:stdout) { should eq "vcap\n" } end end - context 'The sudo command must require authentication (stig: V-58901)' do + context "The sudo command must require authentication (stig: V-58901)" do describe command("egrep -sh 'NOPASSWD|!authenticate' /etc/sudoers /etc/sudoers.d/* | egrep -v '^#|%bosh_sudoers\s' --") do - its (:stdout) { should eq('') } + its(:stdout) { should eq("") } end end - context 'installed by bosh_users' do + context "installed by bosh_users" do describe command("grep -q 'export PATH=/var/vcap/bosh/bin:$PATH\n' /root/.bashrc") do - it('has exit status of 0') { expect(subject.exit_status).to eq 0 } + it("has exit status of 0") { expect(subject.exit_status).to eq 0 } end describe command("grep -q 'export PATH=/var/vcap/bosh/bin:$PATH\n' /home/vcap/.bashrc") do - it('has exit status of 0') { expect(subject.exit_status).to eq 0 } + it("has exit status of 0") { expect(subject.exit_status).to eq 0 } end - describe file('/root/.bashrc') do + describe file("/root/.bashrc") do it { should be_file } - its(:content) { should match 'source /etc/profile.d/00-bosh-ps1' } + its(:content) { should match "source /etc/profile.d/00-bosh-ps1" } end - describe file('/home/vcap/.bashrc') do + describe file("/home/vcap/.bashrc") do it { should be_file } - its(:content) { should match 'source /etc/profile.d/00-bosh-ps1' } + its(:content) { should match "source /etc/profile.d/00-bosh-ps1" } end - describe file('/etc/skel/.bashrc') do + describe file("/etc/skel/.bashrc") do it { should be_file } - its(:content) { should match 'source /etc/profile.d/00-bosh-ps1' } + its(:content) { should match "source /etc/profile.d/00-bosh-ps1" } end - describe file('/etc/profile.d/00-bosh-ps1') do + describe file("/etc/profile.d/00-bosh-ps1") do it { should be_file } end - describe command('grep -q .bashrc /root/.profile') do - it('has exit status of 0') { expect(subject.exit_status).to eq 0 } + describe command("grep -q .bashrc /root/.profile") do + it("has exit status of 0") { expect(subject.exit_status).to eq 0 } end - describe command('stat -c %a ~vcap') do - it('includes restrictive permissions') { expect(subject.stdout.strip).to eq('700') } + describe command("stat -c %a ~vcap") do + it("includes restrictive permissions") { expect(subject.stdout.strip).to eq("700") } end - describe user('vcap') do - it { should be_in_group 'bosh_sshers' } + describe user("vcap") do + it { should be_in_group "bosh_sshers" } end end - context '/etc/securetty' do - context 'disallows virtual console access (stig: V-38492)' do + context "/etc/securetty" do + context "disallows virtual console access (stig: V-38492)" do describe command("grep '^vc/[0-9]+' /etc/securetty") do its(:stdout) { should be_empty } end end - context 'restricts root login to system console (CIS-9.4)' do + context "restricts root login to system console (CIS-9.4)" do describe command("awk '$1 !~ /^(console|#.*|\s*)$/ { print; f=1 } END { if (!f) print \"none\" }' /etc/securetty") do its(:stdout) { should eq "none\n" } end end end - # The STIG says to have the log files owned and grouped by 'root'. However, this would mean that # rsyslog would not be able to dropping privileges to another user. Because of this we've decided # it should run as the limited scope user 'syslog' which still prevents 'vcap' from reading the # logs (which is the original intention of the STIG). - context 'all rsyslog-generated log files must be owned by syslog. (stig: V-38519 V-38518 V-38623)' do - it 'secures rsyslog.conf-referenced files correctly' do + context "all rsyslog-generated log files must be owned by syslog. (stig: V-38519 V-38518 V-38623)" do + it "secures rsyslog.conf-referenced files correctly" do command( [ # get all logfile directives @@ -112,325 +111,324 @@ # remove leading characters "sed 's%^[ \t]*%%' | rev | awk '{ print $1 }' | rev | sed 's%^-%%'", # unique tests - 'sort | uniq', - ].join('|') + "sort | uniq" + ].join("|") ).stdout.split("\n").each do |logfile| f = file(logfile) - expect(f).to be_owned_by('syslog') # stig: V-38518 - expect(f.group).to eq('syslog') # stig: V-38519 - expect(f).to be_mode(0600) # stig: V-38623 + expect(f).to be_owned_by("syslog") # stig: V-38518 + expect(f.group).to eq("syslog") # stig: V-38519 + expect(f).to be_mode(0o600) # stig: V-38623 - expect(f).to_not be_readable_by_user('vcap') + expect(f).to_not be_readable_by_user("vcap") end end end - context 'installed by rsyslog_logrotate' do - describe file('/etc/logrotate.d/rsyslog') do + context "installed by rsyslog_logrotate" do + describe file("/etc/logrotate.d/rsyslog") do it { should be_file } - it 'should reload rsyslog on rotate' do - expect(subject.content).to match /sudo systemctl kill -s HUP rsyslog.service/ + it "should reload rsyslog on rotate" do + expect(subject.content).to match(/sudo systemctl kill -s HUP rsyslog.service/) end - it 'should not restart rsyslog on rotate so that logs are not lost' do - expect(subject.content).not_to match 'restart rsyslog' + it "should not restart rsyslog on rotate so that logs are not lost" do + expect(subject.content).not_to match "restart rsyslog" end - end end - context 'installed by rsyslog_config' do + context "installed by rsyslog_config" do before do - Open3.capture3("sudo mount --bind /dev #{ @os_image_dir }/dev") unless @os_image_dir.nil? + Open3.capture3("sudo mount --bind /dev #{@os_image_dir}/dev") unless @os_image_dir.nil? end after do - Open3.capture3("sudo umount #{ @os_image_dir }/dev") unless @os_image_dir.nil? + Open3.capture3("sudo umount #{@os_image_dir}/dev") unless @os_image_dir.nil? end - describe file('/etc/rsyslog.conf') do + describe file("/etc/rsyslog.conf") do it { should be_file } - its(:content) { should match /^module\( load="omrelp" tls.tlslib="openssl" \)$/ } + its(:content) { should match(/^module\( load="omrelp" tls.tlslib="openssl" \)$/) } its(:content) { should match '\$FileGroup syslog' } # stig: V-38519 its(:content) { should match '\$FileOwner syslog' } # stig: V-38518 its(:content) { should match '\$FileCreateMode 0600' } # stig: V-38623 end - describe user('syslog') do + describe user("syslog") do it { should exist } - it { should be_in_group 'vcap' } + it { should be_in_group "vcap" } end - describe group('adm') do + describe group("adm") do it { should exist } end - describe group('bosh_sudoers') do + describe group("bosh_sudoers") do it { should exist } end - describe group('bosh_sshers') do + describe group("bosh_sshers") do it { should exist } end - describe command('rsyslogd -N 1') do - it('has exit status of 0') { expect(subject.exit_status).to eq 0 } - it('reports its version number as 8') { expect(subject.stderr).to match /version 8/ } + describe command("rsyslogd -N 1") do + it("has exit status of 0") { expect(subject.exit_status).to eq 0 } + it("reports its version number as 8") { expect(subject.stderr).to match(/version 8/) } end - describe file('/etc/rsyslog.conf') do + describe file("/etc/rsyslog.conf") do it { should be_file } - its(:content) { should match('ModLoad imklog') } + its(:content) { should match("ModLoad imklog") } end end - context 'auditd should be installed but not enabled (stig: V-38628) (stig: V-38631) (stig: V-38632)' do - describe service('auditd') do + context "auditd should be installed but not enabled (stig: V-38628) (stig: V-38631) (stig: V-38632)" do + describe service("auditd") do # Agent is responsible for starting auditd it { should_not be_enabled } end end - context 'configured by base_ssh' do - it 'is secure' do - expect(sshd_config).to be_mode(0600) + context "configured by base_ssh" do + it "is secure" do + expect(sshd_config).to be_mode(0o600) end - it 'disallows root login (stig: V-38613)' do + it "disallows root login (stig: V-38613)" do expect(sshd_config.content).to match(/^PermitRootLogin no$/) end - it 'allows PrintLastLog (stig: V-38484)' do + it "allows PrintLastLog (stig: V-38484)" do expect(sshd_config.content).to match(/^PrintLastLog yes$/) end - it 'disables insecure DSA host keys' do + it "disables insecure DSA host keys" do expect(sshd_config.content).to_not match(/HostKey \/etc\/ssh\/ssh_host_dsa_key$/) end - it 'enables RSA, ECDSA, ED25519 host keys', exclude_on_fips: true do + it "enables RSA, ECDSA, ED25519 host keys", exclude_on_fips: true do matches = sshd_config.content.scan(/^HostKey.*/) - expect(matches).to contain_exactly('HostKey /etc/ssh/ssh_host_rsa_key', 'HostKey /etc/ssh/ssh_host_ecdsa_key', 'HostKey /etc/ssh/ssh_host_ed25519_key') + expect(matches).to contain_exactly("HostKey /etc/ssh/ssh_host_rsa_key", "HostKey /etc/ssh/ssh_host_ecdsa_key", "HostKey /etc/ssh/ssh_host_ed25519_key") end - it 'disallows X11 forwarding' do + it "disallows X11 forwarding" do expect(sshd_config.content).to match(/^X11Forwarding no$/) expect(sshd_config.content).to_not match(/^X11DisplayOffset/) end - it 'sets MaxAuthTries to 3' do + it "sets MaxAuthTries to 3" do expect(sshd_config.content).to match(/^MaxAuthTries 3$/) end - it 'sets PermitEmptyPasswords to no (stig: V-38614)' do + it "sets PermitEmptyPasswords to no (stig: V-38614)" do expect(sshd_config.content).to match(/^PermitEmptyPasswords no$/) end - it 'sets HostbasedAuthentication to no (stig: V-38612)' do + it "sets HostbasedAuthentication to no (stig: V-38612)" do expect(sshd_config.content).to match(/^HostbasedAuthentication no$/) end - it 'sets Banner to /etc/issue.net (stig: V-38615 V-38593) (CIS-11.1)' do + it "sets Banner to /etc/issue.net (stig: V-38615 V-38593) (CIS-11.1)" do expect(sshd_config.content).to match(/^Banner \/etc\/issue.net$/) - banner = file('/etc/issue.net') + banner = file("/etc/issue.net") # multiline message - expect(banner.content).to match('Unauthorized use is strictly prohibited. All access and activity') - expect(banner.content).to match('is subject to logging and monitoring.') - expect(banner).to be_mode(0644) - expect(banner).to be_owned_by('root') - expect(banner.group).to eq('root') + expect(banner.content).to match("Unauthorized use is strictly prohibited. All access and activity") + expect(banner.content).to match("is subject to logging and monitoring.") + expect(banner).to be_mode(0o644) + expect(banner).to be_owned_by("root") + expect(banner.group).to eq("root") end - it 'sets /etc/issue (CIS-11.1)' do - banner = file('/etc/issue') + it "sets /etc/issue (CIS-11.1)" do + banner = file("/etc/issue") # multiline message - expect(banner.content).to match('Unauthorized use is strictly prohibited. All access and activity') - expect(banner.content).to match('is subject to logging and monitoring.') - expect(banner).to be_mode(0644) - expect(banner).to be_owned_by('root') - expect(banner.group).to eq('root') + expect(banner.content).to match("Unauthorized use is strictly prohibited. All access and activity") + expect(banner.content).to match("is subject to logging and monitoring.") + expect(banner).to be_mode(0o644) + expect(banner).to be_owned_by("root") + expect(banner.group).to eq("root") end - it 'has an empty /etc/motd (CIS-11.1)' do - banner = file('/etc/motd') + it "has an empty /etc/motd (CIS-11.1)" do + banner = file("/etc/motd") expect(banner.content).to be_empty - expect(banner).to be_mode(0644) - expect(banner).to be_owned_by('root') - expect(banner.group).to eq('root') + expect(banner).to be_mode(0o644) + expect(banner).to be_owned_by("root") + expect(banner.group).to eq("root") end - it 'disables motd' do - banner = file('/etc/default/motd-news') - expect(banner.content).to match('ENABLED=0') + it "disables motd" do + banner = file("/etc/default/motd-news") + expect(banner.content).to match("ENABLED=0") end - it 'sets IgnoreRhosts to yes (stig: V-38611)' do + it "sets IgnoreRhosts to yes (stig: V-38611)" do expect(sshd_config.content).to match(/^IgnoreRhosts yes$/) end - it 'sets ClientAliveInterval to 180 seconds (CIS-5.2.12)' do + it "sets ClientAliveInterval to 180 seconds (CIS-5.2.12)" do expect(sshd_config.content).to match(/^ClientAliveInterval 180$/) end - it 'sets LoginGraceTime to 60 seconds (CIS-5.2.13)' do + it "sets LoginGraceTime to 60 seconds (CIS-5.2.13)" do expect(sshd_config.content).to match(/^LoginGraceTime 60$/) end - it 'sets Compression to delayed seconds (stig: V-75851)' do + it "sets Compression to delayed seconds (stig: V-75851)" do expect(sshd_config.content).to match(/^Compression delayed$/) end - it 'sets PermitUserEnvironment to no (stig: V-38616)' do + it "sets PermitUserEnvironment to no (stig: V-38616)" do expect(sshd_config.content).to match(/^PermitUserEnvironment no$/) end - it 'sets ClientAliveCountMax to 1 (stig: V-75837)' do + it "sets ClientAliveCountMax to 1 (stig: V-75837)" do expect(sshd_config.content).to match(/^ClientAliveCountMax 1$/) end - it 'sets Protocol to 2 (stig: V-38607)' do + it "sets Protocol to 2 (stig: V-38607)" do expect(sshd_config.content).to match(/^Protocol 2$/) - end + end - it 'sets AllowGroups to bosh_sshers (CIS 9.3.13)' do + it "sets AllowGroups to bosh_sshers (CIS 9.3.13)" do expect(sshd_config.content).to match(/^AllowGroups bosh_sshers$/) end - it 'sets DenyUsers to root' do + it "sets DenyUsers to root" do expect(sshd_config.content).to match(/^DenyUsers root$/) end end - describe 'PAM configuration' do - context 'blank password logins are disabled (stig: V-38497)' do - describe command('grep -R nullok /etc/pam.d') do - it('exits 1') { expect(subject.exit_status).to eq 1 } - its (:stdout) { should eq('') } + describe "PAM configuration" do + context "blank password logins are disabled (stig: V-38497)" do + describe command("grep -R nullok /etc/pam.d") do + it("exits 1") { expect(subject.exit_status).to eq 1 } + its(:stdout) { should eq("") } end end - context 'a stronger hashing algorithm should be used (stig: V-38574)' do + context "a stronger hashing algorithm should be used (stig: V-38574)" do describe command('egrep -h -r "^password" /etc/pam.d | grep pam_unix.so | grep -v sha512') do - it('exits 1') { expect(subject.exit_status).to eq 1 } - its (:stdout) { should eq('') } + it("exits 1") { expect(subject.exit_status).to eq 1 } + its(:stdout) { should eq("") } end end end - context 'anacron is configured' do - describe file('/etc/anacrontab') do + context "anacron is configured" do + describe file("/etc/anacrontab") do it { should be_file } - it 'declares RANDOM_DELAY early on' do + it "declares RANDOM_DELAY early on" do lines = subject.content.lines.map(&:strip) - random_delay_index = lines.index('RANDOM_DELAY=60') + random_delay_index = lines.index("RANDOM_DELAY=60") expect(random_delay_index).not_to be_nil (0..random_delay_index).each do |idx| - expect(lines[idx]).not_to(match /(\S+\s+){2}cron\./) + expect(lines[idx]).not_to(match(/(\S+\s+){2}cron\./)) end end end end - context 'tftp is not installed (stig: V-38701, V-38609, V-38606)' do + context "tftp is not installed (stig: V-38701, V-38609, V-38606)" do it "shouldn't be installed" do - expect(package('tftp')).to_not be_installed - expect(package('tftpd')).to_not be_installed - expect(package('tftp-server')).to_not be_installed - expect(package('atftp')).to_not be_installed - expect(package('atftpd')).to_not be_installed - expect(package('libnet-tftp-ruby')).to_not be_installed - expect(package('python-tftpy')).to_not be_installed - expect(package('tftp-hpa')).to_not be_installed + expect(package("tftp")).to_not be_installed + expect(package("tftpd")).to_not be_installed + expect(package("tftp-server")).to_not be_installed + expect(package("atftp")).to_not be_installed + expect(package("atftpd")).to_not be_installed + expect(package("libnet-tftp-ruby")).to_not be_installed + expect(package("python-tftpy")).to_not be_installed + expect(package("tftp-hpa")).to_not be_installed end end - context 'vsftpd is not installed (stig: V-38599)' do + context "vsftpd is not installed (stig: V-38599)" do it "shouldn't be installed" do - expect(package('vsftpd')).to_not be_installed - expect(package('ftpd')).to_not be_installed + expect(package("vsftpd")).to_not be_installed + expect(package("ftpd")).to_not be_installed end end - context 'telnet-server is not installed (stig: V-38587, V-38589)' do + context "telnet-server is not installed (stig: V-38587, V-38589)" do it "shouldn't be installed" do - expect(package('telnet-server')).to_not be_installed - expect(package('telnetd')).to_not be_installed - expect(package('telnetd-ssl')).to_not be_installed - expect(package('telnet-server-krb5')).to_not be_installed - expect(package('inetutils-telnetd')).to_not be_installed - expect(package('mactelnet-server')).to_not be_installed + expect(package("telnet-server")).to_not be_installed + expect(package("telnetd")).to_not be_installed + expect(package("telnetd-ssl")).to_not be_installed + expect(package("telnet-server-krb5")).to_not be_installed + expect(package("inetutils-telnetd")).to_not be_installed + expect(package("mactelnet-server")).to_not be_installed end end - context 'gconf2 is not installed (stig: V-43150) (stig: V-38638) (stig: V-38629) (stig: V-38630)' do - describe package('gconf2') do + context "gconf2 is not installed (stig: V-43150) (stig: V-38638) (stig: V-38629) (stig: V-38630)" do + describe package("gconf2") do it { should_not be_installed } end end - context 'rsh-server is not installed (stig: V-38598, V-38591, V-38594, V-38602)' do - describe package('rsh-server') do + context "rsh-server is not installed (stig: V-38598, V-38591, V-38594, V-38602)" do + describe package("rsh-server") do it { should_not be_installed } end end - context '/etc/passwd file' do - describe file('/etc/passwd') do - it('should be owned by root user (stig: V-38450)') { should be_owned_by('root') } - it('should be group-owned by root group (stig: V-38451)') { expect(subject.group).to eq('root') } - it('should have mode 0644 (stig: V-38457)') { should be_mode(0644) } + context "/etc/passwd file" do + describe file("/etc/passwd") do + it("should be owned by root user (stig: V-38450)") { should be_owned_by("root") } + it("should be group-owned by root group (stig: V-38451)") { expect(subject.group).to eq("root") } + it("should have mode 0644 (stig: V-38457)") { should be_mode(0o644) } end - context 'should not contain password hash (stig: V-38499)' do + context "should not contain password hash (stig: V-38499)" do describe command('grep -v "^#" /etc/passwd | awk -F: \'($2 != "x") {print}\'') do - its (:stdout) { should eq('') } + its(:stdout) { should eq("") } end end - context 'disable system accounts (CIS-10.2)' do + context "disable system accounts (CIS-10.2)" do describe command('/usr/bin/awk -F: \'$1 !~ /^(root|sync|shutdown|halt)$/ && $3 < 500 && $7 !~ /^(\/usr\/sbin\/nologin|\/sbin\/nologin|\/bin\/false)$/ { print; f=1 } END { if (!f) print "none" }\' /etc/passwd') do its(:stdout) { should eq("none\n") } end end end - context '/etc/group file' do - describe file('/etc/group') do - it('should be owned by root user (stig: V-38458)') { should be_owned_by('root') } - it('should be owned by root group (stig: V-38459)') { expect(subject.group).to eq('root') } - it('should have mode 0644 (stig: V-38461)') { should be_mode(0644) } + context "/etc/group file" do + describe file("/etc/group") do + it("should be owned by root user (stig: V-38458)") { should be_owned_by("root") } + it("should be owned by root group (stig: V-38459)") { expect(subject.group).to eq("root") } + it("should have mode 0644 (stig: V-38461)") { should be_mode(0o644) } end end - context '/etc/gshadow file' do - describe file('/etc/gshadow') do - it('should be owned by root user (stig: V-38443)') { should be_owned_by('root') } - it('should be owned by root group (stig: V-38448)') { expect(subject.group).to eq('root')} - it('should have mode 0 (stig: V-38449)') { should be_mode(0000) } + context "/etc/gshadow file" do + describe file("/etc/gshadow") do + it("should be owned by root user (stig: V-38443)") { should be_owned_by("root") } + it("should be owned by root group (stig: V-38448)") { expect(subject.group).to eq("root") } + it("should have mode 0 (stig: V-38449)") { should be_mode(0o000) } end end - context 'find world-writable files (stig: V-38643)' do + context "find world-writable files (stig: V-38643)" do describe command('find \/ -xdev -type f -perm -002') do - its (:stdout) { should eq('') } + its(:stdout) { should eq("") } end end - describe file('/etc/login.defs') do - it('should not allow users to cycle passwords quickly (stig: V-38477)') do - expect(subject.content).to match /^PASS_MIN_DAYS 1/ + describe file("/etc/login.defs") do + it("should not allow users to cycle passwords quickly (stig: V-38477)") do + expect(subject.content).to match(/^PASS_MIN_DAYS 1/) end - it('should use an approved hashing algorithm to save the password (stig: V-38576)') do - expect(subject.content).to match /^ENCRYPT_METHOD SHA512/ + it("should use an approved hashing algorithm to save the password (stig: V-38576)") do + expect(subject.content).to match(/^ENCRYPT_METHOD SHA512/) end end @@ -439,342 +437,340 @@ # nothing will be excluded, which is the desired behavior... we want all OS # images to perform theses stages. For the Stemcell suites the exlude flags # here apply. - describe 'exceptions' do - context 'unless: warden', { - exclude_on_warden: true, + describe "exceptions" do + context "unless: warden", { + exclude_on_warden: true } do - it 'disallows password authentication' do + it "disallows password authentication" do expect(sshd_config.content).to match(/^PasswordAuthentication no$/) end end end - describe package('xinetd') do - it('should not be installed (stig: V-38582)') { should_not be_installed } + describe package("xinetd") do + it("should not be installed (stig: V-38582)") { should_not be_installed } end - context 'The root account must be the only account having a UID of 0 (stig: V-38500)' do + context "The root account must be the only account having a UID of 0 (stig: V-38500)" do describe command("awk -F: '($3 == 0) {print}' /etc/passwd") do - its (:stdout) { should eq("root:x:0:0:root:/root:/bin/bash\n") } + its(:stdout) { should eq("root:x:0:0:root:/root:/bin/bash\n") } end end - describe file('/etc/shadow') do - it('should be owned by root user (stig: V-38502)') { expect(subject.group).to eq('root') } - it('should be owned by root group (stig: V-38503)') { expect(subject.group).to eq('root') } - it('should have mode 0 (stig: V-38504)') { should be_mode(0000) } + describe file("/etc/shadow") do + it("should be owned by root user (stig: V-38502)") { expect(subject.group).to eq("root") } + it("should be owned by root group (stig: V-38503)") { expect(subject.group).to eq("root") } + it("should have mode 0 (stig: V-38504)") { should be_mode(0o000) } - context 'contains no system users with passwords (stig: V-38496)' do + context "contains no system users with passwords (stig: V-38496)" do describe command("awk -F: '$1 !~ /^root$/ && $1 !~ /^vcap$/ && $2 !~ /^[!*]/ {print $1 \":\" $2}' /etc/shadow") do - it('has exit status of 0') { expect(subject.exit_status).to eq 0 } - its (:stdout) { should eq('') } + it("has exit status of 0") { expect(subject.exit_status).to eq 0 } + its(:stdout) { should eq("") } end end - context 'contains no users with that can update their password frequently (stig: V-38477)' do + context "contains no users with that can update their password frequently (stig: V-38477)" do describe command("awk -F: '$1 !~ /^root$/ && $2 !~ /^[!*]/ && $4 != \"1\" {print $1 \":\" $4}' /etc/shadow") do - it('has exit status of 0') { expect(subject.exit_status).to eq 0 } - its (:stdout) { should eq('') } + it("has exit status of 0") { expect(subject.exit_status).to eq 0 } + its(:stdout) { should eq("") } end end - context 'contains no users with that can update their password frequently (stig: V-38477)' do + context "contains no users with that can update their password frequently (stig: V-38477)" do describe command("awk -F: '$1 !~ /^root$/ && $2 !~ /^[!*]/ && $4 != \"1\" {print $1 \":\" $4}' /etc/shadow") do - it('has exit status of 0') { expect(subject.exit_status).to eq 0 } - its (:stdout) { should eq('') } + it("has exit status of 0") { expect(subject.exit_status).to eq 0 } + its(:stdout) { should eq("") } end end end - describe 'IP forwarding for IPv4 must not be enabled (stig: V-38511)' do - context file('/etc/sysctl.d/60-bosh-sysctl.conf') do - its (:content) { should match /^net\.ipv4\.ip_forward=0$/ } + describe "IP forwarding for IPv4 must not be enabled (stig: V-38511)" do + context file("/etc/sysctl.d/60-bosh-sysctl.conf") do + its(:content) { should match(/^net\.ipv4\.ip_forward=0$/) } end end - describe 'address space layout randomization (ASLR) should be enabled (stig: V-38596)' do - context file('/etc/sysctl.d/60-bosh-sysctl.conf') do - its (:content) { should match /^kernel\.randomize_va_space=2$/ } + describe "address space layout randomization (ASLR) should be enabled (stig: V-38596)" do + context file("/etc/sysctl.d/60-bosh-sysctl.conf") do + its(:content) { should match(/^kernel\.randomize_va_space=2$/) } end end - describe 'syncookies should be enabled (stig: V-38539)' do - context file('/etc/sysctl.d/60-bosh-sysctl.conf') do - its (:content) { should match /^net\.ipv4\.tcp_syncookies=1$/ } + describe "syncookies should be enabled (stig: V-38539)" do + context file("/etc/sysctl.d/60-bosh-sysctl.conf") do + its(:content) { should match(/^net\.ipv4\.tcp_syncookies=1$/) } end end - - describe 'tcp keepalive values' do - context file('/etc/sysctl.d/60-bosh-sysctl.conf') do - its (:content) { should match /^net\.ipv4\.tcp_keepalive_time=120$/ } - its (:content) { should match /^net\.ipv4\.tcp_keepalive_intvl=30$/ } - its (:content) { should match /^net\.ipv4\.tcp_keepalive_probes=8$/ } + describe "tcp keepalive values" do + context file("/etc/sysctl.d/60-bosh-sysctl.conf") do + its(:content) { should match(/^net\.ipv4\.tcp_keepalive_time=120$/) } + its(:content) { should match(/^net\.ipv4\.tcp_keepalive_intvl=30$/) } + its(:content) { should match(/^net\.ipv4\.tcp_keepalive_probes=8$/) } end end - describe 'root_maxkeys and maxkeys' do - context file('/etc/sysctl.d/60-bosh-sysctl.conf') do - its (:content) { should match /^kernel\.keys\.root_maxkeys=1000000$/ } - its (:content) { should match /^kernel\.keys\.maxkeys=1000000$/ } + describe "root_maxkeys and maxkeys" do + context file("/etc/sysctl.d/60-bosh-sysctl.conf") do + its(:content) { should match(/^kernel\.keys\.root_maxkeys=1000000$/) } + its(:content) { should match(/^kernel\.keys\.maxkeys=1000000$/) } end end - describe 'dmesg_restrict' do - context file('/etc/sysctl.d/60-bosh-sysctl.conf') do - its (:content) { should match /^kernel\.dmesg_restrict\=1$/ } + describe "dmesg_restrict" do + context file("/etc/sysctl.d/60-bosh-sysctl.conf") do + its(:content) { should match(/^kernel\.dmesg_restrict=1$/) } end end - describe 'auditd configuration' do - describe file('/var/log/audit') do + describe "auditd configuration" do + describe file("/var/log/audit") do it { should be_directory } - describe 'Audit log directories must have mode 0755 or less permissive (750 by default) (stig: V-38493)' do - it { should_not be_writable_by('group') } - it { should_not be_writable_by('other') } + describe "Audit log directories must have mode 0755 or less permissive (750 by default) (stig: V-38493)" do + it { should_not be_writable_by("group") } + it { should_not be_writable_by("other") } end end - describe file('/etc/audit/auditd.conf') do - describe 'logging disk errors to syslog (stig: V-38464)' do - its (:content) { should match /^disk_error_action = SYSLOG$/ } + describe file("/etc/audit/auditd.conf") do + describe "logging disk errors to syslog (stig: V-38464)" do + its(:content) { should match(/^disk_error_action = SYSLOG$/) } end - describe 'logging disks being low on space to syslog (stig: V-54381) (stig: V-38470)' do - its (:content) { should match /^admin_space_left_action = SYSLOG$/ } - its (:content) { should match /^space_left_action = SYSLOG$/ } + describe "logging disks being low on space to syslog (stig: V-54381) (stig: V-38470)" do + its(:content) { should match(/^admin_space_left_action = SYSLOG$/) } + its(:content) { should match(/^space_left_action = SYSLOG$/) } end - describe 'logging disks being full to syslog (stig: V-38468)' do - its (:content) { should match /^disk_full_action = SYSLOG$/ } + describe "logging disks being full to syslog (stig: V-38468)" do + its(:content) { should match(/^disk_full_action = SYSLOG$/) } end - describe 'keeping the log files under a certain size (stig: V-38633)' do - its (:content) { should match /^max_log_file = 6$/ } + describe "keeping the log files under a certain size (stig: V-38633)" do + its(:content) { should match(/^max_log_file = 6$/) } end - describe 'rotating the logs so the disk does not run out of space (stig: V-38634)' do - its (:content) { should match /^max_log_file_action = ROTATE$/ } + describe "rotating the logs so the disk does not run out of space (stig: V-38634)" do + its(:content) { should match(/^max_log_file_action = ROTATE$/) } end - describe 'keeping the logs around for a sensible retention period (stig: V-38636)' do - its (:content) { should match /^num_logs = 5$/ } + describe "keeping the logs around for a sensible retention period (stig: V-38636)" do + its(:content) { should match(/^num_logs = 5$/) } end - describe 'audit log files must be group owned by root (stig: V-38445)' do - its (:content) { should match /^log_group = root$/ } + describe "audit log files must be group owned by root (stig: V-38445)" do + its(:content) { should match(/^log_group = root$/) } end - describe 'audit log files triggers action when storage capacity is less than 75mb (stig: V-38678)' do - its (:content) { should match /^space_left = 75$/ } + describe "audit log files triggers action when storage capacity is less than 75mb (stig: V-38678)" do + its(:content) { should match(/^space_left = 75$/) } end - describe 'audit log files triggers action when storage capacity is less than 50mb (this must be less than space_left) (stig: V-38678)' do - its (:content) { should match /^admin_space_left = 50$/ } + describe "audit log files triggers action when storage capacity is less than 50mb (this must be less than space_left) (stig: V-38678)" do + its(:content) { should match(/^admin_space_left = 50$/) } end end - context ("plugins.d/syslog.conf") do - it 'auditd logs to syslog' do - expect(syslog_config.content).to match ( /^active = yes$/ ) + context("plugins.d/syslog.conf") do + it "auditd logs to syslog" do + expect(syslog_config.content).to match(/^active = yes$/) end end end - describe file('/etc/audit/rules.d/audit.rules') do - describe 'loading and unloading of dynamic kernel modules must be audited (stig: V-38580)' do - its(:content) { should match /^-w \/sbin\/insmod -p x -k modules$/ } - its(:content) { should match /^-w \/sbin\/rmmod -p x -k modules$/ } - its(:content) { should match /^-w \/sbin\/modprobe -p x -k modules$/ } - its(:content) { should match /^-w \/bin\/kmod -p x -k modules$/ } - its(:content) { should match /-a always,exit -F arch=b64 -S finit_module -S init_module -S delete_module -k modules/ } + describe file("/etc/audit/rules.d/audit.rules") do + describe "loading and unloading of dynamic kernel modules must be audited (stig: V-38580)" do + its(:content) { should match(/^-w \/sbin\/insmod -p x -k modules$/) } + its(:content) { should match(/^-w \/sbin\/rmmod -p x -k modules$/) } + its(:content) { should match(/^-w \/sbin\/modprobe -p x -k modules$/) } + its(:content) { should match(/^-w \/bin\/kmod -p x -k modules$/) } + its(:content) { should match(/-a always,exit -F arch=b64 -S finit_module -S init_module -S delete_module -k modules/) } end - describe 'events that modify system date and time must be recorded (CIS-8.1.4)' do - its(:content) { should match /^-a always,exit -F arch=b64 -S adjtimex -S settimeofday -k time-change$/ } - its(:content) { should match /^-a always,exit -F arch=b32 -S adjtimex -S settimeofday -S stime -k time-change$/ } - its(:content) { should match /^-a always,exit -F arch=b64 -S clock_settime -k time-change$/ } - its(:content) { should match /^-a always,exit -F arch=b32 -S clock_settime -k time-change$/ } - its(:content) { should match /^-w \/etc\/localtime -p wa -k time-change$/ } + describe "events that modify system date and time must be recorded (CIS-8.1.4)" do + its(:content) { should match(/^-a always,exit -F arch=b64 -S adjtimex -S settimeofday -k time-change$/) } + its(:content) { should match(/^-a always,exit -F arch=b32 -S adjtimex -S settimeofday -S stime -k time-change$/) } + its(:content) { should match(/^-a always,exit -F arch=b64 -S clock_settime -k time-change$/) } + its(:content) { should match(/^-a always,exit -F arch=b32 -S clock_settime -k time-change$/) } + its(:content) { should match(/^-w \/etc\/localtime -p wa -k time-change$/) } end - describe 'file deletion events must be recorded (CIS-8.1.14)' do - its(:content) { should match /^-a always,exit -F arch=b64 -S unlink -S unlinkat -S rmdir -S rename -S renameat -F auid>=500 -F auid!=4294967295 -k delete$/ } - its(:content) { should match /^-a always,exit -F arch=b32 -S unlink -S unlinkat -S rmdir -S rename -S renameat -F auid>=500 -F auid!=4294967295 -k delete$/ } + describe "file deletion events must be recorded (CIS-8.1.14)" do + its(:content) { should match(/^-a always,exit -F arch=b64 -S unlink -S unlinkat -S rmdir -S rename -S renameat -F auid>=500 -F auid!=4294967295 -k delete$/) } + its(:content) { should match(/^-a always,exit -F arch=b32 -S unlink -S unlinkat -S rmdir -S rename -S renameat -F auid>=500 -F auid!=4294967295 -k delete$/) } end - describe 'audit rules are made mutable (CIS-8.1.18)' do - it 'should not have a -e 2 line' do - expect(subject.content).not_to match '-e 2' + describe "audit rules are made mutable (CIS-8.1.18)" do + it "should not have a -e 2 line" do + expect(subject.content).not_to match "-e 2" end end - describe 'record changes to sudoers file (CIS-8.1.15)' do - its(:content) { should match /^-w \/etc\/sudoers -p wa -k scope$/ } - its(:content) { should match /^-w \/etc\/sudoers\.d -p wa -k scope$/ } - end + describe "record changes to sudoers file (CIS-8.1.15)" do + its(:content) { should match(/^-w \/etc\/sudoers -p wa -k scope$/) } + its(:content) { should match(/^-w \/etc\/sudoers\.d -p wa -k scope$/) } + end - describe 'record login and logout events (CIS-8.1.8)' do - its(:content) { should match /^-w \/var\/log\/faillog -p wa -k logins$/ } - its(:content) { should match /^-w \/var\/log\/lastlog -p wa -k logins$/ } - its(:content) { should match /^-w \/var\/log\/tallylog -p wa -k logins$/ } - its(:content) { should match /^-w \/var\/run\/faillock -p wa -k logins$/ } + describe "record login and logout events (CIS-8.1.8)" do + its(:content) { should match(/^-w \/var\/log\/faillog -p wa -k logins$/) } + its(:content) { should match(/^-w \/var\/log\/lastlog -p wa -k logins$/) } + its(:content) { should match(/^-w \/var\/log\/tallylog -p wa -k logins$/) } + its(:content) { should match(/^-w \/var\/run\/faillock -p wa -k logins$/) } end - describe 'record session initiation events (CIS-8.1.9)' do - its(:content) { should match /^-w \/var\/run\/utmp -p wa -k session$/ } - its(:content) { should match /^-w \/var\/log\/wtmp -p wa -k session$/ } - its(:content) { should match /^-w \/var\/log\/btmp -p wa -k session$/ } + describe "record session initiation events (CIS-8.1.9)" do + its(:content) { should match(/^-w \/var\/run\/utmp -p wa -k session$/) } + its(:content) { should match(/^-w \/var\/log\/wtmp -p wa -k session$/) } + its(:content) { should match(/^-w \/var\/log\/btmp -p wa -k session$/) } end - describe 'record events that modify user/group information (CIS-8.1.5)' do - its(:content) { should match /^-w \/etc\/group -p wa -k identity$/ } - its(:content) { should match /^-w \/etc\/passwd -p wa -k identity$/ } - its(:content) { should match /^-w \/etc\/gshadow -p wa -k identity$/ } - its(:content) { should match /^-w \/etc\/shadow -p wa -k identity$/ } - its(:content) { should match /^-w \/etc\/security\/opasswd -p wa -k identity$/ } + describe "record events that modify user/group information (CIS-8.1.5)" do + its(:content) { should match(/^-w \/etc\/group -p wa -k identity$/) } + its(:content) { should match(/^-w \/etc\/passwd -p wa -k identity$/) } + its(:content) { should match(/^-w \/etc\/gshadow -p wa -k identity$/) } + its(:content) { should match(/^-w \/etc\/shadow -p wa -k identity$/) } + its(:content) { should match(/^-w \/etc\/security\/opasswd -p wa -k identity$/) } end - describe 'record events that modify system network environment (CIS-4.1.6)' do - its(:content) { should match /^-a exit,always -F arch=b64 -S sethostname -S setdomainname -k system-locale$/ } - its(:content) { should match /^-a exit,always -F arch=b32 -S sethostname -S setdomainname -k system-locale$/ } - its(:content) { should match /^-w \/etc\/issue -p wa -k system-locale$/ } - its(:content) { should match /^-w \/etc\/issue\.net -p wa -k system-locale$/ } - its(:content) { should match /^-w \/etc\/hosts -p wa -k system-locale$/ } - its(:content) { should match /^-w \/etc\/network -p wa -k system-locale$/ } - its(:content) { should match /^-w \/etc\/networks -p wa -k system-locale$/ } + describe "record events that modify system network environment (CIS-4.1.6)" do + its(:content) { should match(/^-a exit,always -F arch=b64 -S sethostname -S setdomainname -k system-locale$/) } + its(:content) { should match(/^-a exit,always -F arch=b32 -S sethostname -S setdomainname -k system-locale$/) } + its(:content) { should match(/^-w \/etc\/issue -p wa -k system-locale$/) } + its(:content) { should match(/^-w \/etc\/issue\.net -p wa -k system-locale$/) } + its(:content) { should match(/^-w \/etc\/hosts -p wa -k system-locale$/) } + its(:content) { should match(/^-w \/etc\/network -p wa -k system-locale$/) } + its(:content) { should match(/^-w \/etc\/networks -p wa -k system-locale$/) } end - describe 'record events that modify systems mandatory access controls (CIS-4.1.7)' do - its(:content) { should match /^-w \/etc\/apparmor\/ -p wa -k MAC-policy$/ } - its(:content) { should match /^-w \/etc\/apparmor\.d\/ -p wa -k MAC-policy$/ } + describe "record events that modify systems mandatory access controls (CIS-4.1.7)" do + its(:content) { should match(/^-w \/etc\/apparmor\/ -p wa -k MAC-policy$/) } + its(:content) { should match(/^-w \/etc\/apparmor\.d\/ -p wa -k MAC-policy$/) } end - describe 'record system administrator actions (CIS-8.1.16)' do - its(:content) { should match /^-a always,exit -F arch=b64 -S execve -F euid=0 -F auid>=1000 -F auid!=4294967295 -F key=sudo_log$/ } - its(:content) { should match /^-a always,exit -F arch=b32 -S execve -F euid=0 -F auid>=1000 -F auid!=4294967295 -F key=sudo_log$/ } + describe "record system administrator actions (CIS-8.1.16)" do + its(:content) { should match(/^-a always,exit -F arch=b64 -S execve -F euid=0 -F auid>=1000 -F auid!=4294967295 -F key=sudo_log$/) } + its(:content) { should match(/^-a always,exit -F arch=b32 -S execve -F euid=0 -F auid>=1000 -F auid!=4294967295 -F key=sudo_log$/) } end - describe 'record file system mounts (CIS-8.1.13)' do - its(:content) { should match /^-a always,exit -F arch=b64 -S mount -F auid>=500 -F auid!=4294967295 -k mounts$/ } - its(:content) { should match /^-a always,exit -F arch=b32 -S mount -F auid>=500 -F auid!=4294967295 -k mounts$/ } + describe "record file system mounts (CIS-8.1.13)" do + its(:content) { should match(/^-a always,exit -F arch=b64 -S mount -F auid>=500 -F auid!=4294967295 -k mounts$/) } + its(:content) { should match(/^-a always,exit -F arch=b32 -S mount -F auid>=500 -F auid!=4294967295 -k mounts$/) } end - describe 'record discretionary access control permission modification events (CIS-8.1.10)' do - its(:content) { should match /^-a always,exit -F arch=b64 -S mount -F auid>=500 -F auid!=4294967295 -k mounts$/ } - its(:content) { should match /^-a always,exit -F arch=b32 -S mount -F auid>=500 -F auid!=4294967295 -k mounts$/ } - its(:content) { should match /^-a always,exit -F arch=b64 -S chmod -S fchmod -S fchmodat -F auid>=500 -F auid!=4294967295 -k perm_mod$/ } - its(:content) { should match /^-a always,exit -F arch=b32 -S chmod -S fchmod -S fchmodat -F auid>=500 -F auid!=4294967295 -k perm_mod$/ } - its(:content) { should match /^-a always,exit -F arch=b64 -S chown -S fchown -S fchownat -S lchown -F auid>=500 -F auid!=4294967295 -k perm_mod$/ } - its(:content) { should match /^-a always,exit -F arch=b32 -S chown -S fchown -S fchownat -S lchown -F auid>=500 -F auid!=4294967295 -k perm_mod$/ } - its(:content) { should match /^-a always,exit -F arch=b64 -S setxattr -S lsetxattr -S fsetxattr -S removexattr -S lremovexattr -S fremovexattr -F auid>=500 -F auid!=4294967295 -k perm_mod$/ } - its(:content) { should match /^-a always,exit -F arch=b32 -S setxattr -S lsetxattr -S fsetxattr -S removexattr -S lremovexattr -S fremovexattr -F auid>=500 -F auid!=4294967295 -k perm_mod$/ } + describe "record discretionary access control permission modification events (CIS-8.1.10)" do + its(:content) { should match(/^-a always,exit -F arch=b64 -S mount -F auid>=500 -F auid!=4294967295 -k mounts$/) } + its(:content) { should match(/^-a always,exit -F arch=b32 -S mount -F auid>=500 -F auid!=4294967295 -k mounts$/) } + its(:content) { should match(/^-a always,exit -F arch=b64 -S chmod -S fchmod -S fchmodat -F auid>=500 -F auid!=4294967295 -k perm_mod$/) } + its(:content) { should match(/^-a always,exit -F arch=b32 -S chmod -S fchmod -S fchmodat -F auid>=500 -F auid!=4294967295 -k perm_mod$/) } + its(:content) { should match(/^-a always,exit -F arch=b64 -S chown -S fchown -S fchownat -S lchown -F auid>=500 -F auid!=4294967295 -k perm_mod$/) } + its(:content) { should match(/^-a always,exit -F arch=b32 -S chown -S fchown -S fchownat -S lchown -F auid>=500 -F auid!=4294967295 -k perm_mod$/) } + its(:content) { should match(/^-a always,exit -F arch=b64 -S setxattr -S lsetxattr -S fsetxattr -S removexattr -S lremovexattr -S fremovexattr -F auid>=500 -F auid!=4294967295 -k perm_mod$/) } + its(:content) { should match(/^-a always,exit -F arch=b32 -S setxattr -S lsetxattr -S fsetxattr -S removexattr -S lremovexattr -S fremovexattr -F auid>=500 -F auid!=4294967295 -k perm_mod$/) } end - describe 'record unsuccessful unauthorized access attempts to files - EACCES (CIS-8.1.11)' do - its(:content) { should match /^-a always,exit -F arch=b64 -S creat -S open -S open_by_handle_at -S openat -S truncate -S ftruncate -F exit=-EACCES -F auid>=500 -F auid!=4294967295 -k access/ } - its(:content) { should match /^-a always,exit -F arch=b32 -S creat -S open -S open_by_handle_at -S openat -S truncate -S ftruncate -F exit=-EACCES -F auid>=500 -F auid!=4294967295 -k access/ } - its(:content) { should match /^-a always,exit -F arch=b64 -S creat -S open -S open_by_handle_at -S openat -S truncate -S ftruncate -F exit=-EPERM -F auid>=500 -F auid!=4294967295 -k access/ } - its(:content) { should match /^-a always,exit -F arch=b32 -S creat -S open -S open_by_handle_at -S openat -S truncate -S ftruncate -F exit=-EPERM -F auid>=500 -F auid!=4294967295 -k access/ } + describe "record unsuccessful unauthorized access attempts to files - EACCES (CIS-8.1.11)" do + its(:content) { should match(/^-a always,exit -F arch=b64 -S creat -S open -S open_by_handle_at -S openat -S truncate -S ftruncate -F exit=-EACCES -F auid>=500 -F auid!=4294967295 -k access/) } + its(:content) { should match(/^-a always,exit -F arch=b32 -S creat -S open -S open_by_handle_at -S openat -S truncate -S ftruncate -F exit=-EACCES -F auid>=500 -F auid!=4294967295 -k access/) } + its(:content) { should match(/^-a always,exit -F arch=b64 -S creat -S open -S open_by_handle_at -S openat -S truncate -S ftruncate -F exit=-EPERM -F auid>=500 -F auid!=4294967295 -k access/) } + its(:content) { should match(/^-a always,exit -F arch=b32 -S creat -S open -S open_by_handle_at -S openat -S truncate -S ftruncate -F exit=-EPERM -F auid>=500 -F auid!=4294967295 -k access/) } end - describe 'record use of binaries' do - its(:content) { should match /^-a always,exit -F perm=x -F auid>=500 -F auid!=4294967295 -F path=\/sbin\/unix_chkpwd -k privileged/ } - its(:content) { should match /^-a always,exit -F perm=x -F auid>=500 -F auid!=4294967295 -F path=\/sbin\/mount\.nfs -k privileged/ } - its(:content) { should match /^-a always,exit -F perm=x -F auid>=500 -F auid!=4294967295 -F path=\/usr\/sbin\/pam_timestamp_check -k privileged/ } - its(:content) { should match /^-a always,exit -F perm=x -F auid>=500 -F auid!=4294967295 -F path=\/usr\/bin\/write -k privileged/ } - its(:content) { should match /^-a always,exit -F perm=x -F auid>=500 -F auid!=4294967295 -F path=\/bin\/mount \-k privileged/ } - its(:content) { should match /^-a always,exit -F perm=x -F auid>=500 -F auid!=4294967295 -F path=\/usr\/bin\/newgrp -k privileged/ } - its(:content) { should match /^-a always,exit -F perm=x -F auid>=500 -F auid!=4294967295 -F path=\/usr\/bin\/wall -k privileged/ } - its(:content) { should match /^-a always,exit -F perm=x -F auid>=500 -F auid!=4294967295 -F path=\/usr\/bin\/passwd -k privileged/ } - its(:content) { should match /^-a always,exit -F perm=x -F auid>=500 -F auid!=4294967295 -F path=\/bin\/umount \-k privileged/ } - its(:content) { should match /^-a always,exit -F perm=x -F auid>=500 -F auid!=4294967295 -F path=\/usr\/bin\/crontab -k privileged/ } - its(:content) { should match /^-a always,exit -F perm=x -F auid>=500 -F auid!=4294967295 -F path=\/usr\/bin\/chfn -k privileged/ } - its(:content) { should match /^-a always,exit -F perm=x -F auid>=500 -F auid!=4294967295 -F path=\/usr\/bin\/ssh-agent -k privileged/ } - its(:content) { should match /^-a always,exit -F perm=x -F auid>=500 -F auid!=4294967295 -F path=\/usr\/bin\/gpasswd -k privileged/ } - its(:content) { should match /^-a always,exit -F perm=x -F auid>=500 -F auid!=4294967295 -F path=\/usr\/bin\/chsh -k privileged/ } - its(:content) { should match /^-a always,exit -F perm=x -F auid>=500 -F auid!=4294967295 -F path=\/usr\/bin\/chage -k privileged/ } - its(:content) { should match /^-a always,exit -F perm=x -F auid>=500 -F auid!=4294967295 -F path=\/usr\/bin\/mount -k privileged/ } - its(:content) { should match /^-a always,exit -F perm=x -F auid>=500 -F auid!=4294967295 -F path=\/usr\/bin\/su -k privileged/ } - its(:content) { should match /^-a always,exit -F perm=x -F auid>=500 -F auid!=4294967295 -F path=\/usr\/bin\/umount -k privileged/ } - its(:content) { should match /^-a always,exit -F perm=x -F auid>=500 -F auid!=4294967295 -F path=\/usr\/sbin\/mount.nfs -k privileged/ } - its(:content) { should match /^-a always,exit -F perm=x -F auid>=500 -F auid!=4294967295 -F path=\/usr\/sbin\/netreport -k privileged/ } - its(:content) { should match /^-a always,exit -F perm=x -F auid>=500 -F auid!=4294967295 -F path=\/usr\/sbin\/postdrop -k privileged/ } - its(:content) { should match /^-a always,exit -F perm=x -F auid>=500 -F auid!=4294967295 -F path=\/usr\/sbin\/postqueue -k privileged/ } - its(:content) { should match /^-a always,exit -F perm=x -F auid>=500 -F auid!=4294967295 -F path=\/usr\/sbin\/usernetctl -k privileged/ } - its(:content) { should match /^-a always,exit -F perm=x -F auid>=500 -F auid!=4294967295 -F path=\/usr\/sbin\/service -k privileged/ } + describe "record use of binaries" do + its(:content) { should match(/^-a always,exit -F perm=x -F auid>=500 -F auid!=4294967295 -F path=\/sbin\/unix_chkpwd -k privileged/) } + its(:content) { should match(/^-a always,exit -F perm=x -F auid>=500 -F auid!=4294967295 -F path=\/sbin\/mount\.nfs -k privileged/) } + its(:content) { should match(/^-a always,exit -F perm=x -F auid>=500 -F auid!=4294967295 -F path=\/usr\/sbin\/pam_timestamp_check -k privileged/) } + its(:content) { should match(/^-a always,exit -F perm=x -F auid>=500 -F auid!=4294967295 -F path=\/usr\/bin\/write -k privileged/) } + its(:content) { should match(/^-a always,exit -F perm=x -F auid>=500 -F auid!=4294967295 -F path=\/bin\/mount -k privileged/) } + its(:content) { should match(/^-a always,exit -F perm=x -F auid>=500 -F auid!=4294967295 -F path=\/usr\/bin\/newgrp -k privileged/) } + its(:content) { should match(/^-a always,exit -F perm=x -F auid>=500 -F auid!=4294967295 -F path=\/usr\/bin\/wall -k privileged/) } + its(:content) { should match(/^-a always,exit -F perm=x -F auid>=500 -F auid!=4294967295 -F path=\/usr\/bin\/passwd -k privileged/) } + its(:content) { should match(/^-a always,exit -F perm=x -F auid>=500 -F auid!=4294967295 -F path=\/bin\/umount -k privileged/) } + its(:content) { should match(/^-a always,exit -F perm=x -F auid>=500 -F auid!=4294967295 -F path=\/usr\/bin\/crontab -k privileged/) } + its(:content) { should match(/^-a always,exit -F perm=x -F auid>=500 -F auid!=4294967295 -F path=\/usr\/bin\/chfn -k privileged/) } + its(:content) { should match(/^-a always,exit -F perm=x -F auid>=500 -F auid!=4294967295 -F path=\/usr\/bin\/ssh-agent -k privileged/) } + its(:content) { should match(/^-a always,exit -F perm=x -F auid>=500 -F auid!=4294967295 -F path=\/usr\/bin\/gpasswd -k privileged/) } + its(:content) { should match(/^-a always,exit -F perm=x -F auid>=500 -F auid!=4294967295 -F path=\/usr\/bin\/chsh -k privileged/) } + its(:content) { should match(/^-a always,exit -F perm=x -F auid>=500 -F auid!=4294967295 -F path=\/usr\/bin\/chage -k privileged/) } + its(:content) { should match(/^-a always,exit -F perm=x -F auid>=500 -F auid!=4294967295 -F path=\/usr\/bin\/mount -k privileged/) } + its(:content) { should match(/^-a always,exit -F perm=x -F auid>=500 -F auid!=4294967295 -F path=\/usr\/bin\/su -k privileged/) } + its(:content) { should match(/^-a always,exit -F perm=x -F auid>=500 -F auid!=4294967295 -F path=\/usr\/bin\/umount -k privileged/) } + its(:content) { should match(/^-a always,exit -F perm=x -F auid>=500 -F auid!=4294967295 -F path=\/usr\/sbin\/mount.nfs -k privileged/) } + its(:content) { should match(/^-a always,exit -F perm=x -F auid>=500 -F auid!=4294967295 -F path=\/usr\/sbin\/netreport -k privileged/) } + its(:content) { should match(/^-a always,exit -F perm=x -F auid>=500 -F auid!=4294967295 -F path=\/usr\/sbin\/postdrop -k privileged/) } + its(:content) { should match(/^-a always,exit -F perm=x -F auid>=500 -F auid!=4294967295 -F path=\/usr\/sbin\/postqueue -k privileged/) } + its(:content) { should match(/^-a always,exit -F perm=x -F auid>=500 -F auid!=4294967295 -F path=\/usr\/sbin\/usernetctl -k privileged/) } + its(:content) { should match(/^-a always,exit -F perm=x -F auid>=500 -F auid!=4294967295 -F path=\/usr\/sbin\/service -k privileged/) } end - describe 'record execution of privileged functions (stig: V-75689)' do - its(:content) { should match /^-a always,exit -F arch=b64 -S execve -C uid!=euid -F key=execpriv/ } - its(:content) { should match /^-a always,exit -F arch=b64 -S execve -C gid!=egid -F key=execpriv/ } - its(:content) { should match /^-a always,exit -F arch=b32 -S execve -C uid!=euid -F key=execpriv/ } - its(:content) { should match /^-a always,exit -F arch=b32 -S execve -C gid!=egid -F key=execpriv/ } + describe "record execution of privileged functions (stig: V-75689)" do + its(:content) { should match(/^-a always,exit -F arch=b64 -S execve -C uid!=euid -F key=execpriv/) } + its(:content) { should match(/^-a always,exit -F arch=b64 -S execve -C gid!=egid -F key=execpriv/) } + its(:content) { should match(/^-a always,exit -F arch=b32 -S execve -C uid!=euid -F key=execpriv/) } + its(:content) { should match(/^-a always,exit -F arch=b32 -S execve -C gid!=egid -F key=execpriv/) } end - describe 'record use of ssh-keysign (stig: V-75707)' do - its(:content) { should match /^-a always,exit -F path=\/usr\/lib\/openssh\/ssh-keysign -F perm=x -F auid>=500 -F auid!=4294967295 -k privileged-ssh/ } + describe "record use of ssh-keysign (stig: V-75707)" do + its(:content) { should match(/^-a always,exit -F path=\/usr\/lib\/openssh\/ssh-keysign -F perm=x -F auid>=500 -F auid!=4294967295 -k privileged-ssh/) } end - describe 'record use of sudoedit (stig: V-75757)' do - its(:content) { should match /^-a always,exit -F path=\/usr\/bin\/sudoedit -F perm=x -F auid>=500 -F auid!=4294967295 -k priv_cmd/ } + describe "record use of sudoedit (stig: V-75757)" do + its(:content) { should match(/^-a always,exit -F path=\/usr\/bin\/sudoedit -F perm=x -F auid>=500 -F auid!=4294967295 -k priv_cmd/) } end - describe 'record use of apparmor_parser (stig: V-75765)' do - its(:content) { should match /^-a always,exit -F path=\/sbin\/apparmor_parser -F perm=x -F auid>=500 -F auid!=4294967295 -k perm_chng/ } + describe "record use of apparmor_parser (stig: V-75765)" do + its(:content) { should match(/^-a always,exit -F path=\/sbin\/apparmor_parser -F perm=x -F auid>=500 -F auid!=4294967295 -k perm_chng/) } end - describe 'record use of usermod (stig: V-75785)' do - its(:content) { should match /^-a always,exit -F path=\/usr\/sbin\/usermod -F perm=x -F auid>=500 -F auid!=4294967295 -k privileged-usermod/ } + describe "record use of usermod (stig: V-75785)" do + its(:content) { should match(/^-a always,exit -F path=\/usr\/sbin\/usermod -F perm=x -F auid>=500 -F auid!=4294967295 -k privileged-usermod/) } end - describe 'record use of chcon (stig: V-80969)' do - its(:content) { should match /^-a always,exit -F path=\/usr\/bin\/chcon -F perm=x -F auid>=500 -F auid!=4294967295 -k perm_chng/ } + describe "record use of chcon (stig: V-80969)" do + its(:content) { should match(/^-a always,exit -F path=\/usr\/bin\/chcon -F perm=x -F auid>=500 -F auid!=4294967295 -k perm_chng/) } end - describe 'record use of unix_update (stig: V-75779)' do - its(:content) { should match /^-a always,exit -F path=\/sbin\/unix_update -F perm=x -F auid>=500 -F auid!=4294967295 -k privileged-unix-update/ } + describe "record use of unix_update (stig: V-75779)" do + its(:content) { should match(/^-a always,exit -F path=\/sbin\/unix_update -F perm=x -F auid>=500 -F auid!=4294967295 -k privileged-unix-update/) } end - end - describe 'record use of privileged programs (CIS-8.1.12)' do + describe "record use of privileged programs (CIS-8.1.12)" do let(:privileged_binaries) { command("find /bin /sbin /usr/bin /usr/sbin /boot -xdev \\( -perm -4000 -o -perm -2000 \\) -type f") .stdout .split } - describe file('/etc/audit/rules.d/audit.rules') do + describe file("/etc/audit/rules.d/audit.rules") do its(:content) do privileged_binaries.each do |privileged_binary| - should match /^-a always,exit -F path=#{privileged_binary} -F perm=x -F auid>=500 -F auid!=4294967295 -k privileged$/ + should match(/^-a always,exit -F path=#{privileged_binary} -F perm=x -F auid>=500 -F auid!=4294967295 -k privileged$/) end end end end - describe 'disabling core dumps (CIS-4.1)' do - describe file('/etc/security/limits.conf') do - its(:content) { should match /^\*\s+hard\s+core\s+0$/ } + describe "disabling core dumps (CIS-4.1)" do + describe file("/etc/security/limits.conf") do + its(:content) { should match(/^\*\s+hard\s+core\s+0$/) } end end - context 'postfix is not installed (stig: V-38622) (stig: V-38446)' do + context "postfix is not installed (stig: V-38622) (stig: V-38446)" do it "shouldn't be installed" do - expect(package('postfix')).to_not be_installed + expect(package("postfix")).to_not be_installed end end - context 'installed binaries' do - describe file('/var/vcap/bosh/bin/sync-time') do + context "installed binaries" do + describe file("/var/vcap/bosh/bin/sync-time") do it { should be_file } it { should be_executable } end end - describe 'Cron logging must be implemented. (stig: V-75865)' do - context file('/etc/rsyslog.d/50-default.conf') do - its (:content) { should match /^cron\.\*\s+\/var\/log\/cron\.log$/ } + describe "Cron logging must be implemented. (stig: V-75865)" do + context file("/etc/rsyslog.d/50-default.conf") do + its(:content) { should match(/^cron\.\*\s+\/var\/log\/cron\.log$/) } end end end diff --git a/bosh-stemcell/spec/support/os_image_systemd_shared_examples.rb b/bosh-stemcell/spec/support/os_image_systemd_shared_examples.rb index 400e28df0e..506a15af83 100644 --- a/bosh-stemcell/spec/support/os_image_systemd_shared_examples.rb +++ b/bosh-stemcell/spec/support/os_image_systemd_shared_examples.rb @@ -1,30 +1,30 @@ -shared_examples_for 'a systemd-based OS image' do - context 'systemd services' do - describe service('monit') do +shared_examples_for "a systemd-based OS image" do + context "systemd services" do + describe service("monit") do it { should be_enabled } end - describe service('rsyslog') do + describe service("rsyslog") do it { should be_enabled } end - describe service('chrony') do + describe service("chrony") do it { should be_enabled } end - describe file('/etc/systemd/system/chronyd.service.d/prevent_mount_locking.conf') do + describe file("/etc/systemd/system/chronyd.service.d/prevent_mount_locking.conf") do it { should be_file } - its(:content) { should match /^InaccessiblePaths=-\/var\/vcap\/store/ } + its(:content) { should match(/^InaccessiblePaths=-\/var\/vcap\/store/) } end - describe file('/etc/systemd/journald.conf.d/00-override.conf') do + describe file("/etc/systemd/journald.conf.d/00-override.conf") do it { should be_file } - its(:content) { should match /^Storage=volatile/ } + its(:content) { should match(/^Storage=volatile/) } end - describe file('/etc/systemd/system/rsyslog.service.d/00-override.conf') do + describe file("/etc/systemd/system/rsyslog.service.d/00-override.conf") do it { should be_file } - its(:content) { should match /^ExecStartPre=\/usr\/local\/bin\/wait_for_var_log_to_be_mounted/ } + its(:content) { should match(/^ExecStartPre=\/usr\/local\/bin\/wait_for_var_log_to_be_mounted/) } end end end diff --git a/bosh-stemcell/spec/support/os_image_ubuntu_shared_examples.rb b/bosh-stemcell/spec/support/os_image_ubuntu_shared_examples.rb index ac00cb268d..2ee4b75695 100644 --- a/bosh-stemcell/spec/support/os_image_ubuntu_shared_examples.rb +++ b/bosh-stemcell/spec/support/os_image_ubuntu_shared_examples.rb @@ -1,6 +1,6 @@ -shared_examples_for 'an Ubuntu-based OS image' do - context 'X Windows must not be enabled unless required (stig: V-38674)' do - describe package('xserver-xorg') do +shared_examples_for "an Ubuntu-based OS image" do + context "X Windows must not be enabled unless required (stig: V-38674)" do + describe package("xserver-xorg") do it { should_not be_installed } end end diff --git a/bosh-stemcell/spec/support/os_image_upstart_shared_examples.rb b/bosh-stemcell/spec/support/os_image_upstart_shared_examples.rb index e7f1c277f4..6e5103afa8 100644 --- a/bosh-stemcell/spec/support/os_image_upstart_shared_examples.rb +++ b/bosh-stemcell/spec/support/os_image_upstart_shared_examples.rb @@ -1,23 +1,23 @@ -shared_examples_for 'an upstart-based OS image' do - context 'installed by rsyslog_config' do - RSYSLOG_EXECUTABLE = '/usr/sbin/rsyslogd'.freeze +shared_examples_for "an upstart-based OS image" do + context "installed by rsyslog_config" do + rsyslog_executable = "/usr/sbin/rsyslogd".freeze - describe file('/etc/init/rsyslog.conf') do - its(:content) { should match RSYSLOG_EXECUTABLE } + describe file("/etc/init/rsyslog.conf") do + its(:content) { should match rsyslog_executable } end # verify that the path used in the upstart config points to an actual executable - describe file(RSYSLOG_EXECUTABLE) do + describe file(rsyslog_executable) do it { should be_file } it { should be_executable } end # Make sure that rsyslog starts with the machine - describe file('/etc/init.d/rsyslog'), :rsyslog_check do + describe file("/etc/init.d/rsyslog"), :rsyslog_check do it { should be_executable } end - describe service('rsyslog') do + describe service("rsyslog") do it { should be_enabled_for_level(2) } it { should be_enabled_for_level(3) } it { should be_enabled_for_level(4) } diff --git a/bosh-stemcell/spec/support/shellout_type_assertions.rb b/bosh-stemcell/spec/support/shellout_type_assertions.rb index dddf9e885a..4f522fb469 100644 --- a/bosh-stemcell/spec/support/shellout_type_assertions.rb +++ b/bosh-stemcell/spec/support/shellout_type_assertions.rb @@ -1,14 +1,14 @@ -require 'shellout_types/file' -require 'shellout_types/package' -require 'shellout_types/user' -require 'shellout_types/command' -require 'shellout_types/service' -require 'shellout_types/group' -require 'shellout_types/chroot' +require "shellout_types/file" +require "shellout_types/package" +require "shellout_types/user" +require "shellout_types/command" +require "shellout_types/service" +require "shellout_types/group" +require "shellout_types/chroot" module ShelloutTypes module Assertions - def file(file_path, chroot=ShelloutTypes::Chroot.new) + def file(file_path, chroot = ShelloutTypes::Chroot.new) ShelloutTypes::File.new(file_path, chroot) end @@ -33,7 +33,7 @@ def group(group_name) end def no_chroot - ShelloutTypes::Chroot.new('/') + ShelloutTypes::Chroot.new("/") end end end diff --git a/bosh-stemcell/spec/support/spec_assets.rb b/bosh-stemcell/spec/support/spec_assets.rb index 5f79b3ebdd..c80a0d90db 100644 --- a/bosh-stemcell/spec/support/spec_assets.rb +++ b/bosh-stemcell/spec/support/spec_assets.rb @@ -1,9 +1,9 @@ -require 'support/shellout_type_assertions' +require "support/shellout_type_assertions" module Bosh::Stemcell module SpecAssets def spec_asset(name) - File.expand_path(File.join('..', 'assets', name), File.dirname(__FILE__)) + File.expand_path(File.join("..", "assets", name), File.dirname(__FILE__)) end end end diff --git a/bosh-stemcell/spec/support/spec_ordering.rb b/bosh-stemcell/spec/support/spec_ordering.rb index 4a8d2f987e..4b660c6412 100644 --- a/bosh-stemcell/spec/support/spec_ordering.rb +++ b/bosh-stemcell/spec/support/spec_ordering.rb @@ -1,4 +1,3 @@ - RSpec.configure do |config| config.register_ordering(:global) do |list| # make sure that stig test case check will be run at last diff --git a/bosh-stemcell/spec/support/stemcell_image.rb b/bosh-stemcell/spec/support/stemcell_image.rb index ff2f06d556..89e32406c3 100644 --- a/bosh-stemcell/spec/support/stemcell_image.rb +++ b/bosh-stemcell/spec/support/stemcell_image.rb @@ -1,23 +1,23 @@ -require 'bosh/stemcell/disk_image' -require 'shellout_types/chroot' -require_relative 'shellout_type_assertions' +require "bosh/stemcell/disk_image" +require "shellout_types/chroot" +require_relative "shellout_type_assertions" RSpec.configure do |config| # do not run stemcell image tests when shellout types tests are executed. unless config.inclusion_filter[:shellout_types] - if ENV['STEMCELL_IMAGE'] - config.filter_run_including stemcell_image: true - disk_image = Bosh::Stemcell::DiskImage.new(image_file_path: ENV['STEMCELL_IMAGE']) - config.before(:suite) do |example| - disk_image.mount - ShelloutTypes::Chroot.chroot_dir = disk_image.image_mount_point - end - config.after(:suite) do |example| - ShelloutTypes::Chroot.unmount_proc - disk_image.unmount - end + if ENV["STEMCELL_IMAGE"] + config.filter_run_including stemcell_image: true + disk_image = Bosh::Stemcell::DiskImage.new(image_file_path: ENV["STEMCELL_IMAGE"]) + config.before(:suite) do |example| + disk_image.mount + ShelloutTypes::Chroot.chroot_dir = disk_image.image_mount_point + end + config.after(:suite) do |example| + ShelloutTypes::Chroot.unmount_proc + disk_image.unmount + end else - warning = 'All stemcell_image tests are being skipped. STEMCELL_IMAGE needs to be set' + warning = "All stemcell_image tests are being skipped. STEMCELL_IMAGE needs to be set" puts RSpec::Core::Formatters::ConsoleCodes.wrap(warning, :yellow) config.filter_run_excluding stemcell_image: true end diff --git a/bosh-stemcell/spec/support/stemcell_shared_examples.rb b/bosh-stemcell/spec/support/stemcell_shared_examples.rb index 30636e87b8..d8e7bde462 100644 --- a/bosh-stemcell/spec/support/stemcell_shared_examples.rb +++ b/bosh-stemcell/spec/support/stemcell_shared_examples.rb @@ -1,88 +1,87 @@ -require 'rspec' +require "rspec" -shared_examples_for 'All Stemcells' do - - context 'building a new stemcell' do - describe file '/var/vcap/bosh/etc/stemcell_version' do - let(:expected_version) { ENV['CANDIDATE_BUILD_NUMBER'] || '0000' } +shared_examples_for "All Stemcells" do + context "building a new stemcell" do + describe file "/var/vcap/bosh/etc/stemcell_version" do + let(:expected_version) { ENV["CANDIDATE_BUILD_NUMBER"] || "0000" } it { should be_file } its(:content) { should eq expected_version } end - describe file '/var/vcap/bosh/etc/stemcell_git_sha1' do + describe file "/var/vcap/bosh/etc/stemcell_git_sha1" do it { should be_file } its(:content) { should match '^[0-9a-f]{40}\+?$' } end - describe command('ls -l /etc/ssh/*_key*') do - its(:stderr) { should match /No such file or directory/ } + describe command("ls -l /etc/ssh/*_key*") do + its(:stderr) { should match(/No such file or directory/) } end end - context 'disable remote host login (stig: V-38491)' do - describe command('find /home -name .rhosts') do - its (:stdout) { should eq('') } + context "disable remote host login (stig: V-38491)" do + describe command("find /home -name .rhosts") do + its(:stdout) { should eq("") } end - describe file('/etc/hosts.equiv') do + describe file("/etc/hosts.equiv") do it { should_not be_file } end end - context 'system library files' do - describe file('/lib') do - it('should be owned by root user (stig: V-38466)') { should be_owned_by('root') } + context "system library files" do + describe file("/lib") do + it("should be owned by root user (stig: V-38466)") { should be_owned_by("root") } end - describe file('/lib64') do - it('should be owned by root user (stig: V-38466)') { should be_owned_by('root') } + describe file("/lib64") do + it("should be owned by root user (stig: V-38466)") { should be_owned_by("root") } end - describe file('/usr/lib') do - it('should be owned by root user (stig: V-38466)') { should be_owned_by('root') } + describe file("/usr/lib") do + it("should be owned by root user (stig: V-38466)") { should be_owned_by("root") } end describe command('if [ -e /usr/lib64 ]; then stat -c "%U" /usr/lib64 ; else echo "root" ; fi') do - its (:stdout) { should eq("root\n") } + its(:stdout) { should eq("root\n") } end end - describe file('/var/vcap/micro_bosh/data/cache') do - it('should still be created') { should be_directory } + describe file("/var/vcap/micro_bosh/data/cache") do + it("should still be created") { should be_directory } end - context 'Library files must have mode 0755 or less permissive (stig: V-38465)' do + context "Library files must have mode 0755 or less permissive (stig: V-38465)" do describe command("find -L /lib /lib64 /usr/lib $( [ ! -e /usr/lib64 ] || echo '/usr/lib64' ) -perm /022 -type f") do - its (:stdout) { should eq('') } + its(:stdout) { should eq("") } end end - context 'System command files must have mode 0755 or less permissive (stig: V-38469)' do - describe command('find -L /bin /usr/bin /usr/local/bin /sbin /usr/sbin /usr/local/sbin -perm /022 -type f') do - its (:stdout) { should eq('') } + context "System command files must have mode 0755 or less permissive (stig: V-38469)" do + describe command("find -L /bin /usr/bin /usr/local/bin /sbin /usr/sbin /usr/local/sbin -perm /022 -type f") do + its(:stdout) { should eq("") } end end - context 'all system command files must be owned by root (stig: V-38472)' do - describe command('find -L /bin /usr/bin /usr/local/bin /sbin /usr/sbin /usr/local/sbin ! -user root') do - its (:stdout) { should eq('') } + context "all system command files must be owned by root (stig: V-38472)" do + describe command("find -L /bin /usr/bin /usr/local/bin /sbin /usr/sbin /usr/local/sbin ! -user root") do + its(:stdout) { should eq("") } end end - context 'There must be no .netrc files on the system (stig: V-38619)' do - describe command('sudo find /root /home /var/vcap -xdev -name .netrc') do + context "There must be no .netrc files on the system (stig: V-38619)" do + describe command("sudo find /root /home /var/vcap -xdev -name .netrc") do # its (:stdout) { should eq('') } - it 'does not include .netrc' do + it "does not include .netrc" do results = subject.stdout.split("\n").reject { |str| str.match(/^Last login/) } expect(results).to eq [] end end end - context 'rsyslog conf directory only contains the builder-specified config files', exclude_on_google: true do - describe command('ls -A /etc/rsyslog.d') do - its (:stdout) do + context "rsyslog conf directory only contains the builder-specified config files", exclude_on_google: true do + describe command("ls -A /etc/rsyslog.d") do + its(:stdout) do should eq(<<~FILELIST) 50-default.conf 90-bosh-agent.conf @@ -91,49 +90,49 @@ end end - describe file('/var/vcap/bosh/bin/restart_networking') do + describe file("/var/vcap/bosh/bin/restart_networking") do it { should be_file } it { should be_executable } - it { should be_owned_by('root') } - its(:group) { should eq('root') } + it { should be_owned_by("root") } + its(:group) { should eq("root") } - context 'restarts systemd-networkd on non-warden images', { - exclude_on_warden: true, + context "restarts systemd-networkd on non-warden images", { + exclude_on_warden: true } do - its(:content) { should eql(< "${REPO_PARENT}/candidate-build-number/number" +echo "${CANDIDATE_BUILD_NUMBER}" > "${REPO_PARENT}/candidate-build-number/number" mkdir -p "$( dirname "$meta4_path" )" rm -f "$meta4_path" meta4 create --metalink="$meta4_path" -if [ -e "${REPO_PARENT}/bosh-linux-stemcell-builder/tmp"/*-raw.tgz ] ; then +raw_images=( "${REPO_ROOT}/tmp"/*-raw.tgz ) +if [ "${#raw_images[@]}" -ge 2 ]; then + echo "Found more than one raw image: '${raw_images[*]}'" >&2 + exit 1 +fi + +if [ -e "${raw_images[0]}" ] ; then # openstack currently publishes raw files raw_stemcell_filename="${stemcell_name}-raw.tgz" - mv "${REPO_PARENT}/bosh-linux-stemcell-builder/tmp"/*-raw.tgz "${REPO_PARENT}/stemcell/${raw_stemcell_filename}" + mv "${REPO_ROOT}/tmp"/*-raw.tgz "${REPO_PARENT}/stemcell/${raw_stemcell_filename}" - meta4 import-file --metalink="$meta4_path" --version="$CANDIDATE_BUILD_NUMBER" "${REPO_PARENT}/stemcell/${raw_stemcell_filename}" + meta4 import-file --metalink="$meta4_path" --version="${CANDIDATE_BUILD_NUMBER}" "${REPO_PARENT}/stemcell/${raw_stemcell_filename}" meta4 file-set-url --metalink="$meta4_path" --file="${raw_stemcell_filename}" "https://${S3_API_ENDPOINT}/${STEMCELL_BUCKET}/${IAAS}/${raw_stemcell_filename}" fi stemcell_filename="${stemcell_name}.tgz" -mv "${REPO_PARENT}/bosh-linux-stemcell-builder/tmp/${stemcell_filename}" "${REPO_PARENT}/stemcell/${stemcell_filename}" +mv "${REPO_ROOT}/tmp/${stemcell_filename}" "${REPO_PARENT}/stemcell/${stemcell_filename}" -meta4 import-file --metalink="$meta4_path" --version="$CANDIDATE_BUILD_NUMBER" "${REPO_PARENT}/stemcell/${stemcell_filename}" +meta4 import-file --metalink="$meta4_path" --version="${CANDIDATE_BUILD_NUMBER}" "${REPO_PARENT}/stemcell/${stemcell_filename}" meta4 file-set-url --metalink="$meta4_path" --file="${stemcell_filename}" "https://${S3_API_ENDPOINT}/${STEMCELL_BUCKET}/${IAAS}/${stemcell_filename}" # just in case we need to debug/verify the live results @@ -131,4 +136,4 @@ cd "${REPO_PARENT}/stemcells-index-output" git add -A git config --global user.email "ci@localhost" git config --global user.name "CI Bot" -git commit -m "dev: $OS_NAME-$OS_VERSION/$CANDIDATE_BUILD_NUMBER ($IAAS-$HYPERVISOR)" +git commit -m "dev: ${OS_NAME}-${OS_VERSION}/${CANDIDATE_BUILD_NUMBER} ($IAAS-$HYPERVISOR)" diff --git a/ci/tasks/bump-bosh-agent.sh b/ci/tasks/bump-bosh-agent.sh index e5ee902164..ecf8fa91bc 100755 --- a/ci/tasks/bump-bosh-agent.sh +++ b/ci/tasks/bump-bosh-agent.sh @@ -10,7 +10,7 @@ if [[ -n "${DEBUG:-}" ]]; then export BOSH_LOG_PATH="${BOSH_LOG_PATH:-${REPO_PARENT}/bosh-debug.log}" fi -git clone "${REPO_PARENT}/bosh-linux-stemcell-builder" "${REPO_PARENT}/bosh-linux-stemcell-builder-out" +git clone "${REPO_ROOT}" "${REPO_PARENT}/bosh-linux-stemcell-builder-out" version=$( cat "${REPO_PARENT}/bosh-agent/.resource/version" ) diff --git a/ci/tasks/bump-bosh-blobstore-cli.sh b/ci/tasks/bump-bosh-blobstore-cli.sh index f82d23ca1a..e37bfb6c51 100755 --- a/ci/tasks/bump-bosh-blobstore-cli.sh +++ b/ci/tasks/bump-bosh-blobstore-cli.sh @@ -10,7 +10,7 @@ if [[ -n "${DEBUG:-}" ]]; then export BOSH_LOG_PATH="${BOSH_LOG_PATH:-${REPO_PARENT}/bosh-debug.log}" fi -git clone "${REPO_PARENT}/bosh-linux-stemcell-builder" "${REPO_PARENT}/bosh-linux-stemcell-builder-out" +git clone "${REPO_ROOT}" "${REPO_PARENT}/bosh-linux-stemcell-builder-out" url=$(cat "${REPO_PARENT}/bosh-blobstore-cli/url") version=$(cat "${REPO_PARENT}/bosh-blobstore-cli/version") diff --git a/ci/tasks/commit-build-time.sh b/ci/tasks/commit-build-time.sh index 3d8688a1b9..e1850726c3 100755 --- a/ci/tasks/commit-build-time.sh +++ b/ci/tasks/commit-build-time.sh @@ -13,7 +13,7 @@ fi build_time="$(cat "${REPO_PARENT}/build-time/timestamp")" formatted_build_time="$(date --date "${build_time%.*}" +%Y%m%dT%H%M%SZ)" -pushd "${REPO_PARENT}/bosh-linux-stemcell-builder" +pushd "${REPO_ROOT}" echo "${formatted_build_time}" > build_time.txt git add -A git config --global user.email "ci@localhost" diff --git a/ci/tasks/os-images/build.sh b/ci/tasks/os-images/build.sh index 3943f88c6f..ce6af26d0c 100755 --- a/ci/tasks/os-images/build.sh +++ b/ci/tasks/os-images/build.sh @@ -10,8 +10,6 @@ if [[ -n "${DEBUG:-}" ]]; then export BOSH_LOG_PATH="${BOSH_LOG_PATH:-${REPO_PARENT}/bosh-debug.log}" fi -cd "${REPO_PARENT}/bosh-linux-stemcell-builder" - function check_param() { local name=$1 local value=$(eval echo '$'$name) @@ -33,7 +31,12 @@ fi sudo chown -R ubuntu . sudo chown -R ubuntu:ubuntu /mnt sudo chmod u+s "$(which sudo)" -bundle install --local + sudo --preserve-env --set-home --user ubuntu -- /bin/bash --login -i <