Skip to content

Commit

Permalink
migration for merging container and container_definition
Browse files Browse the repository at this point in the history
  • Loading branch information
Ari Zellner committed Jul 2, 2017
1 parent e9d356d commit be9e7a7
Show file tree
Hide file tree
Showing 3 changed files with 285 additions and 21 deletions.
169 changes: 169 additions & 0 deletions db/migrate/20170529142557_unify_container_definition_and_container.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
class UnifyContainerDefinitionAndContainer < ActiveRecord::Migration[5.0]
class ContainerDefinition < ActiveRecord::Base
has_many :container_port_configs, :class_name => 'UnifyContainerDefinitionAndContainer::ContainerPortConfig'
has_many :container_env_vars, :class_name => 'UnifyContainerDefinitionAndContainer::ContainerEnvVar'
has_one :security_context, :as => :resource
has_one :container, :class_name => 'UnifyContainerDefinitionAndContainer::Container'
end

class Container < ActiveRecord::Base
belongs_to :container_definition, :class_name => 'UnifyContainerDefinitionAndContainer::ContainerDefinition'
end

class SecurityContext < ActiveRecord::Base
self.inheritance_column = :_type_disabled
belongs_to :resource, :polymorphic => true
end

class ContainerEnvVar < ActiveRecord::Base
belongs_to :container_definition, :class_name => 'UnifyContainerDefinitionAndContainer::ContainerDefinition'
end

class ContainerPortConfig < ActiveRecord::Base
belongs_to :container_definition, :class_name => 'UnifyContainerDefinitionAndContainer::ContainerDefinition'
end

def up
# attributes
add_column :containers, :image, :string
add_column :containers, :image_pull_policy, :string
add_column :containers, :memory, :string
add_column :containers, :cpu_cores, :float
add_column :containers, :container_group_id, :bigint
add_column :containers, :privileged, :boolean
add_column :containers, :run_as_user, :bigint
add_column :containers, :run_as_non_root, :boolean
add_column :containers, :capabilities_add, :string
add_column :containers, :capabilities_drop, :string
add_column :containers, :command, :text

containers = Arel::Table.new(:containers)
definitions = Arel::Table.new(:container_definitions)
say_with_time("Copying over columns from container_definition to container") do
%w(image image_pull_policy memory cpu_cores container_group_id privileged
run_as_user run_as_non_root capabilities_add capabilities_drop command).each do |column|
join_sql = definitions.project(definitions[column.to_sym])
.where(definitions[:id].eq(containers[:container_definition_id])).to_sql
Container.update_all("#{column} = (#{join_sql})")
end
end

say_with_time("switch container_definition_id with container_id for container_port_configs") do
port_configs = Arel::Table.new(:container_port_configs)
join_sql = containers.project(containers[:id])
.where(containers[:container_definition_id].eq(port_configs[:container_definition_id])).to_sql
ContainerPortConfig.update_all("container_definition_id = (#{join_sql})")
end

say_with_time("switch container_definition_id with container_id for container_port_configs") do
env_vars = Arel::Table.new(:container_env_vars)
join_sql = containers.project(containers[:id])
.where(containers[:container_definition_id].eq(env_vars[:container_definition_id])).to_sql
ContainerEnvVar.update_all("container_definition_id = (#{join_sql})")
end

say_with_time("switch container_definition_id with container_id for security_contexts") do
security_contexts = Arel::Table.new(:security_contexts)
join_sql = containers.project(containers[:id])
.where(containers[:container_definition_id].eq(security_contexts[:resource_id])
.and(security_contexts[:resource_type].eq(Arel::Nodes::Quoted.new('ContainerDefinition')))).to_sql
SecurityContext.where(:resource_type => 'ContainerDefinition').update_all("resource_type = 'Container', resource_id = (#{join_sql})")
end

# relationships
rename_column :container_port_configs, :container_definition_id, :container_id
rename_column :container_env_vars, :container_definition_id, :container_id

remove_column :containers, :container_definition_id
drop_table :container_definitions
end

def down
create_table :container_definitions do |t|
t.belongs_to :ems, :type => :bigint
t.string :ems_ref
t.bigint :old_ems_id
t.timestamp :deleted_on
t.string :name
t.string :image
t.string :image_pull_policy
t.string :memory
t.float :cpu_cores
t.belongs_to :container_group, :type => :bigint
t.boolean :privileged
t.bigint :run_as_user
t.boolean :run_as_non_root
t.string :capabilities_add
t.string :capabilities_drop
t.text :command
end

add_column :containers, :container_definition_id, :bigint

say_with_time("splitting columns from container into container_definition") do
ContainerDefinition.transaction do
Container.all.each do |container|
container_def = ContainerDefinition.create(
:ems_id => container.ems_id,
:ems_ref => container.ems_ref,
:old_ems_id => container.old_ems_id,
:deleted_on => container.deleted_on,
:name => container.name,
:image => container.image,
:image_pull_policy => container.image_pull_policy,
:memory => container.memory,
:cpu_cores => container.cpu_cores,
:container_group_id => container.container_group_id,
:privileged => container.privileged,
:run_as_user => container.run_as_user,
:run_as_non_root => container.run_as_non_root,
:capabilities_add => container.capabilities_add,
:capabilities_drop => container.capabilities_drop,
:command => container.command
)
container.update!(:container_definition_id => container_def.id)
end
end
end

containers = Arel::Table.new(:containers)
say_with_time("switch container_definition_id with container_id for container_port_configs") do
port_configs = Arel::Table.new(:container_port_configs)
join_sql = containers.project(containers[:container_definition_id])
.where(containers[:id].eq(port_configs[:container_id])).to_sql
ContainerPortConfig.update_all("container_id = (#{join_sql})")
end

say_with_time("switch container_definition_id with container_id for container_port_configs") do
env_vars = Arel::Table.new(:container_env_vars)
join_sql = containers.project(containers[:container_definition_id])
.where(containers[:id].eq(env_vars[:container_id])).to_sql
ContainerEnvVar.update_all("container_id = (#{join_sql})")
end

say_with_time("switch container_definition_id with container_id for security_contexts") do
security_contexts = Arel::Table.new(:security_contexts)
join_sql = containers.project(containers[:container_definition_id])
.where(containers[:id].eq(security_contexts[:resource_id])
.and(security_contexts[:resource_type].eq(Arel::Nodes::Quoted.new('Container')))).to_sql
SecurityContext.where(:resource_type => 'Container').update_all("resource_type = 'ContainerDefinition', resource_id = (#{join_sql})")
end

# relationships
rename_column :container_port_configs, :container_id, :container_definition_id
rename_column :container_env_vars, :container_id, :container_definition_id

# attributes
remove_column :containers, :image
remove_column :containers, :image_pull_policy
remove_column :containers, :memory
remove_column :containers, :cpu_cores
remove_column :containers, :container_group_id
remove_column :containers, :privileged
remove_column :containers, :run_as_user
remove_column :containers, :run_as_non_root
remove_column :containers, :capabilities_add
remove_column :containers, :capabilities_drop
remove_column :containers, :command
end
end
34 changes: 13 additions & 21 deletions db/schema.yml
Original file line number Diff line number Diff line change
Expand Up @@ -643,24 +643,6 @@ container_conditions:
- reason
- message
- container_entity_type
container_definitions:
- id
- ems_ref
- name
- image
- image_pull_policy
- memory
- cpu_cores
- container_group_id
- privileged
- run_as_user
- run_as_non_root
- capabilities_add
- capabilities_drop
- command
- deleted_on
- ems_id
- old_ems_id
container_deployment_nodes:
- id
- address
Expand Down Expand Up @@ -693,7 +675,7 @@ container_env_vars:
- name
- value
- field_path
- container_definition_id
- container_id
container_groups:
- id
- ems_ref
Expand Down Expand Up @@ -801,7 +783,7 @@ container_port_configs:
- port
- host_port
- protocol
- container_definition_id
- container_id
- name
container_projects:
- id
Expand Down Expand Up @@ -945,7 +927,6 @@ containers:
- name
- backing_ref
- last_perf_capture_on
- container_definition_id
- type
- container_image_id
- reason
Expand All @@ -964,6 +945,17 @@ containers:
- deleted_on
- ems_id
- old_ems_id
- image
- image_pull_policy
- memory
- cpu_cores
- container_group_id
- privileged
- run_as_user
- run_as_non_root
- capabilities_add
- capabilities_drop
- command
custom_attributes:
- id
- section
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
require_migration

describe UnifyContainerDefinitionAndContainer do
let(:container_stub) { migration_stub(:Container) }
let(:container_definition_stub) { migration_stub(:ContainerDefinition) }

let(:security_context_stub) { migration_stub(:SecurityContext) }
let(:container_env_var_stub) { migration_stub(:ContainerEnvVar) }
let(:container_port_config_stub) { migration_stub(:ContainerPortConfig) }

let(:definition_hash) do
{
:image => "my_image",
:image_pull_policy => "image_pull_policy",
:memory => "memory",
:cpu_cores => 1.1,
:container_group_id => 1,
:privileged => true,
:run_as_user => 2,
:run_as_non_root => true,
:capabilities_add => "capabilities_add",
:capabilities_drop => "capabilities_drop",
:command => "command"
}
end

let(:container_hash) do
{
:name => "mycontainer",
:ems_ref => "123",
:ems_id => 1,
:old_ems_id => 1,
:deleted_on => Time.now.beginning_of_hour.utc
}
end

migration_context :up do
it "merges container_defintion and container" do
container_def = container_definition_stub.create!(definition_hash)
container = container_stub.create!(container_hash.merge(:container_definition => container_def))
container_env_var_stub.create!(:name => "REGISTRY_HTTP_ADDR",
:value => ":5000",
:container_definition_id => container_def.id)
container_port_config_stub.create!(:ems_ref => "2da0c9e4",
:port => 5000,
:protocol => "TCP",
:container_definition_id => container_def.id)
security_context_stub.create!(:se_linux_level => "s0:c1,c0",
:resource_id => container_def.id,
:resource_type => 'ContainerDefinition')

container_def2 = container_definition_stub.create!(definition_hash.merge(:image => "my_image2"))
container2 = container_stub.create!(container_hash.merge(:container_definition => container_def2, :name => "mycontainer2"))
container_def2.container_env_vars << container_env_var_stub.create!(:name => "REGISTRY_HTTP_ADDR",
:value => ":5000")
container_def2.container_port_configs << container_port_config_stub.create!(:ems_ref => "2da0c9e4",
:port => 5000,
:protocol => "TCP")
security_context_stub.create!(:se_linux_level => "s0:c1,c0",
:resource_id => container_def2.id,
:resource_type => 'ContainerDefinition')

migrate

expect(container_stub.first).to have_attributes(definition_hash.merge(container_hash))

expect(container_port_config_stub.first).to have_attributes(:container_id => container.id)
expect(container_env_var_stub.first).to have_attributes(:container_id => container.id)
expect(security_context_stub.first).to have_attributes(:resource_type => "Container",
:resource_id => container.id)

expect(container_port_config_stub.second).to have_attributes(:container_id => container2.id)
expect(container_env_var_stub.second).to have_attributes(:container_id => container2.id)
expect(security_context_stub.second).to have_attributes(:resource_type => "Container",
:resource_id => container2.id)
end
end

migration_context :down do
it "splits container_definition columns from container" do
container = container_stub.create!(definition_hash.merge(container_hash))
container_env_var_stub.create!(:name => "REGISTRY_HTTP_ADDR",
:value => ":5000", :field_path => nil,
:container_id => container.id)
container_port_config_stub.create!(:ems_ref => "2da0c9e4",
:port => 5000,
:protocol => "TCP",
:container_id => container.id)
security_context_stub.create!(:resource_type => "Container",
:resource_id => container.id,
:se_linux_level => "s0:c1,c0")

migrate

container_def = container_definition_stub.first
expect(container_def).to have_attributes(definition_hash)
expect(container_env_var_stub.first).to have_attributes(:container_definition_id => container_def.id)
expect(container_port_config_stub.first).to have_attributes(:container_definition_id => container_def.id)
expect(security_context_stub.first).to have_attributes(:resource_type => "ContainerDefinition",
:resource_id => container_def.id)
end
end
end

0 comments on commit be9e7a7

Please sign in to comment.