1
|
|
2
|
module Api
|
3
|
module V2
|
4
|
class ContainersController < ::Api::V2::BaseController
|
5
|
before_action :find_resource, :except => %w(index create)
|
6
|
|
7
|
resource_description do
|
8
|
resource_id 'containers'
|
9
|
api_version 'v2'
|
10
|
api_base_url '/docker/api/v2'
|
11
|
end
|
12
|
|
13
|
api :GET, '/containers/', N_('List all containers')
|
14
|
api :GET, '/compute_resources/:compute_resource_id/containers/',
|
15
|
N_('List all containers on a compute resource')
|
16
|
param :compute_resource_id, :identifier
|
17
|
param_group :search_and_pagination, ::Api::V2::BaseController
|
18
|
|
19
|
def index
|
20
|
compute_resource_id = params[:compute_resource_id].tap do |id|
|
21
|
id.present? ? { :compute_resource_id => id } : nil
|
22
|
end
|
23
|
scoped = Container.where(compute_resource_id)
|
24
|
@containers = scoped.search_for(params[:search], :order => params[:order])
|
25
|
.paginate(:page => params[:page])
|
26
|
end
|
27
|
|
28
|
api :GET, '/containers/:id/', N_('Show a container')
|
29
|
api :GET, '/compute_resources/:compute_resource_id/containers/:id',
|
30
|
N_('Show container on a compute resource')
|
31
|
param :id, :identifier, :required => true
|
32
|
param :compute_resource_id, :identifier
|
33
|
|
34
|
def show
|
35
|
end
|
36
|
|
37
|
def_param_group :container do
|
38
|
param :container, Hash, :required => true, :action_aware => true do
|
39
|
param :name, String
|
40
|
param_group :taxonomies, ::Api::V2::BaseController
|
41
|
param :compute_resource_id, :identifier, :required => true
|
42
|
param :registry_id, :identifier, :desc => N_('Registry this container will have to ' +
|
43
|
'use to get the image')
|
44
|
param :repository_name, String, :required => true,
|
45
|
:desc => N_('Name of the repository to use ' +
|
46
|
'to create the container. e.g. centos')
|
47
|
param :tag, String, :required => true,
|
48
|
:desc => N_('Tag to use to create the container. e.g. latest')
|
49
|
param :tty, :bool
|
50
|
param :entrypoint, String
|
51
|
param :command, String, :required => true
|
52
|
param :memory, String
|
53
|
param :cpu_shares, :number
|
54
|
param :cpu_set, String
|
55
|
param :environment_variables, Array, :desc => N_("Optional array of environment variables hashes. e.g. 'environment_variables': [{'name' => 'example', 'value' => '123'}]")
|
56
|
param :attach_stdout, :bool
|
57
|
param :attach_stdin, :bool
|
58
|
param :attach_stderr, :bool
|
59
|
param :capsule_id, :identifier, :desc => N_('The capsule this container will have to ' +
|
60
|
'use to get the image. Relevant for images ' +
|
61
|
'retrieved from katello registry.')
|
62
|
end
|
63
|
end
|
64
|
|
65
|
api :POST, '/containers/', N_('Create a container')
|
66
|
api :POST, '/compute_resources/:compute_resource_id/containers/',
|
67
|
N_('Create container on a compute resource')
|
68
|
param_group :container, :as => :create
|
69
|
|
70
|
def create
|
71
|
service = Service::Containers.new
|
72
|
@container = service.start_container!(set_wizard_state)
|
73
|
if service.errors.any?
|
74
|
render :json => { :errors => service.errors,
|
75
|
:full_messages => service.full_messages.join(', ')
|
76
|
},
|
77
|
:status => :unprocessable_entity
|
78
|
else
|
79
|
set_container_taxonomies
|
80
|
process_response @container.save
|
81
|
end
|
82
|
end
|
83
|
|
84
|
api :DELETE, '/containers/:id/', N_('Delete a container')
|
85
|
api :DELETE, '/compute_resources/:compute_resource_id/containers/:id',
|
86
|
N_('Delete container on a compute resource')
|
87
|
param :id, :identifier, :required => true
|
88
|
param :compute_resource_id, :identifier
|
89
|
|
90
|
def destroy
|
91
|
deleted_identifier = ForemanDocker::ContainerRemover.remove_unmanaged(
|
92
|
@container.compute_resource_id,
|
93
|
@container.uuid)
|
94
|
|
95
|
if deleted_identifier
|
96
|
process_response @container.destroy
|
97
|
else
|
98
|
render :json => { :error => 'Could not delete container on Docker host' }, :status => :precondition_failed
|
99
|
end
|
100
|
end
|
101
|
|
102
|
api :GET, '/containers/:id/logs', N_('Show container logs')
|
103
|
api :GET, '/compute_resources/:compute_resource_id/containers/:id/logs',
|
104
|
N_('Show logs from a container on a compute resource')
|
105
|
param :id, :identifier, :required => true
|
106
|
param :compute_resource_id, :identifier
|
107
|
param :stdout, :bool
|
108
|
param :stderr, :bool
|
109
|
param :tail, Fixnum, N_('Number of lines to tail. Default: 100')
|
110
|
|
111
|
def logs
|
112
|
render :json => { :logs => Docker::Container.get(@container.uuid)
|
113
|
.logs(:stdout => (params[:stdout] || true),
|
114
|
:stderr => (params[:stderr] || false),
|
115
|
:tail => (params[:tail] || 100)) }
|
116
|
end
|
117
|
|
118
|
api :PUT, '/containers/:id/power', N_('Run power operation on a container')
|
119
|
api :PUT, '/compute_resources/:compute_resource_id/containers/:id/power',
|
120
|
N_('Run power operation on a container on a compute resource')
|
121
|
param :id, :identifier, :required => true
|
122
|
param :compute_resource_id, :identifier
|
123
|
param :power_action, String,
|
124
|
:required => true,
|
125
|
:desc => N_('power action, valid actions are (start), (stop), (status)')
|
126
|
|
127
|
def power
|
128
|
power_actions = %(start stop status)
|
129
|
if power_actions.include? params[:power_action]
|
130
|
response = if params[:power_action] == 'status'
|
131
|
{ :running => @container.in_fog.ready? }
|
132
|
else
|
133
|
{ :running => @container.in_fog.send(params[:power_action]) }
|
134
|
end
|
135
|
render :json => response
|
136
|
else
|
137
|
render :json =>
|
138
|
{ :error => _("Unknown method: available power operations are %s") %
|
139
|
power_actions.join(', ') }, :status => :unprocessable_entity
|
140
|
end
|
141
|
end
|
142
|
|
143
|
private
|
144
|
|
145
|
def wizard_properties
|
146
|
wizard_props = { :preliminary => [:compute_resource_id],
|
147
|
:image => [:registry_id, :repository_name, :tag],
|
148
|
:configuration => [:name, :command, :entrypoint, :cpu_set,
|
149
|
:cpu_shares, :memory],
|
150
|
:environment => [:tty, :attach_stdin, :attach_stdout,
|
151
|
:attach_stderr] }
|
152
|
if DockerContainerWizardStates::Image.attribute_names.include?("capsule_id")
|
153
|
wizard_props[:image] << :capsule_id
|
154
|
end
|
155
|
wizard_props
|
156
|
end
|
157
|
|
158
|
def set_wizard_state
|
159
|
wizard_state = DockerContainerWizardState.create
|
160
|
wizard_properties.each do |step, properties|
|
161
|
property_values = properties.each_with_object({}) do |property, values|
|
162
|
values[:"#{property}"] = params[:container][:"#{property}"]
|
163
|
end
|
164
|
wizard_state.send(:"create_#{step}", property_values)
|
165
|
end
|
166
|
|
167
|
if params[:container][:environment_variables].present?
|
168
|
environment_variables = []
|
169
|
params[:container][:environment_variables].each do |env_var|
|
170
|
environment_variable = DockerContainerWizardStates::EnvironmentVariable.new
|
171
|
environment_variable.key = env_var[:key]
|
172
|
environment_variable.value = env_var[:value]
|
173
|
environment_variables << environment_variable
|
174
|
end
|
175
|
wizard_state.environment.environment_variables = environment_variables
|
176
|
end
|
177
|
wizard_state.tap(&:save)
|
178
|
end
|
179
|
|
180
|
def set_container_taxonomies
|
181
|
Taxonomy.enabled_taxonomies.each do |taxonomy|
|
182
|
if params[:container][:"#{taxonomy}"].present?
|
183
|
@container.send(:"#{taxonomy}=", params[:container][:"#{taxonomy}"])
|
184
|
end
|
185
|
end
|
186
|
end
|
187
|
|
188
|
def action_permission
|
189
|
case params[:action]
|
190
|
when 'logs'
|
191
|
:view
|
192
|
when 'power'
|
193
|
:edit
|
194
|
else
|
195
|
super
|
196
|
end
|
197
|
end
|
198
|
end
|
199
|
end
|
200
|
end
|
201
|
|