foreman_docker 0.2.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +10 -3
  3. data/app/assets/javascripts/foreman_docker/image_step.js +44 -5
  4. data/app/controllers/concerns/foreman_docker/find_container.rb +19 -0
  5. data/app/controllers/containers/steps_controller.rb +25 -39
  6. data/app/controllers/containers_controller.rb +10 -43
  7. data/app/controllers/image_search_controller.rb +88 -0
  8. data/app/controllers/registries_controller.rb +47 -0
  9. data/app/helpers/container_steps_helper.rb +21 -4
  10. data/app/helpers/containers_helper.rb +19 -7
  11. data/app/models/concerns/foreman_docker/parameter_validators.rb +11 -0
  12. data/app/models/container.rb +20 -7
  13. data/app/models/docker_container_wizard_state.rb +30 -0
  14. data/app/models/docker_container_wizard_states/configuration.rb +7 -0
  15. data/app/models/docker_container_wizard_states/environment.rb +21 -0
  16. data/app/models/docker_container_wizard_states/environment_variable.rb +7 -0
  17. data/app/models/docker_container_wizard_states/image.rb +11 -0
  18. data/app/models/docker_container_wizard_states/preliminary.rb +11 -0
  19. data/app/models/docker_registry.rb +28 -0
  20. data/app/models/environment_variable.rb +5 -0
  21. data/app/models/foreman_docker/docker.rb +22 -3
  22. data/app/models/service/containers.rb +38 -0
  23. data/app/models/service/registry_api.rb +26 -0
  24. data/app/views/containers/_list.html.erb +19 -18
  25. data/app/views/containers/index.html.erb +11 -6
  26. data/app/views/containers/show.html.erb +26 -7
  27. data/app/views/containers/steps/_form_buttons.html.erb +1 -1
  28. data/app/views/containers/steps/configuration.html.erb +2 -2
  29. data/app/views/containers/steps/environment.html.erb +19 -6
  30. data/app/views/containers/steps/image.html.erb +58 -39
  31. data/app/views/containers/steps/preliminary.html.erb +21 -4
  32. data/app/views/foreman_docker/common_parameters/_environment_variable.html.erb +18 -0
  33. data/app/views/image_search/_repository_search_results.html.erb +12 -0
  34. data/app/views/registries/_form.html.erb +26 -0
  35. data/app/views/registries/edit.html.erb +3 -0
  36. data/app/views/registries/index.html.erb +28 -0
  37. data/app/views/registries/new.html.erb +3 -0
  38. data/config/routes.rb +11 -2
  39. data/db/migrate/20141024163003_create_docker_registries.rb +22 -0
  40. data/db/migrate/20141120123003_add_user_credentials_to_docker_registries.rb +6 -0
  41. data/db/migrate/20141209182008_remove_docker_tables.rb +72 -0
  42. data/db/migrate/20141222113313_create_wizard_states.rb +42 -0
  43. data/lib/foreman_docker/engine.rb +25 -5
  44. data/lib/foreman_docker/version.rb +1 -1
  45. data/test/factories/containers.rb +2 -0
  46. data/test/factories/docker_registry.rb +16 -0
  47. data/test/functionals/containers_steps_controller_test.rb +7 -40
  48. data/test/integration/container_steps_test.rb +24 -0
  49. data/test/integration/container_test.rb +18 -0
  50. data/test/units/container_test.rb +0 -7
  51. data/test/units/containers_service_test.rb +21 -0
  52. data/test/units/docker_registry_test.rb +24 -0
  53. metadata +45 -22
  54. data/app/models/docker_image.rb +0 -9
  55. data/app/models/docker_tag.rb +0 -8
  56. data/test/factories/docker_image.rb +0 -5
  57. data/test/factories/docker_tag.rb +0 -6
  58. data/test/units/docker_image_test.rb +0 -23
  59. data/test/units/docker_tag_test.rb +0 -35
@@ -2,7 +2,7 @@
2
2
 
3
3
  <% if authorized? %>
4
4
  <% title_actions button_group(link_to_if_authorized _("New container"), hash_for_new_container_path,
5
- :class => 'btn-success' ) %>
5
+ :class => 'btn-success') %>
6
6
  <% end %>
7
7
 
8
8
  <ul class="nav nav-tabs" data-tabs="tabs">
@@ -22,10 +22,15 @@
22
22
  <% else %>
23
23
  <div class="tab-pane" id="<%= resource.name %>">
24
24
  <% end %>
25
- <%= render 'list', :containers => resource.vms.to_a
26
- .sort_by(&:name).paginate(:page => params[:page],
27
- :per_page => 10),
28
- :resource => resource %>
25
+ <% if resource.test_connection %>
26
+ <%= render 'list', :containers => resource.vms,
27
+ :resource => resource %>
28
+ <% else %>
29
+ <div class="alert alert-warning">
30
+ <%= (_("Error connecting with the compute resource: <strong> %s </strong>") % resource.errors.messages[:base]).html_safe %>
31
+ </div>
32
+ <% end %>
29
33
  </div>
30
34
  <% end %>
31
- </div>
35
+ </div>
36
+ </div>
@@ -12,12 +12,12 @@
12
12
  <td><%= @container.in_fog.name %></td>
13
13
  </tr>
14
14
  <tr>
15
- <td><%= _('Image') %></td>
16
- <td><%= @container.image.image_id %> </td>
15
+ <td><%= _('Image Repository') %></td>
16
+ <td><%= @container.repository_name %> </td>
17
17
  </tr>
18
18
  <tr>
19
- <td><%= _('Tag') %></td>
20
- <td><%= @container.tag.tag %> </td>
19
+ <td><%= _('Image Tag') %></td>
20
+ <td><%= @container.tag %> </td>
21
21
  </tr>
22
22
  <tr>
23
23
  <td><%= _('IP Address') %></td>
@@ -43,7 +43,26 @@
43
43
  <td><%= _('Exposed ports') %></td>
44
44
  <td><%= @container.in_fog.exposed_ports %> </td>
45
45
  </tr>
46
-
46
+ <tr>
47
+ <td><%= _('Environment Variables') %></td>
48
+ <td>
49
+ <table id="environment_variables" class="table table-bordered" style="table-layout:fixed; word-wrap: break-word">
50
+ <% @container.in_fog.attributes['config_env'].each do |environment_variable| %>
51
+ <% pair = environment_variable.split("=") %>
52
+ <tr>
53
+ <td><b><%= pair.first %></b></td>
54
+ <td><i><%= pair.second %></i></td>
55
+ </tr>
56
+ <% end %>
57
+ </table>
58
+ </td>
59
+ </tr>
60
+ <% Taxonomy.enabled_taxonomies.each do |taxonomy| %>
61
+ <tr>
62
+ <td><%= _(taxonomy.humanize) %></td>
63
+ <td><%= link_to_taxonomies(@container.send(:"#{taxonomy}")).html_safe %> </td>
64
+ </tr>
65
+ <% end %>
47
66
  <tr>
48
67
  <td><%= _('Running on') %></td>
49
68
  <td><%= link_to @container.compute_resource,
@@ -121,8 +140,8 @@
121
140
  </div>
122
141
  <div class="form-group">
123
142
  <%= label_tag "commit[tag]", _("Tag"), :class=>"col-sm-2 control-label" %>
124
- <%= text_field :commit, :tag, { :class => "col-sm-8", :focus_on_load => true,
125
- :placeholder => _('latest') } %>
143
+ <%= text_field :commit, :tag, { :class => "col-sm-8",
144
+ :placeholder => _('latest') } %>
126
145
  </div>
127
146
  <div class="form-group">
128
147
  <%= label_tag "commit[author]", _("Author"), :class=>"col-sm-2 control-label" %>
@@ -9,7 +9,7 @@
9
9
  </a>
10
10
  <% end %>
11
11
  <%= button_tag(:type => 'submit', :class => "btn btn-primary pull-right") do %>
12
- <% if step == :environment %>
12
+ <% if last_step? %>
13
13
  <%= _("Submit") %>
14
14
  <% else %>
15
15
  <%= _("Next") %>
@@ -1,5 +1,5 @@
1
1
  <%= render :layout => 'title', :locals => { :step => 3 } do %>
2
- <%= form_for @container, :url => wizard_path, :method => :put do |f| %>
2
+ <%= form_for @configuration, :url => wizard_path, :method => :put do |f| %>
3
3
  <h3><%= _("Basic options") %></h3>
4
4
  <%= text_f f, :name, :size => 'col-md-4' %>
5
5
  <%= text_f f, :command, :size => 'col-md-4' %>
@@ -11,7 +11,7 @@
11
11
  :help_block => link_to(_("learn more about CPU sets"), 'http://docs.fedoraproject.org/en-US/Fedora/17/html/Resource_Management_Guide/sec-cpuset.html') %>
12
12
  <%= text_f f, :cpu_shares, :class => "col-md-2", :label => _('CPU shares'),
13
13
  :placeholder => 'relative share of CPU time in cgroup',
14
- :help_block => link_to(_("learn more about CPU shares"), 'http://docs.fedoraproject.org/en-US/Fedora/17/html/Resource_Management_Guide/sec-cpuset.html') %>
14
+ :help_block => link_to(_("learn more about CPU shares"), 'http://docs.fedoraproject.org/en-US/Fedora/17/html/Resource_Management_Guide/sec-cpu.html') %>
15
15
  <%= text_f f, :memory, :class => "col-md-2", :label => _('Memory'), :placeholder => '512m limits container memory usage to 512 MB' %>
16
16
  <%= render :partial => 'form_buttons' %>
17
17
  <% end %>
@@ -1,9 +1,22 @@
1
1
  <%= render :layout => 'title', :locals => { :step => 4 } do %>
2
- <%= form_for @container, :url => wizard_path, :method => :put do |f| %>
3
- <%= checkbox_f f, :tty, :help_inline => _('Allocate a pseudo-tty'), :label => _('TTY') %>
4
- <%= checkbox_f f, :attach_stdin, :label => _('Attach STDIN') %>
5
- <%= checkbox_f f, :attach_stdout, :label => _('Attach STDOUT') %>
6
- <%= checkbox_f f, :attach_stderr, :label => _('Attach STDERR') %>
7
- <%= render :partial => 'form_buttons' %>
2
+ <%= form_for @environment, :url => wizard_path, :method => :put do |f| %>
3
+ <div class='row'>
4
+ <div class='col-md-6 col-md-push-7'>
5
+ <h3><%= _("Shell") %></h3>
6
+ <%= checkbox_f f, :tty, :help_inline => _('Allocate a pseudo-tty'), :label => _('TTY') %>
7
+ <%= checkbox_f f, :attach_stdin, :label => _('Attach STDIN') %>
8
+ <%= checkbox_f f, :attach_stdout, :label => _('Attach STDOUT') %>
9
+ <%= checkbox_f f, :attach_stderr, :label => _('Attach STDERR') %>
10
+ </div>
11
+ <div class='col-md-6 col-md-pull-6'>
12
+ <h3><%= _("Environment variables") %></h3>
13
+ <%= f.fields_for :environment_variables, @environment.environment_variables do |builder| %>
14
+ <%= render 'foreman_docker/common_parameters/environment_variable', :f => builder %>
15
+ <% end %>
16
+ <%= link_to_add_fields(_("Add environment variable"), f, :environment_variables,
17
+ 'foreman_docker/common_parameters/environment_variable') %>
18
+ </div>
19
+ </div>
20
+ <%= render :partial => 'form_buttons' %>
8
21
  <% end %>
9
22
  <% end %>
@@ -1,45 +1,64 @@
1
1
  <%= javascript 'foreman_docker/image_step' %>
2
2
  <%= stylesheet 'foreman_docker/autocomplete' %>
3
- <%= render :layout => 'title', :locals => { :step => 2 } do %>
4
- <%= form_for @container, :url => wizard_path, :method => :put do |f| %>
5
3
 
6
- <ul class="nav nav-tabs" data-tabs="tabs">
7
- <li class="active"><a href="#primary" data-toggle="tab">
8
- <span class="glyphicon glyphicon-cloud-download"></span>
9
- <%= _("Docker hub") %>
10
- </a></li>
11
- </ul>
4
+ <%= render :layout => 'title', :locals => { :step => 2 } do %>
5
+ <ul class="nav nav-tabs" data-tabs="tabs">
6
+ <li class="active"><a href="#hub" data-toggle="tab" id="hub_tab">
7
+ <span class="glyphicon glyphicon-cloud-download"></span>
8
+ <%= _("Docker hub") %>
9
+ </a></li>
10
+ <li><a href="#registry" data-toggle="tab" id="registry_tab">
11
+ <span class="glyphicon glyphicon-cloud-download"></span>
12
+ <%= _("External registry") %>
13
+ </a></li>
14
+ </ul>
12
15
 
13
- <div class="tab-content">
14
- <div class="tab-pane active" id="hub">
15
- <div class="input-group col-md-6">
16
- <%= auto_complete_search(:image, '',
17
- :'data-url' => auto_complete_image_container_path(@container),
18
- :value => f.object.image.present? ? f.object.image.image_id : '',
19
- :id => :search,
20
- :placeholder => _('Find your favorite container, e.g: centos:latest')) %>
21
- <span class="input-group-addon glyphicon" id="search-addon"></span>
22
- <span class="input-group-btn">
23
- <%= button_tag(:class => 'btn btn-default',
24
- :type => 'button',
25
- :onclick => "$('#search').trigger('focus')") do %>
26
- <span class="glyphicon glyphicon-search"></span>
27
- <%= _("Search") %>
28
- <% end %>
29
- </span>
30
- </div>
31
- <br/>
32
- <div class="input-group col-md-6">
33
- <%= text_f f, :tag,
34
- :size => 'col-md-6',
35
- :value => f.object.tag.present? ? f.object.tag.tag : '',
36
- :id => 'tag',
37
- :'data-url' => auto_complete_image_tags_container_path(@container) %>
38
- </div>
39
- <hr/>
40
- <%= render :partial => 'form_buttons' %>
41
- </div>
42
- </div>
16
+ <%= form_for @image, :class => 'form-horizontal', :url => wizard_path, :method => :put do |f| %>
17
+ <div class="tab-content">
18
+ <div class="tab-pane active" id="hub">
19
+ </div>
20
+ <div class="tab-pane" id="registry">
21
+ <div class="input-group col-md-6">
22
+ <%= select_registry f %>
23
+ </div>
24
+ </div>
25
+ <div>
26
+ <div class="form-group col-md-6">
27
+ <%= label_tag "image_id", _('Search'), :class=>"col-sm-2 control-label" %>
28
+ <div class="input-group">
43
29
 
44
- <% end %>
30
+ <%= auto_complete_docker_search('docker_container_wizard_states_image[repository_name]', '',
31
+ :'data-url' => auto_complete_repository_name_image_search_path(@image.compute_resource_id),
32
+ :value => f.object.repository_name.present? ? f.object.repository_name : '',
33
+ :id => :search,
34
+ :focus_on_load => true,
35
+ :placeholder => _('Find your favorite container, e.g: centos')) %>
36
+ <span class="input-group-addon glyphicon" id="search-addon"></span>
37
+ <span class="input-group-btn">
38
+ <%= button_tag(:class => 'btn btn-default',
39
+ :type => 'button',
40
+ :id => 'search_repository',
41
+ :'data-url' => search_repository_image_search_path(@image.compute_resource_id),
42
+ :onclick => 'searchRepo(this)') do %>
43
+ <span class="glyphicon glyphicon-search"></span>
44
+ <% end %>
45
+ </span>
46
+ </div>
47
+ </div>
48
+ <%= text_f f, :tag,
49
+ :id => 'tag',
50
+ :'data-url' => auto_complete_image_tag_image_search_path(@image.compute_resource_id) %>
51
+ <div class="col-md-12">
52
+ <div id='searching_spinner' class='col-md-offset-3 hide'>
53
+ <span id='waiting_text'>
54
+ </span>
55
+ <%= image_tag('/assets/spinner.gif', :id => 'loading_repositories_indicator') %>
56
+ </div>
57
+ <div id='repository_search_results'>
58
+ </div>
59
+ </div>
60
+ </div>
61
+ <%= render :partial => 'form_buttons' %>
62
+ </div>
63
+ <% end %>
45
64
  <% end %>
@@ -1,18 +1,35 @@
1
1
  <%= render :layout => 'title', :locals => { :step => 1 } do %>
2
- <%= form_for @container, :url => wizard_path, :method => :put do |f| %>
3
- <div>
2
+ <%= form_for @preliminary, :url => wizard_path, :method => :put do |f| %>
3
+ <ul class="nav nav-tabs" data-tabs="tabs">
4
+ <li class="active"><a href="#primary" data-toggle="tab">
5
+ <span class="glyphicon glyphicon-tasks"></span>
6
+ <%= _("Compute resource") %>
7
+ </a></li>
8
+ <% Taxonomy.enabled_taxonomies.each do |taxonomy| %>
9
+ <li><a href="#<%= taxonomy %>" data-toggle="tab">
10
+ <span class="glyphicon glyphicon-<%= taxonomy_icon(taxonomy) %>">
11
+ </span>
12
+ <%= _(taxonomy.humanize) %>
13
+ </a></li>
14
+ <% end %>
15
+ </ul>
16
+ <div class="tab-content">
17
+ <div class="tab-pane active" id="primary">
4
18
  <% if @container_resources.present? %>
5
19
  <h3><%= _("Resource selection") %></h3>
6
20
  <%= _("Where do you want to deploy your container?:") %>
7
21
  <hr>
8
- <%= select_f f, :compute_resource_id, @container_resources, :id, :to_label, {}, { :label => _('Deploy on') } %>
22
+ <%= select_f f, 'compute_resource_id', @container_resources, :id, :to_label, {}, { :label => _('Deploy on') } %>
9
23
  <% else %>
10
24
  <div class="alert alert-warning alert-dismissable">
11
25
  <%= image_tag 'false.png' %> <%= (_("You need a Docker compute resource in order to create containers. Please %s and try again.") % link_to('add a new one', hash_for_new_compute_resource_path)).html_safe %>
12
26
  </div>
13
27
  <% end %>
14
28
  </div>
15
-
29
+ <%= render "taxonomies/loc_org_tabs", :f => f, :obj => @preliminary %>
30
+ </div>
31
+ <% if @container_resources.present? %>
16
32
  <%= render :partial => 'form_buttons' %>
17
33
  <% end %>
18
34
  <% end %>
35
+ <% end %>
@@ -0,0 +1,18 @@
1
+ <div class='fields'>
2
+ <table class="table table-bordered table-hover table-striped">
3
+ <tr class="form-group <%= 'error' if f.object.errors.any? %>">
4
+ <td><%= f.text_field(:name, :class => "form-control",
5
+ :placeholder => _("Name, e.g: PING_HOST")) %></td>
6
+ <td><%= f.text_field(:value, :class => "form-control",
7
+ :placeholder => _("Value, e.g: theforeman.org")) %></td>
8
+ <td style='vertical-align: middle' class='text-center'>
9
+ <span class="help-block">
10
+ <%= link_to_remove_fields('', f) %>
11
+ </span>
12
+ </td>
13
+ <span class="help-block">
14
+ <%= f.object.errors.full_messages.to_sentence %>
15
+ </span>
16
+ </tr>
17
+ </table>
18
+ </div>
@@ -0,0 +1,12 @@
1
+ <% repositories.each do |repository| %>
2
+ <h3><%= link_to repository['name'], '#', :onclick => 'repoSelected(this)' %></h3>
3
+ <p>
4
+ <%= '<span class="glyphicon glyphicon-certificate" title="Official"></span>'.html_safe if repository['is_official'] %>
5
+ <%= '<span class="glyphicon glyphicon-thumbs-up" title="Trusted"></span>'.html_safe if repository['is_trusted'] %>
6
+ <span class="glyphicon glyphicon-star"></span> <%= repository['star_count'] %>
7
+ </p>
8
+ <p>
9
+ <%= trunc(repository['description']) %>
10
+ <%= link_to '<span class="glyphicon glyphicon-share"></span>'.html_safe, hub_url(repository), :target => '_blank' %>
11
+ </p>
12
+ <% end %>
@@ -0,0 +1,26 @@
1
+ <%= form_for @registry, :url => (@registry.new_record? ? registries_path : registry_path(:id => @registry.id)) do |f| %>
2
+ <%= base_errors_for @registry %>
3
+ <ul class="nav nav-tabs" data-tabs="tabs">
4
+ <li class="active"><a href="#primary" data-toggle="tab"><%= _("Registry") %></a></li>
5
+ <% if show_location_tab? %>
6
+ <li><a href="#locations" data-toggle="tab"><%= _("Locations") %></a></li>
7
+ <% end %>
8
+ <% if show_organization_tab? %>
9
+ <li><a href="#organizations" data-toggle="tab"><%= _("Organizations") %></a></li>
10
+ <% end %>
11
+ </ul>
12
+
13
+ <div class="tab-content">
14
+ <div class="tab-pane active" id="primary">
15
+ <%= text_f f, :name, :help_inline => _("Registry name") %>
16
+ <%= text_f f, :url, :help_inline => _("Registry url") %>
17
+ <%= text_f f, :description, :help_inline => _("Describing of the registry") %>
18
+ <%= text_f f, :username, :help_inline => _("Username used to access the registry") %>
19
+ <%= password_f f, :password, :help_inline => _("Password used for authentication to the registry") %>
20
+ </div>
21
+
22
+ <%= render 'taxonomies/loc_org_tabs', :f => f, :obj => @registry %>
23
+ </div>
24
+
25
+ <%= submit_or_cancel f %>
26
+ <% end %>
@@ -0,0 +1,3 @@
1
+ <% title _("Edit Registry") %>
2
+
3
+ <%= render :partial => 'form' %>
@@ -0,0 +1,28 @@
1
+ <% title _("Registries") %>
2
+
3
+ <% if authorized? %>
4
+ <% title_actions button_group(link_to_if_authorized _("New Registry"), hash_for_new_registry_path,
5
+ :class => 'btn-success' ) %>
6
+ <% end %>
7
+
8
+ <table class="table table-bordered table-striped table-condensed" data-table="inline">
9
+ </thead>
10
+ <tr>
11
+ <th class="text-center"><%= sort :name, :as => _("Name") %></th>
12
+ <th class="hidden-tablet hidden-xs text-center"><%= sort :url, :as => _("Url") %></th>
13
+ <th class="hidden-tablet hidden-xs text-center"><%= _("Description") %></th>
14
+ <th></th>
15
+ </tr>
16
+ </thead>
17
+
18
+ <% @registries.each do |r| %>
19
+ <tr>
20
+ <td><%= link_to_if_authorized trunc(r.name), hash_for_edit_registry_path(:id => r).merge(:auth_object => r, :authorizer => authorizer) %></td>
21
+ <td class="hidden-tablet hidden-xs text-center"><%= trunc(r.url) %></td>
22
+ <td class="hidden-tablet hidden-xs text-center"><%= trunc(r.description) %></td>
23
+ <td><%= display_delete_if_authorized hash_for_registry_path(:id => r).merge(:auth_object => r, :authorizer => authorizer), :confirm => _("Delete %s?") % r.name %></td>
24
+ </tr>
25
+ <% end %>
26
+ </table>
27
+
28
+ <%= will_paginate_with_info @registries %>
@@ -0,0 +1,3 @@
1
+ <% title _("New Registry") %>
2
+
3
+ <%= render :partial => 'form' %>
@@ -3,8 +3,17 @@ Rails.application.routes.draw do
3
3
  member do
4
4
  post :commit
5
5
  end
6
+ end
7
+
8
+ resources :wizard_states, :only => [] do
6
9
  resources :steps, :controller => 'containers/steps', :only => [:show, :update]
7
- get :auto_complete_image, :on => :member
8
- get :auto_complete_image_tags, :on => :member
9
10
  end
11
+
12
+ resources :image_search, :only => [] do
13
+ get :auto_complete_repository_name, :on => :member
14
+ get :auto_complete_image_tag, :on => :member
15
+ get :search_repository, :on => :member
16
+ end
17
+
18
+ resources :registries, :only => [:index, :new, :create, :update, :destroy, :edit]
10
19
  end
@@ -0,0 +1,22 @@
1
+ class CreateDockerRegistries < ActiveRecord::Migration
2
+ def change
3
+ create_table :docker_registries do |t|
4
+ t.string :url
5
+ t.string :name
6
+ t.integer :id
7
+ t.string :description
8
+ t.timestamps
9
+ end
10
+
11
+ create_table :docker_image_docker_registries do |t|
12
+ t.integer :id
13
+ t.integer :docker_registry_id
14
+ t.integer :docker_image_id
15
+ end
16
+
17
+ add_index :docker_image_docker_registries,
18
+ [:docker_registry_id, :docker_image_id],
19
+ :name => 'by_docker_image_and_registry',
20
+ :unique => true
21
+ end
22
+ end
@@ -0,0 +1,6 @@
1
+ class AddUserCredentialsToDockerRegistries < ActiveRecord::Migration
2
+ def change
3
+ add_column :docker_registries, :username, :string
4
+ add_column :docker_registries, :password, :string
5
+ end
6
+ end
@@ -0,0 +1,72 @@
1
+ class RemoveDockerTables < ActiveRecord::Migration
2
+ class DockerImage
3
+ end
4
+
5
+ class DockerTag
6
+ end
7
+
8
+ def up
9
+ change_table :containers do |t|
10
+ t.string :repository_name
11
+ t.string :tag
12
+ t.belongs_to :registry
13
+ end
14
+
15
+ Container.reset_column_information
16
+ Container.all do |container|
17
+ image = DockerImage.find(container.docker_image_id)
18
+ container.update_attribute(:repository_name, image.image_id)
19
+
20
+ tag = DockerTag.find(container.docker_tag_id)
21
+ container.update_attribute(:tag, tag.tag)
22
+ end
23
+ remove_foreign_key :containers, :name => :containers_docker_image_id_fk
24
+ remove_foreign_key :containers, :name => :containers_docker_tag_id_fk
25
+ remove_column :containers, :docker_image_id
26
+ remove_column :containers, :docker_tag_id
27
+
28
+ # these tables might have foreign keys from plugins like katello so use cascade
29
+ cascade_drop(:docker_images)
30
+ cascade_drop(:docker_tags)
31
+ cascade_drop(:docker_image_docker_registries)
32
+ end
33
+
34
+ def down
35
+ remove_column :containers, :repository_name
36
+ remove_column :containers, :registry_id
37
+ remove_column :containers, :tag
38
+ add_column :containers, :docker_image_id, :integer
39
+ add_column :containers, :docker_tag_id, :integer
40
+
41
+ create_table :docker_images do |t|
42
+ t.string :image_id
43
+ t.integer :size
44
+ t.timestamps
45
+ end
46
+ create_table :docker_tags do |t|
47
+ t.string :tag
48
+ t.references :docker_image, :null => false
49
+ t.timestamps
50
+ end
51
+ create_table :docker_image_docker_registries do |t|
52
+ t.integer :id
53
+ t.integer :docker_registry_id
54
+ t.integer :docker_image_id
55
+ end
56
+ end
57
+
58
+ def cascade_drop(table_name)
59
+ case connection.adapter_name.downcase.to_sym
60
+ when :mysql, :mysql2
61
+ execute "SET FOREIGN_KEY_CHECKS=0"
62
+ execute "DROP TABLE #{table_name}"
63
+ execute "SET FOREIGN_KEY_CHECKS=1"
64
+ when :pg, :postgresql
65
+ execute "DROP TABLE #{table_name} CASCADE"
66
+ when :sqlite
67
+ execute "DROP TABLE #{table_name}"
68
+ else
69
+ fail NotImplementedError, "Unknown adapter type '#{connection.adapter_name.downcase.to_sym}'"
70
+ end
71
+ end
72
+ end