Class: Gjallarhorn::Deployment::Basic

Inherits:
Strategy
  • Object
show all
Defined in:
lib/gjallarhorn/deployment/basic.rb

Overview

Basic deployment strategy

Implements a simple deployment strategy that stops old containers and starts new ones without zero-downtime guarantees. This is the fallback strategy when zero-downtime features are not needed.

Since:

  • 0.1.0

Instance Attribute Summary

Attributes inherited from Strategy

#adapter, #logger, #proxy_manager

Instance Method Summary collapse

Methods inherited from Strategy

#initialize, #name

Constructor Details

This class inherits a constructor from Gjallarhorn::Deployment::Strategy

Instance Method Details

#build_container_labels(service, environment) ⇒ Hash (private)

Build container labels for identification and management

Parameters:

  • service (Hash)

    Service configuration

  • environment (String)

    Target environment

Returns:

  • (Hash)

    Container labels

Since:

  • 0.1.0



133
134
135
136
137
138
139
140
141
# File 'lib/gjallarhorn/deployment/basic.rb', line 133

def build_container_labels(service, environment)
  {
    "gjallarhorn.service" => service[:name],
    "gjallarhorn.environment" => environment,
    "gjallarhorn.role" => service[:role] || "web",
    "gjallarhorn.deployed_at" => Time.now.utc.iso8601,
    "gjallarhorn.strategy" => "basic"
  }
end

#build_environment_variables(service, environment) ⇒ Hash (private)

Build environment variables for container

Parameters:

  • service (Hash)

    Service configuration

  • environment (String)

    Target environment

Returns:

  • (Hash)

    Environment variables

Since:

  • 0.1.0



115
116
117
118
119
120
121
122
123
124
125
126
# File 'lib/gjallarhorn/deployment/basic.rb', line 115

def build_environment_variables(service, environment)
  env_vars = {
    "GJALLARHORN_SERVICE" => service[:name],
    "GJALLARHORN_ENVIRONMENT" => environment,
    "GJALLARHORN_DEPLOYED_AT" => Time.now.utc.iso8601
  }

  # Add service-specific environment variables
  env_vars.merge!(service[:env]) if service[:env]

  env_vars
end

#deploy(image:, environment:, services:) ⇒ void

This method returns an undefined value.

Deploy services using basic strategy

Parameters:

  • image (String)

    Container image to deploy

  • environment (String)

    Target environment

  • services (Array<Hash>)

    Services to deploy

Since:

  • 0.1.0



21
22
23
24
25
26
27
28
29
30
# File 'lib/gjallarhorn/deployment/basic.rb', line 21

def deploy(image:, environment:, services:)
  @logger.info "Starting basic deployment of #{image} to #{environment}"

  services.each do |service|
    @logger.info "Deploying service: #{service[:name]}"
    deploy_service_basic(service, image, environment)
  end

  @logger.info "Basic deployment completed successfully"
end

#deploy_service_basic(service, image, environment) ⇒ void (private)

This method returns an undefined value.

Deploy a single service using basic strategy

Parameters:

  • service (Hash)

    Service configuration

  • image (String)

    Container image to deploy

  • environment (String)

    Target environment

Since:

  • 0.1.0



47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/gjallarhorn/deployment/basic.rb', line 47

def deploy_service_basic(service, image, environment)
  service_name = service[:name]

  # Step 1: Stop existing containers
  @logger.info "Stopping existing containers for #{service_name}..."
  stop_existing_containers(service_name)

  # Step 2: Start new container
  new_container = start_new_container(service, image, environment)
  @logger.info "Started new container: #{new_container[:name]} (#{new_container[:id]})"

  # Step 3: Wait for container to be running
  wait_for_container_running(new_container)

  # Step 4: Optional health check
  if service[:healthcheck]
    @logger.info "Waiting for health check to pass..."
    wait_for_container_health(new_container, service[:healthcheck])
  end

  @logger.info "Service #{service_name} deployed successfully"
end

#start_new_container(service, image, environment) ⇒ Hash (private)

Start a new container for the service

Parameters:

  • service (Hash)

    Service configuration

  • image (String)

    Container image

  • environment (String)

    Target environment

Returns:

  • (Hash)

    New container information

Since:

  • 0.1.0



93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
# File 'lib/gjallarhorn/deployment/basic.rb', line 93

def start_new_container(service, image, environment)
  container_name = generate_container_name(service[:name])

  container_config = {
    name: container_name,
    image: image,
    ports: service[:ports] || [],
    env: build_environment_variables(service, environment),
    volumes: service[:volumes] || [],
    command: service[:cmd],
    labels: build_container_labels(service, environment),
    restart_policy: service[:restart_policy] || "unless-stopped"
  }

  @adapter.start_container(container_config)
end

#stop_existing_containers(service_name) ⇒ void (private)

This method returns an undefined value.

Stop all existing containers for a service

Parameters:

  • service_name (String)

    Service name

Since:

  • 0.1.0



74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/gjallarhorn/deployment/basic.rb', line 74

def stop_existing_containers(service_name)
  current_containers = @adapter.get_running_containers(service_name)

  current_containers.each do |container|
    @logger.info "Stopping container: #{container[:name]} (#{container[:id]})"
    @adapter.stop_container(container[:id], graceful: true)
    @adapter.remove_container(container[:id])
  end
rescue StandardError => e
  @logger.warn "Failed to stop some existing containers: #{e.message}"
  # Continue with deployment even if cleanup fails
end

#wait_for_container_running(container, timeout = 60) ⇒ Boolean (private)

Wait for container to be in running state

Parameters:

  • container (Hash)

    Container information

  • timeout (Integer) (defaults to: 60)

    Timeout in seconds

Returns:

  • (Boolean)

    True when container is running

Since:

  • 0.1.0



148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
# File 'lib/gjallarhorn/deployment/basic.rb', line 148

def wait_for_container_running(container, timeout = 60)
  start_time = Time.now

  loop do
    status = @adapter.get_container_status(container[:id])

    if status == "running"
      @logger.info "Container #{container[:name]} is running"
      return true
    end

    elapsed = Time.now - start_time
    if elapsed >= timeout
      raise DeploymentError,
            "Container #{container[:name]} failed to start within #{timeout}s (status: #{status})"
    end

    @logger.debug "Container #{container[:name]} status: #{status}, waiting..."
    sleep 2
  end
end

#zero_downtime?Boolean

Check if strategy supports zero-downtime deployments

Returns:

  • (Boolean)

    Always false for basic strategy

Since:

  • 0.1.0



35
36
37
# File 'lib/gjallarhorn/deployment/basic.rb', line 35

def zero_downtime?
  false
end