Project

General

Profile

Download (8.04 KB) Statistics
| Branch: | Tag: | Revision:

foreman-docker / app / controllers / api / v2 / containers_controller.rb @ 9d5ef1c9

1
# module ForemanDocker
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
# end