Module: LanguageOperator::CLI::Commands::System::Helpers::PodManager
- Defined in:
- lib/language_operator/cli/commands/system/helpers/pod_manager.rb
Overview
Pod management utilities for exec command
Instance Method Summary collapse
-
#create_agent_configmap(name, code) ⇒ Object
Create a ConfigMap with agent code.
-
#create_test_pod(name, configmap_name, image) ⇒ Object
Create a test pod for running the agent.
-
#delete_configmap(name) ⇒ Object
Delete a ConfigMap.
-
#delete_pod(name) ⇒ Object
Delete a pod.
-
#detect_model_config ⇒ Object
Detect model configuration from the cluster.
-
#get_pod_status(name) ⇒ Object
Get pod status.
-
#stream_pod_logs(name, timeout: 300) ⇒ Object
Stream pod logs until completion.
-
#wait_for_pod_start(name, timeout: 60) ⇒ Object
Wait for pod to start (running or terminated).
-
#wait_for_pod_termination(name, timeout: 10) ⇒ Object
Wait for pod to terminate and get exit code.
Instance Method Details
#create_agent_configmap(name, code) ⇒ Object
Create a ConfigMap with agent code
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
# File 'lib/language_operator/cli/commands/system/helpers/pod_manager.rb', line 13 def create_agent_configmap(name, code) configmap = { 'apiVersion' => 'v1', 'kind' => 'ConfigMap', 'metadata' => { 'name' => name, 'namespace' => ctx.namespace }, 'data' => { 'agent.rb' => code } } ctx.client.create_resource(configmap) end |
#create_test_pod(name, configmap_name, image) ⇒ Object
Create a test pod for running the agent
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
# File 'lib/language_operator/cli/commands/system/helpers/pod_manager.rb', line 30 def create_test_pod(name, configmap_name, image) # Detect available models in the cluster model_env = detect_model_config if model_env.nil? Formatters::ProgressFormatter.warn('Could not detect model configuration from cluster') Formatters::ProgressFormatter.warn('Agent may fail without MODEL_ENDPOINTS configured') end env_vars = [ { 'name' => 'AGENT_NAME', 'value' => name }, { 'name' => 'AGENT_MODE', 'value' => 'autonomous' }, { 'name' => 'AGENT_CODE_PATH', 'value' => '/etc/agent/code/agent.rb' }, { 'name' => 'CONFIG_PATH', 'value' => '/nonexistent/config.yaml' } ] # Add model configuration if available env_vars += model_env if model_env pod = { 'apiVersion' => 'v1', 'kind' => 'Pod', 'metadata' => { 'name' => name, 'namespace' => ctx.namespace, 'labels' => Constants::KubernetesLabels.test_agent_labels(name).merge( Constants::KubernetesLabels::KIND_LABEL => 'LanguageAgent' ) }, 'spec' => { 'restartPolicy' => 'Never', 'containers' => [ { 'name' => 'agent', 'image' => image, 'imagePullPolicy' => 'Always', 'env' => env_vars, 'volumeMounts' => [ { 'name' => 'agent-code', 'mountPath' => '/etc/agent/code', 'readOnly' => true } ] } ], 'volumes' => [ { 'name' => 'agent-code', 'configMap' => { 'name' => configmap_name } } ] } } ctx.client.create_resource(pod) end |
#delete_configmap(name) ⇒ Object
Delete a ConfigMap
202 203 204 205 206 |
# File 'lib/language_operator/cli/commands/system/helpers/pod_manager.rb', line 202 def delete_configmap(name) ctx.client.delete_resource('ConfigMap', name, ctx.namespace) rescue K8s::Error::NotFound # Already deleted end |
#delete_pod(name) ⇒ Object
Delete a pod
195 196 197 198 199 |
# File 'lib/language_operator/cli/commands/system/helpers/pod_manager.rb', line 195 def delete_pod(name) ctx.client.delete_resource('Pod', name, ctx.namespace) rescue K8s::Error::NotFound # Already deleted end |
#detect_model_config ⇒ Object
Detect model configuration from the cluster
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 |
# File 'lib/language_operator/cli/commands/system/helpers/pod_manager.rb', line 91 def detect_model_config models = ctx.client.list_resources('LanguageModel', namespace: ctx.namespace) return nil if models.empty? # Use first available model model = models.first model_name = model.dig('metadata', 'name') model_id = model.dig('spec', 'modelName') # Build endpoint URL (port 8000 is the model service port) endpoint = "http://#{model_name}.#{ctx.namespace}.svc.cluster.local:8000" [ { 'name' => 'MODEL_ENDPOINTS', 'value' => endpoint }, { 'name' => 'LLM_MODEL', 'value' => model_id }, { 'name' => 'OPENAI_API_KEY', 'value' => 'sk-dummy-key-for-local-proxy' } ] rescue StandardError => e Formatters::ProgressFormatter.error("Failed to detect model configuration: #{e.}") nil end |
#get_pod_status(name) ⇒ Object
Get pod status
189 190 191 192 |
# File 'lib/language_operator/cli/commands/system/helpers/pod_manager.rb', line 189 def get_pod_status(name) pod = ctx.client.get_resource('Pod', name, ctx.namespace) pod.to_h.fetch('status', {}) end |
#stream_pod_logs(name, timeout: 300) ⇒ Object
Stream pod logs until completion
129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 |
# File 'lib/language_operator/cli/commands/system/helpers/pod_manager.rb', line 129 def stream_pod_logs(name, timeout: 300) require 'open3' cmd = "kubectl logs -f -n #{ctx.namespace} #{name} 2>&1" Open3.popen3(cmd) do |_stdin, stdout, _stderr, wait_thr| # Set up timeout start_time = Time.now # Stream logs stdout.each_line do |line| puts line # Check timeout if Time.now - start_time > timeout Process.kill('TERM', wait_thr.pid) raise "Log streaming timed out after #{timeout} seconds" end end # Wait for process to complete wait_thr.value end rescue Errno::EPIPE # Pod terminated, logs finished end |
#wait_for_pod_start(name, timeout: 60) ⇒ Object
Wait for pod to start (running or terminated)
114 115 116 117 118 119 120 121 122 123 124 125 126 |
# File 'lib/language_operator/cli/commands/system/helpers/pod_manager.rb', line 114 def wait_for_pod_start(name, timeout: 60) start_time = Time.now loop do pod = ctx.client.get_resource('Pod', name, ctx.namespace) phase = pod.dig('status', 'phase') return if %w[Running Succeeded Failed].include?(phase) raise "Pod #{name} did not start within #{timeout} seconds" if Time.now - start_time > timeout sleep 1 end end |
#wait_for_pod_termination(name, timeout: 10) ⇒ Object
Wait for pod to terminate and get exit code
156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 |
# File 'lib/language_operator/cli/commands/system/helpers/pod_manager.rb', line 156 def wait_for_pod_termination(name, timeout: 10) # Give the pod a moment to fully transition after logs complete sleep 2 start_time = Time.now loop do pod = ctx.client.get_resource('Pod', name, ctx.namespace) phase = pod.dig('status', 'phase') container_status = pod.dig('status', 'containerStatuses', 0) # Pod completed successfully or failed if %w[Succeeded Failed].include?(phase) && container_status && (terminated = container_status.dig('state', 'terminated')) return terminated['exitCode'] end # Check timeout if Time.now - start_time > timeout # Try one last time if container_status && (terminated = container_status.dig('state', 'terminated')) return terminated['exitCode'] end return nil end sleep 0.5 rescue K8s::Error::NotFound # Pod was deleted before we could get status return nil end end |