Skip to content

Commit

Permalink
Merge pull request #277 from pocke/user-option-file
Browse files Browse the repository at this point in the history
Make `send_file` aware of `user` option
  • Loading branch information
sue445 authored Jan 18, 2019
2 parents efda69f + acdba48 commit bf51e19
Show file tree
Hide file tree
Showing 7 changed files with 305 additions and 22 deletions.
12 changes: 10 additions & 2 deletions lib/itamae/backend.rb
Original file line number Diff line number Diff line change
Expand Up @@ -98,15 +98,23 @@ def receive_file(src, dst = nil)
@backend.receive_file(src, dst)
end

def send_file(src, dst)
def send_file(src, dst, user: nil)
Itamae.logger.debug "Sending a file from '#{src}' to '#{dst}'..."
unless ::File.exist?(src)
raise SourceNotExistError, "The file '#{src}' doesn't exist."
end
unless ::File.file?(src)
raise SourceNotExistError, "'#{src}' is not a file."
end
@backend.send_file(src, dst)

if self.instance_of?(Backend::Local)
read_command = build_command("cat #{src.shellescape}", {})
write_command = build_command("cat > #{dst.shellescape}", user: user)
command = [read_command, write_command].join(' | ')
run_command(command)
else
@backend.send_file(src, dst)
end
end

def send_directory(src, dst)
Expand Down
4 changes: 2 additions & 2 deletions lib/itamae/resource/file.rb
Original file line number Diff line number Diff line change
Expand Up @@ -183,12 +183,12 @@ def send_tempfile

if backend.is_a?(Itamae::Backend::Docker)
run_command(["mkdir", @temppath])
backend.send_file(src, @temppath)
backend.send_file(src, @temppath, user: attributes.user)
@temppath = ::File.join(@temppath, ::File.basename(src))
else
run_command(["touch", @temppath])
run_specinfra(:change_file_mode, @temppath, '0600')
backend.send_file(src, @temppath)
backend.send_file(src, @temppath, user: attributes.user)
end

run_specinfra(:change_file_mode, @temppath, '0600')
Expand Down
6 changes: 6 additions & 0 deletions spec/integration/local_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
describe file('/tmp/file_as_ordinary_user') do
it { should be_file }
it { should be_owned_by "itamae" }
it { should be_grouped_into "itamae" }
end

108 changes: 108 additions & 0 deletions spec/integration/ordinary_user_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
require 'spec_helper'

describe file('/tmp/remote_file') do
it { should be_file }
it { should be_owned_by "ordinary_san" }
it { should be_grouped_into "ordinary_san" }
its(:content) { should match(/Hello Itamae/) }
end

describe file('/tmp/remote_file_root') do
it { should be_file }
it { should be_owned_by "root" }
it { should be_grouped_into "root" }
its(:content) { should match(/Hello Itamae/) }
end

%w[/tmp/remote_file_another_ordinary /tmp/remote_file_another_ordinary_with_root].each do |path|
describe file(path) do
it { should be_file }
it { should be_owned_by "itamae" }
it { should be_grouped_into "itamae" }
its(:content) { should match(/Hello Itamae/) }
end
end

###

describe file('/tmp/file') do
it { should be_file }
it { should be_owned_by "ordinary_san" }
it { should be_grouped_into "ordinary_san" }
its(:content) { should match(/Hello World/) }
end

describe file('/tmp/file_root') do
it { should be_file }
it { should be_owned_by "root" }
it { should be_grouped_into "root" }
its(:content) { should match(/Hello World/) }
end

%w[/tmp/file_another_ordinary /tmp/file_another_ordinary_with_root].each do |path|
describe file(path) do
it { should be_file }
it { should be_owned_by "itamae" }
it { should be_grouped_into "itamae" }
its(:content) { should match(/Hello World/) }
end
end

###

describe file('/tmp/template') do
it { should be_file }
it { should be_owned_by "ordinary_san" }
it { should be_grouped_into "ordinary_san" }
its(:content) { should match(/Hello/) }
its(:content) { should match(/Good bye/) }
its(:content) { should match(/^total memory: \d+kB$/) }
its(:content) { should match(/^uninitialized node key: $/) }
end

describe file('/tmp/template_root') do
it { should be_file }
it { should be_owned_by "root" }
it { should be_grouped_into "root" }
its(:content) { should match(/Hello/) }
its(:content) { should match(/Good bye/) }
its(:content) { should match(/^total memory: \d+kB$/) }
its(:content) { should match(/^uninitialized node key: $/) }
end

%w[/tmp/template_another_ordinary /tmp/template_another_ordinary_with_root].each do |path|
describe file(path) do
it { should be_file }
it { should be_owned_by "itamae" }
it { should be_grouped_into "itamae" }
its(:content) { should match(/Hello/) }
its(:content) { should match(/Good bye/) }
its(:content) { should match(/^total memory: \d+kB$/) }
its(:content) { should match(/^uninitialized node key: $/) }
end
end

###

describe file('/tmp/http_request.html') do
it { should be_file }
it { should be_owned_by "ordinary_san" }
it { should be_grouped_into "ordinary_san" }
its(:content) { should match(/"from":\s*"itamae"/) }
end

describe file('/tmp/http_request_root.html') do
it { should be_file }
it { should be_owned_by "root" }
it { should be_grouped_into "root" }
its(:content) { should match(/"from":\s*"itamae"/) }
end

%w[/tmp/http_request_another_ordinary.html /tmp/http_request_another_ordinary_with_root.html].each do |path|
describe file(path) do
it { should be_file }
it { should be_owned_by "itamae" }
it { should be_grouped_into "itamae" }
its(:content) { should match(/"from":\s*"itamae"/) }
end
end
11 changes: 11 additions & 0 deletions spec/integration/recipes/local.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,14 @@
version '2.0.0'
options ['--no-document']
end

######

# Docker backend raises an error with `user` option, so it tests only on `itamae local`.
# After fix this error, please move this code and the spec to `default.rb`.
file "/tmp/file_as_ordinary_user" do
content "Hello World"
user "itamae"
owner "itamae"
group "itamae"
end
109 changes: 109 additions & 0 deletions spec/integration/recipes/ordinary_user.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
remote_file "/tmp/remote_file" do
source "hello.txt"
end

remote_file "/tmp/remote_file_root" do
user 'root'
owner 'root'
group 'root'
source "hello.txt"
end

remote_file "/tmp/remote_file_another_ordinary" do
user 'itamae'
owner 'itamae'
group 'itamae'
source "hello.txt"
end

remote_file "/tmp/remote_file_another_ordinary_with_root" do
user 'root'
owner 'itamae'
group 'itamae'
source "hello.txt"
end

###

file "/tmp/file" do
content "Hello World"
end

file "/tmp/file_root" do
user 'root'
owner 'root'
group 'root'
content 'Hello World'
end

file "/tmp/file_another_ordinary" do
user 'itamae'
owner 'itamae'
group 'itamae'
content 'Hello World'
end

file "/tmp/file_another_ordinary_with_root" do
user 'root'
owner 'itamae'
group 'itamae'
content 'Hello World'
end

###

template "/tmp/template" do
source "hello.erb"
variables goodbye: "Good bye"
end

template "/tmp/template_root" do
user 'root'
owner 'root'
group 'root'
source "hello.erb"
variables goodbye: "Good bye"
end

template "/tmp/template_another_ordinary" do
user 'itamae'
owner 'itamae'
group 'itamae'
source "hello.erb"
variables goodbye: "Good bye"
end

template "/tmp/template_another_ordinary_with_root" do
user 'root'
owner 'itamae'
group 'itamae'
source "hello.erb"
variables goodbye: "Good bye"
end

###

http_request "/tmp/http_request.html" do
url "https://httpbin.org/get?from=itamae"
end

http_request "/tmp/http_request_root.html" do
user 'root'
owner 'root'
group 'root'
url "https://httpbin.org/get?from=itamae"
end

http_request "/tmp/http_request_another_ordinary.html" do
user 'itamae'
owner 'itamae'
group 'itamae'
url "https://httpbin.org/get?from=itamae"
end

http_request "/tmp/http_request_another_ordinary_with_root.html" do
user 'root'
owner 'itamae'
group 'itamae'
url "https://httpbin.org/get?from=itamae"
end
77 changes: 59 additions & 18 deletions tasks/integration_local_spec.rb
Original file line number Diff line number Diff line change
@@ -1,37 +1,76 @@
desc 'Run integration test on `itamae local` command'
task 'spec:integration:local' do
next if RUBY_DESCRIPTION.include?('dev')
desc 'Run all integration tests on `itamae local` command'
task 'spec:integration:local' => ['spec:integration:local:main', 'spec:integration:local:ordinary_user']

IntegrationLocalSpecRunner.new(
[
namespace 'spec:integration:local' do
desc 'Run main integration test with `itamae local`'
task 'main' do
if RUBY_DESCRIPTION.include?('dev')
$stderr.puts "This integration test is skipped with unreleased Ruby."
$stderr.puts "Use released Ruby to execute this integration test."
next
end

IntegrationLocalSpecRunner.new(
[
"spec/integration/recipes/default.rb",
"spec/integration/recipes/default2.rb",
"spec/integration/recipes/redefine.rb",
"spec/integration/recipes/local.rb",
[
"spec/integration/recipes/default.rb",
"spec/integration/recipes/default2.rb",
"spec/integration/recipes/redefine.rb",
"spec/integration/recipes/local.rb",
],
[
"--dry-run",
"spec/integration/recipes/dry_run.rb",
],
],
['spec/integration/default_spec.rb']
).run

end

desc 'Run integration test for ordinary user with `itamae local`'
task 'ordinary_user' do
if RUBY_DESCRIPTION.include?('dev')
$stderr.puts "This integration test is skipped with unreleased Ruby."
$stderr.puts "Use released Ruby to execute this integration test."
next
end

runner = IntegrationLocalSpecRunner.new(
[
"--dry-run",
"spec/integration/recipes/dry_run.rb",
[
"--dry-run",
"spec/integration/recipes/ordinary_user.rb",
],
[
"spec/integration/recipes/ordinary_user.rb"
],
],
],
['spec/integration/default_spec.rb']
).run
['spec/integration/ordinary_user_spec.rb'],
user: 'ordinary_san'
)
runner.docker_exec 'useradd', 'ordinary_san', '-p', '*'
runner.docker_exec 'useradd', 'itamae', '-p', '*', '--create-home'
runner.docker_exec 'sh', '-c', 'echo "ordinary_san ALL=(ALL:ALL) NOPASSWD: ALL" >> /etc/sudoers'
runner.run
end
end

class IntegrationLocalSpecRunner
CONTAINER_NAME = 'itamae'
include FileUtils

def initialize(suites, specs, ruby_version: RUBY_VERSION.split('.')[0..1].join('.'))
def initialize(suites, specs, ruby_version: RUBY_VERSION.split('.')[0..1].join('.'), user: nil)
@suites = suites
@specs = specs
@ruby_version = ruby_version
end
@user = user

def run
docker_run
prepare
end

def run
provision
serverspec
clean_docker_container
Expand All @@ -57,7 +96,9 @@ def provision
cmd << "-j" << "spec/integration/recipes/node.json"
cmd += suite

docker_exec(*cmd, options: %w[--workdir /itamae])
options = %w[--workdir /itamae]
options.push('--user', @user) if @user
docker_exec(*cmd, options: options)
end
end

Expand Down

0 comments on commit bf51e19

Please sign in to comment.