on_container 0.0.1 → 0.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/README.md +65 -1
- data/lib/on_container/dev/active_record_ops.rb +64 -0
- data/lib/on_container/dev/bundler_ops.rb +40 -0
- data/lib/on_container/dev/container_command_ops.rb +16 -0
- data/lib/on_container/dev/node_modules_ops.rb +44 -0
- data/lib/on_container/dev/rails.rb +19 -0
- data/lib/on_container/dev/rails_ops.rb +15 -0
- data/lib/on_container/dev/setup_ops.rb +47 -0
- data/lib/on_container/load_env_secrets.rb +50 -0
- data/lib/on_container/ops/service_connection_checks.rb +41 -0
- data/lib/on_container/step_down_from_root.rb +3 -3
- data/lib/on_container/version.rb +1 -1
- data/spec/on_container_spec.rb +5 -0
- data/spec/spec_helper.rb +14 -0
- data/spec/step_down_from_root_spec.rb +63 -0
- metadata +20 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 49a6b84a56344cf0119b822fd9f12277bb66fe70
|
4
|
+
data.tar.gz: 6676d161e20a802d3f75c765e04bfd6b0969972c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9aa5a059a7ba11f6f658c08d32ead851ab667ad3c894f5442cd795febc3c8e6c9e65f1e8d126708a6a2a0702d18661e043a600768522caadc8cf90ae119f0c90
|
7
|
+
data.tar.gz: 6916cb665fa674c90a43634f2cf5bce4632c105c862f44caf8b08200b486440f305fc9f2ca01af4220ba59e87ef15b43969072b900e0c198f290c336ff341580
|
data/README.md
CHANGED
@@ -22,7 +22,71 @@ Or install it yourself as:
|
|
22
22
|
|
23
23
|
## Usage
|
24
24
|
|
25
|
-
|
25
|
+
### Development Routines & Docker Entrypoint Scripts
|
26
|
+
|
27
|
+
We use some routines included in this gem to create compelling development entrypoint scripts for docker development containers.
|
28
|
+
|
29
|
+
In this example, we'll be using the `on_container/dev/rails` routine bundle to create our dev entrypoint:
|
30
|
+
|
31
|
+
```ruby
|
32
|
+
#!/usr/bin/env ruby
|
33
|
+
|
34
|
+
# frozen_string_literal: true
|
35
|
+
|
36
|
+
require 'on_container/dev/rails'
|
37
|
+
|
38
|
+
set_given_or_default_command
|
39
|
+
|
40
|
+
# `on_setup_lock_acquired` prevents multiple app containers from running
|
41
|
+
# the setup process concurrently:
|
42
|
+
on_setup_lock_acquired do
|
43
|
+
ensure_project_gems_are_installed
|
44
|
+
ensure_project_node_packages_are_installed
|
45
|
+
|
46
|
+
wait_for_service_to_accept_connections 'tcp://postgres:5432'
|
47
|
+
setup_activerecord_database unless activerecord_database_ready?
|
48
|
+
|
49
|
+
remove_rails_pidfile if rails_server?
|
50
|
+
end if command_requires_setup?
|
51
|
+
|
52
|
+
execute_given_or_default_command
|
53
|
+
```
|
54
|
+
|
55
|
+
### Loading secrets into environment variables, and inserting credentials into URL environment variables
|
56
|
+
|
57
|
+
When using Docker Swarm, the secrets are loaded as files mounted into the container's filesystem.
|
58
|
+
|
59
|
+
The `on_container/load_env_secrets` runs a couple of routines that reads these files into environment variables.
|
60
|
+
|
61
|
+
For our Rails example app, we added the following line to the `config/boot.rb` file:
|
62
|
+
|
63
|
+
```ruby
|
64
|
+
# frozen_string_literal: true
|
65
|
+
|
66
|
+
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__)
|
67
|
+
|
68
|
+
require 'on_container/load_env_secrets' # Load secrets injected by Kubernetes/Swarm
|
69
|
+
|
70
|
+
require 'bundler/setup' # Set up gems listed in the Gemfile.
|
71
|
+
require 'bootsnap/setup' # Speed up boot time by caching expensive operations.
|
72
|
+
```
|
73
|
+
|
74
|
+
The `on_container/load_env_secrets` also merges any credential available in environment variables into any matching
|
75
|
+
`_URL` environment variable. For example, consider the following environment variables:
|
76
|
+
|
77
|
+
```shell
|
78
|
+
DATABASE_URL=postgres://postgres:5432/?encoding=unicode
|
79
|
+
DATABASE_USER=postgres
|
80
|
+
DATABASE_PASS=3x4mpl3P455w0rd
|
81
|
+
```
|
82
|
+
|
83
|
+
The routine will merge `DATABASE_USER` and `DATABASE_PASS` into `DATABASE_URL`:
|
84
|
+
|
85
|
+
```ruby
|
86
|
+
puts ENV['DATABASE_URL']
|
87
|
+
> postgres://postgres:3x4mpl3P455w0rd@postgres:5432/?encoding=unicode
|
88
|
+
```
|
89
|
+
|
26
90
|
|
27
91
|
## Development
|
28
92
|
|
@@ -0,0 +1,64 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
|
4
|
+
module OnContainer
|
5
|
+
module Dev
|
6
|
+
module ActiveRecordOps
|
7
|
+
def app_setup_wait
|
8
|
+
ENV.fetch('APP_SETUP_WAIT', '5').to_i
|
9
|
+
end
|
10
|
+
|
11
|
+
def parse_activerecord_config_file
|
12
|
+
require 'erb'
|
13
|
+
require 'yaml'
|
14
|
+
|
15
|
+
database_yaml = Pathname.new File.expand_path('config/database.yml')
|
16
|
+
loaded_yaml = YAML.load(ERB.new(database_yaml.read).result) || {}
|
17
|
+
shared = loaded_yaml.delete('shared')
|
18
|
+
|
19
|
+
loaded_yaml.each { |_k, values| values.reverse_merge!(shared) } if shared
|
20
|
+
Hash.new(shared).merge(loaded_yaml)
|
21
|
+
end
|
22
|
+
|
23
|
+
def activerecord_config
|
24
|
+
@activerecord_config ||= parse_activerecord_config_file
|
25
|
+
.fetch ENV.fetch('RAILS_ENV', 'development')
|
26
|
+
end
|
27
|
+
|
28
|
+
def establish_activerecord_database_connection
|
29
|
+
require 'active_record' unless defined?(ActiveRecord)
|
30
|
+
ActiveRecord::Base.establish_connection activerecord_config
|
31
|
+
ActiveRecord::Base.connection_pool.with_connection { |connection| }
|
32
|
+
end
|
33
|
+
|
34
|
+
def activerecord_database_initialized?
|
35
|
+
ActiveRecord::Base.connection_pool.with_connection do |connection|
|
36
|
+
connection.data_source_exists? :schema_migrations
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def activerecord_database_ready?
|
41
|
+
connection_tries ||= 3
|
42
|
+
|
43
|
+
establish_activerecord_database_connection
|
44
|
+
activerecord_database_initialized?
|
45
|
+
|
46
|
+
rescue PG::ConnectionBad
|
47
|
+
unless (connection_tries -= 1).zero?
|
48
|
+
puts "Retrying DB connection #{connection_tries} more times..."
|
49
|
+
sleep app_setup_wait
|
50
|
+
retry
|
51
|
+
end
|
52
|
+
false
|
53
|
+
|
54
|
+
rescue ActiveRecord::NoDatabaseError
|
55
|
+
false
|
56
|
+
end
|
57
|
+
|
58
|
+
def setup_activerecord_database
|
59
|
+
system 'rails db:setup'
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module OnContainer
|
4
|
+
module Dev
|
5
|
+
module BundlerOps
|
6
|
+
def bundle_path
|
7
|
+
'/usr/local/bundle'
|
8
|
+
end
|
9
|
+
|
10
|
+
def bundle_owner_id
|
11
|
+
File.stat(bundle_path).uid
|
12
|
+
end
|
13
|
+
|
14
|
+
def current_user_id
|
15
|
+
Etc.getpwuid.uid
|
16
|
+
end
|
17
|
+
|
18
|
+
def bundle_belongs_to_current_user?
|
19
|
+
bundle_owner_id == current_user_id
|
20
|
+
end
|
21
|
+
|
22
|
+
def make_bundle_belong_to_current_user
|
23
|
+
target_ownership = "#{current_user_id}:#{current_user_id}"
|
24
|
+
system "sudo chown -R #{target_ownership} #{bundle_path}"
|
25
|
+
end
|
26
|
+
|
27
|
+
def ensure_bundle_belongs_to_current_user
|
28
|
+
return if bundle_belongs_to_current_user?
|
29
|
+
|
30
|
+
make_bundle_belong_to_current_user
|
31
|
+
end
|
32
|
+
|
33
|
+
def ensure_project_gems_are_installed
|
34
|
+
ensure_bundle_belongs_to_current_user
|
35
|
+
|
36
|
+
system 'bundle check || bundle install'
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module OnContainer
|
4
|
+
module Dev
|
5
|
+
module ContainerCommandOps
|
6
|
+
def set_given_or_default_command
|
7
|
+
ARGV.concat %w[rails server -p 3000 -b 0.0.0.0] if ARGV.empty?
|
8
|
+
end
|
9
|
+
|
10
|
+
def execute_given_or_default_command
|
11
|
+
exec(*ARGV)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'etc'
|
4
|
+
|
5
|
+
module OnContainer
|
6
|
+
module Dev
|
7
|
+
module NodeModulesOps
|
8
|
+
APP_PATH = File.expand_path '.'
|
9
|
+
|
10
|
+
def node_modules_path
|
11
|
+
"#{APP_PATH}/node_modules"
|
12
|
+
end
|
13
|
+
|
14
|
+
def node_modules_owner_id
|
15
|
+
File.stat(node_modules_path).uid
|
16
|
+
end
|
17
|
+
|
18
|
+
def current_user_id
|
19
|
+
Etc.getpwuid.uid
|
20
|
+
end
|
21
|
+
|
22
|
+
def node_modules_belong_to_current_user?
|
23
|
+
node_modules_owner_id == current_user_id
|
24
|
+
end
|
25
|
+
|
26
|
+
def make_node_modules_belong_to_current_user
|
27
|
+
target_ownership = "#{current_user_id}:#{current_user_id}"
|
28
|
+
system "sudo chown -R #{target_ownership} #{node_modules_path}"
|
29
|
+
end
|
30
|
+
|
31
|
+
def ensure_node_modules_belong_to_current_user
|
32
|
+
return if node_modules_belong_to_current_user?
|
33
|
+
|
34
|
+
make_node_modules_belong_to_current_user
|
35
|
+
end
|
36
|
+
|
37
|
+
def ensure_project_node_packages_are_installed
|
38
|
+
ensure_node_modules_belong_to_current_user
|
39
|
+
|
40
|
+
system 'yarn check --integrity || yarn install'
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'on_container/dev/rails_ops'
|
4
|
+
require 'on_container/dev/setup_ops'
|
5
|
+
require 'on_container/dev/bundler_ops'
|
6
|
+
require 'on_container/dev/node_modules_ops'
|
7
|
+
require 'on_container/dev/active_record_ops'
|
8
|
+
require 'on_container/dev/container_command_ops'
|
9
|
+
|
10
|
+
include OnContainer::Dev::RailsOps
|
11
|
+
include OnContainer::Dev::SetupOps
|
12
|
+
include OnContainer::Dev::BundlerOps
|
13
|
+
include OnContainer::Dev::NodeModulesOps
|
14
|
+
include OnContainer::Dev::ActiveRecordOps
|
15
|
+
include OnContainer::Dev::ContainerCommandOps
|
16
|
+
|
17
|
+
require 'on_container/ops/service_connection_checks'
|
18
|
+
|
19
|
+
include OnContainer::Ops::ServiceConnectionChecks
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module OnContainer
|
4
|
+
module Dev
|
5
|
+
module RailsOps
|
6
|
+
def remove_rails_pidfile
|
7
|
+
system "rm -rf #{File.expand_path('tmp/pids/server.pid')}"
|
8
|
+
end
|
9
|
+
|
10
|
+
def rails_server?
|
11
|
+
ARGV[0] == 'rails' && %w[server s].include?(ARGV[1])
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module OnContainer
|
4
|
+
module Dev
|
5
|
+
module SetupOps
|
6
|
+
APP_PATH = File.expand_path '.'
|
7
|
+
|
8
|
+
def app_temp_path; "#{APP_PATH}/tmp"; end
|
9
|
+
def app_setup_wait; ENV.fetch('APP_SETUP_WAIT', '5').to_i; end
|
10
|
+
def app_setup_lock_path; "#{app_temp_path}/setup.lock"; end
|
11
|
+
|
12
|
+
def lock_setup
|
13
|
+
system "mkdir -p #{app_temp_path} && touch #{app_setup_lock_path};"
|
14
|
+
end
|
15
|
+
|
16
|
+
def unlock_setup
|
17
|
+
system "rm -rf #{app_setup_lock_path}"
|
18
|
+
end
|
19
|
+
|
20
|
+
def wait_setup
|
21
|
+
puts 'Waiting for app setup to finish...'
|
22
|
+
sleep app_setup_wait
|
23
|
+
end
|
24
|
+
|
25
|
+
def on_setup_lock_acquired
|
26
|
+
wait_setup while File.exist?(app_setup_lock_path)
|
27
|
+
|
28
|
+
lock_setup
|
29
|
+
|
30
|
+
%w[HUP INT QUIT TERM EXIT].each do |signal_string|
|
31
|
+
Signal.trap(signal_string) { unlock_setup }
|
32
|
+
end
|
33
|
+
|
34
|
+
yield
|
35
|
+
|
36
|
+
ensure
|
37
|
+
unlock_setup
|
38
|
+
end
|
39
|
+
|
40
|
+
def command_requires_setup?
|
41
|
+
%w[
|
42
|
+
rails rspec sidekiq hutch puma rake webpack webpack-dev-server
|
43
|
+
].include?(ARGV[0])
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Reads the specified secret paths (i.e. Docker Secrets) into environment
|
4
|
+
# variables:
|
5
|
+
|
6
|
+
require 'active_support'
|
7
|
+
require 'active_support/core_ext/object'
|
8
|
+
|
9
|
+
# Process only a known list of env vars that can filled by reading a file (i.e.
|
10
|
+
# a docker secret):
|
11
|
+
Dir["#{ENV.fetch('SECRETS_PATH', '/run/secrets/')}*"].each do |secret_filepath|
|
12
|
+
next unless File.file?(secret_filepath)
|
13
|
+
|
14
|
+
secret_envvarname = File.basename(secret_filepath, '.*').upcase
|
15
|
+
|
16
|
+
# Skip if variable is already set - already-set variables have precedence over
|
17
|
+
# the secret files:
|
18
|
+
next if ENV.key?(secret_envvarname) && ENV[secret_envvarname].present?
|
19
|
+
|
20
|
+
ENV[secret_envvarname] = File.read(secret_filepath).strip
|
21
|
+
end
|
22
|
+
|
23
|
+
# For each *_URL environment variable where there's also a *_(USER|USERNAME) or
|
24
|
+
# *_(PASS|PASSWORD), update the URL environment variable with the given
|
25
|
+
# credentials. For example:
|
26
|
+
#
|
27
|
+
# DATABASE_URL: postgres://postgres:5432/demo_production
|
28
|
+
# DATABASE_USERNAME: lalito
|
29
|
+
# DATABASE_PASSWORD: lepass
|
30
|
+
#
|
31
|
+
# Results in the following updated DATABASE_URL:
|
32
|
+
# DATABASE_URL = postgres://lalito:lepass@postgres:5432/demo_production
|
33
|
+
require 'uri' if (url_keys = ENV.keys.select { |key| key =~ /_URL/ }).any?
|
34
|
+
|
35
|
+
url_keys.each do |url_key|
|
36
|
+
credential_pattern_string = url_key.gsub('_URL', '_(USER(NAME)?|PASS(WORD)?)')
|
37
|
+
credential_pattern = Regexp.new "\\A#{credential_pattern_string}\\z"
|
38
|
+
credential_keys = ENV.keys.select { |key| key =~ credential_pattern }
|
39
|
+
next unless credential_keys.any?
|
40
|
+
|
41
|
+
uri = URI(ENV[url_key])
|
42
|
+
username = URI.encode_www_form_component ENV[credential_keys.detect { |key| key =~ /USER/ }]
|
43
|
+
password = URI.encode_www_form_component ENV[credential_keys.detect { |key| key =~ /PASS/ }]
|
44
|
+
|
45
|
+
uri.user = username if username
|
46
|
+
uri.password = password if password
|
47
|
+
ENV[url_key] = uri.to_s
|
48
|
+
end
|
49
|
+
|
50
|
+
# STDERR.puts ENV.inspect
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'socket'
|
4
|
+
require 'timeout'
|
5
|
+
require 'uri'
|
6
|
+
|
7
|
+
module OnContainer
|
8
|
+
module Ops
|
9
|
+
module ServiceConnectionChecks
|
10
|
+
def service_accepts_connections?(service_uri, seconds_to_wait = 30)
|
11
|
+
uri = URI(service_uri)
|
12
|
+
|
13
|
+
Timeout::timeout(seconds_to_wait) do
|
14
|
+
TCPSocket.new(uri.host, uri.port).close
|
15
|
+
rescue Errno::ECONNREFUSED
|
16
|
+
retry
|
17
|
+
end
|
18
|
+
|
19
|
+
true
|
20
|
+
|
21
|
+
rescue => e
|
22
|
+
puts "Connection to #{uri.to_s} failed: '#{e.inspect}'"
|
23
|
+
end
|
24
|
+
|
25
|
+
def wait_for_service_to_accept_connections(service_uri, seconds_to_wait = 30, exit_on_fail = true)
|
26
|
+
wait_loop = Thread.new do
|
27
|
+
loop do
|
28
|
+
sleep(5)
|
29
|
+
puts "Waiting for #{service_uri} to accept connections..."
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
if service_accepts_connections?(service_uri, seconds_to_wait)
|
34
|
+
return wait_loop.exit
|
35
|
+
else
|
36
|
+
exit 1 if exit_on_fail
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -26,11 +26,11 @@ module OnContainer
|
|
26
26
|
end
|
27
27
|
|
28
28
|
def developer_uid?
|
29
|
-
|
29
|
+
developer_uid > 0
|
30
30
|
end
|
31
31
|
|
32
32
|
def developer_uid
|
33
|
-
@developer_uid ||= ENV
|
33
|
+
@developer_uid ||= ENV.fetch('DEVELOPER_UID', '').to_i
|
34
34
|
end
|
35
35
|
|
36
36
|
protected
|
@@ -38,7 +38,7 @@ module OnContainer
|
|
38
38
|
def switch_to_developer_user
|
39
39
|
target_user_name = target_user.name
|
40
40
|
puts "Switching from 'root' user to '#{target_user_name}'..."
|
41
|
-
exec 'su-exec', target_user_name, $0, *$*
|
41
|
+
Kernel.exec 'su-exec', target_user_name, $0, *$*
|
42
42
|
end
|
43
43
|
|
44
44
|
def warn_no_developer_uid
|
data/lib/on_container/version.rb
CHANGED
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require "bundler/setup"
|
2
|
+
require "on_container"
|
3
|
+
|
4
|
+
RSpec.configure do |config|
|
5
|
+
# Enable flags like --only-failures and --next-failure
|
6
|
+
config.example_status_persistence_file_path = ".rspec_status"
|
7
|
+
|
8
|
+
# Disable RSpec exposing methods globally on `Module` and `main`
|
9
|
+
config.disable_monkey_patching!
|
10
|
+
|
11
|
+
config.expect_with :rspec do |c|
|
12
|
+
c.syntax = :expect
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'on_container/step_down_from_root'
|
4
|
+
|
5
|
+
RSpec.describe OnContainer::StepDownFromRoot do
|
6
|
+
let(:root_user) do
|
7
|
+
instance_double "struct Etc::Passwd",
|
8
|
+
name: 'root',
|
9
|
+
passwd: 'x',
|
10
|
+
uid: 0,
|
11
|
+
gid: 0,
|
12
|
+
gecos: 'root',
|
13
|
+
dir: '/root',
|
14
|
+
shell: '/bin/bash'
|
15
|
+
end
|
16
|
+
|
17
|
+
let(:developer_user) do
|
18
|
+
instance_double "struct Etc::Passwd",
|
19
|
+
name: 'developer',
|
20
|
+
passwd: 'x',
|
21
|
+
uid: 1000,
|
22
|
+
gid: 1000,
|
23
|
+
gecos: 'Developer User,,,',
|
24
|
+
dir: '/usr/src',
|
25
|
+
shell: '/bin/bash'
|
26
|
+
end
|
27
|
+
|
28
|
+
let(:example_current_user) { root_user }
|
29
|
+
let(:example_target_user) { developer_user }
|
30
|
+
let(:example_developer_uid) { '1000' }
|
31
|
+
|
32
|
+
before do
|
33
|
+
allow(ENV).to receive(:fetch).with('DEVELOPER_UID', '') { example_developer_uid }
|
34
|
+
allow(Etc).to receive(:getpwuid) { example_current_user }
|
35
|
+
allow(Etc).to receive(:getpwuid).with(example_target_user.uid) { example_target_user }
|
36
|
+
allow(Kernel).to receive(:exec).with('su-exec', example_target_user.name, any_args)
|
37
|
+
end
|
38
|
+
|
39
|
+
describe '#perform' do
|
40
|
+
it 'changes to the target user' do
|
41
|
+
subject.perform
|
42
|
+
expect(Kernel).to have_received(:exec).with 'su-exec', example_target_user.name, any_args
|
43
|
+
end
|
44
|
+
|
45
|
+
context 'without a developer uid' do
|
46
|
+
let(:example_developer_uid) { '' }
|
47
|
+
|
48
|
+
example 'does not change the current user' do
|
49
|
+
subject.perform
|
50
|
+
expect(Kernel).not_to have_received(:exec)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
context 'when not as root' do
|
55
|
+
let(:example_current_user) { developer_user }
|
56
|
+
|
57
|
+
example 'does not change the current user' do
|
58
|
+
subject.perform
|
59
|
+
expect(Kernel).not_to have_received(:exec)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: on_container
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Roberto Quintanilla
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-11-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -38,9 +38,21 @@ files:
|
|
38
38
|
- README.md
|
39
39
|
- Rakefile
|
40
40
|
- lib/on_container.rb
|
41
|
+
- lib/on_container/dev/active_record_ops.rb
|
42
|
+
- lib/on_container/dev/bundler_ops.rb
|
43
|
+
- lib/on_container/dev/container_command_ops.rb
|
44
|
+
- lib/on_container/dev/node_modules_ops.rb
|
45
|
+
- lib/on_container/dev/rails.rb
|
46
|
+
- lib/on_container/dev/rails_ops.rb
|
47
|
+
- lib/on_container/dev/setup_ops.rb
|
48
|
+
- lib/on_container/load_env_secrets.rb
|
49
|
+
- lib/on_container/ops/service_connection_checks.rb
|
41
50
|
- lib/on_container/step_down_from_root.rb
|
42
51
|
- lib/on_container/version.rb
|
43
52
|
- on_container.gemspec
|
53
|
+
- spec/on_container_spec.rb
|
54
|
+
- spec/spec_helper.rb
|
55
|
+
- spec/step_down_from_root_spec.rb
|
44
56
|
homepage: https://github.com/IcaliaLabs/on-container-for-ruby
|
45
57
|
licenses:
|
46
58
|
- MIT
|
@@ -64,9 +76,13 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
64
76
|
- !ruby/object:Gem::Version
|
65
77
|
version: '0'
|
66
78
|
requirements: []
|
67
|
-
|
79
|
+
rubyforge_project:
|
80
|
+
rubygems_version: 2.5.2.3
|
68
81
|
signing_key:
|
69
82
|
specification_version: 4
|
70
83
|
summary: A small collection of scripts and routines to help ruby development within
|
71
84
|
containers
|
72
|
-
test_files:
|
85
|
+
test_files:
|
86
|
+
- spec/on_container_spec.rb
|
87
|
+
- spec/spec_helper.rb
|
88
|
+
- spec/step_down_from_root_spec.rb
|