Class: CMDB::Commands::Shim

Inherits:
Object
  • Object
show all
Defined in:
lib/cmdb/commands/shim.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(command, options = {}) ⇒ Shim

Create a Shim.

Parameters:

  • command (Array)

    collection of string to pass to Kernel#exec; 0th element is the command name



94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
# File 'lib/cmdb/commands/shim.rb', line 94

def initialize(command, options = {})
  @command         = command
  @dir             = options[:dir]
  @consul_url      = options[:consul_url]
  @consul_prefixes = options[:consul_prefix]
  @keys            = options[:keys] || []
  @pretend         = options[:pretend]
  @reload          = options[:reload]
  @signal          = options[:reload_signal]
  @env             = options[:env]
  @user            = options[:user]
  @root            = options[:root]

  CMDB::FileSource.base_directories = @keys unless @keys.empty?
  CMDB::ConsulSource.url = @consul_url unless @consul_url.nil?
  if !@consul_prefixes.nil? && !@consul_prefixes.empty?
    CMDB::ConsulSource.prefixes = @consul_prefixes
  end

  CMDB.log.level = Logger::FATAL if options[:quiet]
end

Instance Attribute Details

#cmdbCMDB::Interface (readonly)

Returns:



89
90
91
# File 'lib/cmdb/commands/shim.rb', line 89

def cmdb
  @cmdb
end

Class Method Details

.createObject



7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/cmdb/commands/shim.rb', line 7

def self.create
  options = Trollop.options do
    banner "The 'shim' command adapts your applications for use with CMDB without coupling them to\nthe CMDB RubyGem (or forcing you to write your applications in Ruby). It works by\nmanipulating the environment or filesystem to make CMDB inputs visible, then invoking\nyour app.\n\nTo use the shim with apps that read configuration from the filesystem, use the --dir\noption to tell the shim where to rewrite configuration files. It will look for tokens\nin JSON or YML that look like <<cmdb.key.name>> and replace them with the value of\nthe specified key.\n\nTo use the shim with 12-factor apps, use the --env option to tell the shim to load\nevery CMDB key into the environment. When using --env, the prefix of each key is\nomitted from the environment variable name, e.g. \"common.database.host\" is\nrepresented as DATABASE_HOST.\n\nTo support \"development mode\" and reload your app whenever its files change on disk,\nuse the --reload option and specify the name of a CMDB key that will enable this\nbehavior.\n\nUsage:\ncmdb shim [options] -- <command_to_exec> [options_for_command]\n\nWhere [options] are selected from:\n    EOS\n    opt :dir,\n        'Directory to scan for key-replacement tokens in data files',\n        type: :string\n    opt :consul_url,\n        'The URL for talking to consul',\n        type: :string\n    opt :consul_prefix,\n        'The prefix to use when getting keys from consul, can be specified more than once',\n        type: :string,\n        multi: true\n    opt :keys,\n        'Override search path(s) for CMDB key files',\n        type: :strings\n    opt :pretend,\n        'Check for errors, but do not actually launch the app or rewrite files',\n        default: false\n    opt :quiet,\n        \"Don't print any output\",\n        default: false\n    opt :reload,\n        'CMDB key that enables reload-on-edit',\n        type: :string\n    opt :reload_signal,\n        'Signal to send to app server when code is edited',\n        type: :string,\n        default: 'HUP'\n    opt :env,\n        \"Add CMDB keys to the app server's process environment\",\n        default: false\n    opt :user,\n        'Switch to named user before executing app',\n        type: :string\n    opt :root,\n        'Promote named subkey to the root when it is present in a namespace',\n        type: :string\n  end\n\n  new(ARGV, options)\nend\n"

.drop_privileges(login) ⇒ true

Irrevocably change the current user for this Unix process by calling the setresuid system call. This sets both the uid and gid (to the user’s primary group).

Parameters:

  • login (String)

    name of user to switch to

Returns:

  • (true)

Raises:

  • (ArgumentError)

    if the named user does not exist



81
82
83
84
85
86
# File 'lib/cmdb/commands/shim.rb', line 81

def self.drop_privileges()
  pwent = Etc.getpwnam()
  Process::Sys.setresgid(pwent.gid, pwent.gid, pwent.gid)
  Process::Sys.setresuid(pwent.uid, pwent.uid, pwent.uid)
  true
end

Instance Method Details

#runObject

Run the shim.

Raises:

  • (SystemExit)

    if something goes wrong



119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
# File 'lib/cmdb/commands/shim.rb', line 119

def run
  @cmdb = CMDB::Interface.new(root: @root)

  rewrote   = rewrite_files
  populated = populate_environment

  if !rewrote && !populated && !@pretend && @command.empty?
    CMDB.log.warn 'CMDB: nothing to do; please specify --dir, --env, or a command to run'
    exit 7
  end

  launch_app
rescue CMDB::BadKey => e
  CMDB.log.fatal "CMDB: Bad Key: malformed CMDB key '#{e.key}'"
  exit 1
rescue CMDB::BadValue => e
  CMDB.log.fatal "CMDB: Bad Value: illegal value for CMDB key '#{e.key}' in source #{e.url}"
  exit 2
rescue CMDB::BadData => e
  CMDB.log.fatal "CMDB: Bad Data: malformed CMDB data in source #{e.url}"
  exit 3
rescue CMDB::ValueConflict => e
  CMDB.log.fatal "CMDB: Value Conflict: #{e.message}"
  e.sources.each do |s|
    CMDB.log.fatal " - #{s.url}"
  end
  exit 4
rescue CMDB::NameConflict => e
  CMDB.log.fatal "CMDB: Name Conflict: #{e.message}"
  e.keys.each do |k|
    CMDB.log.fatal " - #{k}"
  end
  exit 4
rescue CMDB::EnvironmentConflict => e
  CMDB.log.fatal "CMDB: Environment Conflict: #{e.message}"
  exit 5
rescue Errno::ENOENT => e
  CMDB.log.fatal "CMDB: missing file or directory #{e.message}"
  exit 6
end