ruby_llm-docker 0.2.5 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,99 +2,71 @@
2
2
 
3
3
  module RubyLLM
4
4
  module Docker
5
- # RubyLLM tool for stopping running Docker containers.
5
+ # MCP tool for stopping Docker containers.
6
6
  #
7
- # This tool provides the ability to gracefully stop running Docker containers
8
- # with configurable timeout handling. It sends a SIGTERM signal to the main
9
- # process and waits for the specified timeout before forcibly killing the
10
- # container with SIGKILL.
7
+ # This tool gracefully stops a running Docker container by sending a
8
+ # SIGTERM signal to the main process, allowing it to shut down cleanly.
9
+ # If the container doesn't stop within the specified timeout, it will
10
+ # be forcefully killed with SIGKILL.
11
11
  #
12
12
  # == Features
13
13
  #
14
14
  # - Graceful container shutdown with SIGTERM
15
- # - Configurable timeout before force kill
16
- # - Works with containers by ID or name
17
- # - Comprehensive error handling
18
- # - Safe for already stopped containers
19
- #
20
- # == Shutdown Process
21
- #
22
- # 1. Send SIGTERM to container's main process
23
- # 2. Wait for graceful shutdown up to timeout
24
- # 3. Send SIGKILL if container hasn't stopped
25
- # 4. Return success when container is stopped
15
+ # - Configurable timeout for forced termination
16
+ # - Supports container identification by ID or name
17
+ # - Handles both running and already-stopped containers
18
+ # - Provides clear feedback on operation status
19
+ # - Preserves container and data integrity
26
20
  #
27
21
  # == Security Considerations
28
22
  #
29
23
  # Stopping containers affects service availability:
30
- # - Services become unavailable immediately
31
- # - Network connections are terminated
32
- # - Data may be lost if not properly persisted
33
- # - Dependent services may be affected
24
+ # - **Service Disruption**: Terminates running services and processes
25
+ # - **Data Integrity**: May interrupt ongoing operations
26
+ # - **Resource Release**: Frees CPU, memory, and network resources
27
+ # - **State Preservation**: Maintains container state for future restart
28
+ #
29
+ # Coordinate container stops with dependent services and users.
34
30
  #
35
- # Best practices:
36
- # - Ensure data persistence before stopping
37
- # - Consider impact on dependent services
38
- # - Use appropriate timeout for graceful shutdown
39
- # - Monitor application logs during shutdown
31
+ # == Parameters
32
+ #
33
+ # - **id**: Container ID or name (required)
34
+ # - Accepts full container IDs
35
+ # - Accepts short container IDs (first 12+ characters)
36
+ # - Accepts custom container names
37
+ # - **timeout**: Seconds to wait before killing container (optional, default: 10)
40
38
  #
41
39
  # == Example Usage
42
40
  #
43
- # # Stop with default timeout (10 seconds)
44
- # StopContainer.call(
41
+ # # Stop with default timeout
42
+ # response = StopContainer.call(
45
43
  # server_context: context,
46
44
  # id: "web-server"
47
45
  # )
48
46
  #
49
47
  # # Stop with custom timeout
50
- # StopContainer.call(
48
+ # response = StopContainer.call(
51
49
  # server_context: context,
52
50
  # id: "database",
53
51
  # timeout: 30
54
52
  # )
55
53
  #
56
- # @see StartContainer
57
- # @see RemoveContainer
58
- # @see Docker::Container#stop
54
+ # @see ::Docker::Container#stop
59
55
  # @since 0.1.0
60
- class StopContainer < RubyLLM::Tool
56
+ STOP_CONTAINER_DEFINITION = ToolForge.define(:stop_container) do
61
57
  description 'Stop a Docker container'
62
58
 
63
- param :id, desc: 'Container ID or name'
64
- param :timeout, type: :integer, desc: 'Seconds to wait before killing the container (default: 10)',
65
- required: false
59
+ param :id,
60
+ type: :string,
61
+ description: 'Container ID or name'
62
+
63
+ param :timeout,
64
+ type: :integer,
65
+ description: 'Seconds to wait before killing the container (default: 10)',
66
+ required: false,
67
+ default: 10
66
68
 
67
- # Stop a running Docker container gracefully.
68
- #
69
- # This method stops a container by sending SIGTERM to the main process
70
- # and waiting for the specified timeout before sending SIGKILL. The
71
- # operation is idempotent - stopping an already stopped container
72
- # typically succeeds without error.
73
- #
74
- # @param id [String] container ID (full or short) or container name
75
- # @param server_context [Object] RubyLLM context (unused but required)
76
- # @param timeout [Integer] seconds to wait before force killing (default: 10)
77
- #
78
- # @return [RubyLLM::Tool::Response] stop operation results
79
- #
80
- # @raise [Docker::Error::NotFoundError] if container doesn't exist
81
- # @raise [StandardError] for other stop failures
82
- #
83
- # @example Stop with default timeout
84
- # response = StopContainer.call(
85
- # server_context: context,
86
- # id: "nginx-server"
87
- # )
88
- #
89
- # @example Stop database with longer timeout
90
- # response = StopContainer.call(
91
- # server_context: context,
92
- # id: "postgres-db",
93
- # timeout: 60 # Allow more time for DB shutdown
94
- # )
95
- #
96
- # @see Docker::Container#stop
97
- def execute(id:, timeout: 10)
69
+ execute do |id:, timeout: 10|
98
70
  container = ::Docker::Container.get(id)
99
71
  container.stop('timeout' => timeout)
100
72
 
@@ -105,5 +77,7 @@ module RubyLLM
105
77
  "Error stopping container: #{e.message}"
106
78
  end
107
79
  end
80
+
81
+ StopContainer = STOP_CONTAINER_DEFINITION.to_ruby_llm_tool
108
82
  end
109
83
  end
@@ -2,128 +2,98 @@
2
2
 
3
3
  module RubyLLM
4
4
  module Docker
5
- # RubyLLM tool for tagging Docker images.
5
+ # MCP tool for tagging Docker images.
6
6
  #
7
- # This tool provides the ability to create new tags for existing Docker images,
8
- # enabling better organization, versioning, and distribution of images. Tags
9
- # are essential for image management and registry operations.
7
+ # This tool provides the ability to assign repository names and tags
8
+ # to Docker images. Tagging is essential for image organization,
9
+ # versioning, and distribution through Docker registries.
10
10
  #
11
11
  # == Features
12
12
  #
13
- # - Tag images by ID or existing name
14
- # - Support for repository and tag specification
13
+ # - Tag existing images with custom repository names
14
+ # - Support for version and environment tags
15
15
  # - Force tagging to overwrite existing tags
16
- # - Registry-compatible tag formatting
17
- # - Comprehensive error handling
18
- # - Multiple tags per image support
19
- #
20
- # == Tag Management Benefits
21
- #
22
- # Proper tagging enables:
23
- # - **Version Control**: Track different image versions
24
- # - **Distribution**: Prepare images for registry push
25
- # - **Organization**: Group related images logically
26
- # - **Deployment**: Reference specific image versions
27
- # - **Rollback**: Maintain previous versions for rollback
16
+ # - Registry-compatible naming conventions
17
+ # - Automatic tag defaulting to "latest"
18
+ # - Comprehensive error handling and validation
28
19
  #
29
20
  # == Security Considerations
30
21
  #
31
- # Tagging affects image accessibility and distribution:
32
- # - Tags determine registry push destinations
33
- # - Overwriting tags can affect running containers
34
- # - Registry-compatible tags expose images for distribution
35
- # - Tag names may reveal application details
22
+ # Image tagging involves several security considerations:
23
+ # - **Registry Authentication**: Tags may trigger registry operations
24
+ # - **Namespace Conflicts**: Overwriting tags can affect other deployments
25
+ # - **Image Identity**: Improper tagging can lead to deployment confusion
26
+ # - **Version Management**: Incorrect tags can compromise CI/CD pipelines
27
+ # - **Registry Pollution**: Excessive tagging can clutter registries
36
28
  #
37
- # Best practices:
38
- # - Use descriptive but not sensitive tag names
39
- # - Avoid overwriting production tags accidentally
40
- # - Implement tag naming conventions
41
- # - Regular cleanup of unused tags
42
- # - Control access to critical tag operations
29
+ # **Security Recommendations**:
30
+ # - Use consistent naming conventions
31
+ # - Implement tag governance policies
32
+ # - Verify image identity before tagging
33
+ # - Avoid overwriting production tags
34
+ # - Use semantic versioning for releases
35
+ # - Monitor tag usage and lifecycle
43
36
  #
44
- # == Tag Naming Conventions
37
+ # == Parameters
45
38
  #
46
- # Recommended patterns:
47
- # - **Semantic Versioning**: `v1.2.3`, `1.2.3-alpha`
48
- # - **Environment Tags**: `prod`, `staging`, `dev`
49
- # - **Feature Tags**: `feature-branch-name`
50
- # - **Date Tags**: `2024-01-15`, `20240115`
51
- # - **Commit Tags**: `sha-abc123def`
39
+ # - **id**: Image ID or current name:tag to tag (required)
40
+ # - **repo**: Repository name (required, e.g., "username/imagename" or "registry/username/imagename")
41
+ # - **tag**: Tag for the image (optional, default: "latest")
42
+ # - **force**: Force tag even if it already exists (optional, default: true)
52
43
  #
53
44
  # == Example Usage
54
45
  #
55
- # # Tag with version
56
- # TagImage.call(
46
+ # # Tag image with version
47
+ # response = TagImage.call(
57
48
  # server_context: context,
58
- # id: "abc123def456",
59
- # repo: "myapp",
60
- # tag: "v1.0.0"
49
+ # id: "myapp:dev",
50
+ # repo: "myregistry/myapp",
51
+ # tag: "v1.2.3"
61
52
  # )
62
53
  #
63
- # # Tag for registry push
64
- # TagImage.call(
54
+ # # Tag for production deployment
55
+ # response = TagImage.call(
65
56
  # server_context: context,
66
- # id: "myapp:latest",
67
- # repo: "myusername/myapp",
68
- # tag: "production"
57
+ # id: "abc123def456",
58
+ # repo: "production/webapp",
59
+ # tag: "stable",
60
+ # force: false
69
61
  # )
70
62
  #
71
- # # Tag for private registry
72
- # TagImage.call(
63
+ # # Tag with registry prefix
64
+ # response = TagImage.call(
73
65
  # server_context: context,
74
- # id: "webapp:dev",
75
- # repo: "registry.company.com/team/webapp",
76
- # tag: "v2.1.0"
66
+ # id: "local-build:latest",
67
+ # repo: "registry.company.com/team/service",
68
+ # tag: "release-candidate"
77
69
  # )
78
70
  #
79
- # @see BuildImage
80
- # @see PushImage
81
- # @see Docker::Image#tag
71
+ # @see ::Docker::Image#tag
82
72
  # @since 0.1.0
83
- class TagImage < RubyLLM::Tool
73
+ TAG_IMAGE_DEFINITION = ToolForge.define(:tag_image) do
84
74
  description 'Tag a Docker image'
85
75
 
86
- param :id, type: :string, desc: 'Image ID or current name:tag'
87
- param :repo, type: :string,
88
- desc: 'Repository name (e.g., "username/imagename" or "registry/username/imagename")'
89
- param :tag, type: :string, desc: 'Tag for the image (default: "latest")', required: false
90
- param :force, type: :boolean, desc: 'Force tag even if it already exists (default: true)', required: false
76
+ param :id,
77
+ type: :string,
78
+ description: 'Image ID or current name:tag to tag'
91
79
 
92
- # Tag a Docker image with a new repository and tag name.
93
- #
94
- # This method creates a new tag for an existing image, allowing it to
95
- # be referenced by the new name. This is essential for organizing images
96
- # and preparing them for registry distribution.
97
- #
98
- # @param id [String] image ID or current name:tag to tag
99
- # @param repo [String] repository name for the new tag
100
- # @param server_context [Object] RubyLLM context (unused but required)
101
- # @param tag [String] tag name for the image (default: "latest")
102
- # @param force [Boolean] whether to overwrite existing tags (default: true)
103
- #
104
- # @return [RubyLLM::Tool::Response] tagging operation results
105
- #
106
- # @raise [Docker::Error::NotFoundError] if source image doesn't exist
107
- # @raise [StandardError] for other tagging failures
108
- #
109
- # @example Tag for versioning
110
- # response = TagImage.call(
111
- # server_context: context,
112
- # id: "my-app:latest",
113
- # repo: "my-app",
114
- # tag: "v1.2.3"
115
- # )
116
- #
117
- # @example Tag for registry push
118
- # response = tool.execute(
119
- # id: "abc123def456",
120
- # repo: "myregistry.com/myuser/myapp",
121
- # tag: "production",
122
- # force: true
123
- # )
124
- #
125
- # @see Docker::Image#tag
126
- def execute(id:, repo:, tag: 'latest', force: true)
80
+ param :repo,
81
+ type: :string,
82
+ description: 'Repository name (e.g., "username/imagename" or "registry/username/imagename")'
83
+
84
+ param :tag,
85
+ type: :string,
86
+ description: 'Tag for the image (default: "latest")',
87
+ required: false,
88
+ default: 'latest'
89
+
90
+ param :force,
91
+ type: :boolean,
92
+ description: 'Force tag even if it already exists (default: true)',
93
+ required: false,
94
+ default: true
95
+
96
+ execute do |id:, repo:, tag: 'latest', force: true|
127
97
  image = ::Docker::Image.get(id)
128
98
 
129
99
  image.tag('repo' => repo, 'tag' => tag, 'force' => force)
@@ -135,5 +105,7 @@ module RubyLLM
135
105
  "Error tagging image: #{e.message}"
136
106
  end
137
107
  end
108
+
109
+ TagImage = TAG_IMAGE_DEFINITION.to_ruby_llm_tool
138
110
  end
139
111
  end
@@ -2,6 +2,15 @@
2
2
 
3
3
  module RubyLLM
4
4
  module Docker
5
- VERSION = '0.2.5'
5
+ # Current version of the RubyLLM::Docker gem.
6
+ #
7
+ # This constant follows semantic versioning (SemVer) principles:
8
+ # - MAJOR version for incompatible API changes
9
+ # - MINOR version for backwards-compatible functionality additions
10
+ # - PATCH version for backwards-compatible bug fixes
11
+ #
12
+ # @see https://semver.org/
13
+ # @since 0.1.0
14
+ VERSION = '0.3.0'
6
15
  end
7
16
  end
@@ -3,6 +3,7 @@
3
3
  require 'ruby_llm'
4
4
  require 'docker'
5
5
  require 'shellwords'
6
+ require 'tool_forge'
6
7
  require 'zeitwerk'
7
8
 
8
9
  loader = Zeitwerk::Loader.for_gem_extension(RubyLLM)
@@ -11,6 +12,18 @@ loader.setup
11
12
  require_relative 'docker/version'
12
13
 
13
14
  module RubyLLM
15
+ # Docker tools module providing comprehensive Docker management capabilities for RubyLLM.
16
+ #
17
+ # This module contains 22 Docker management tools organized into four categories:
18
+ # - Container Management (10 tools)
19
+ # - Image Management (6 tools)
20
+ # - Network Management (3 tools)
21
+ # - Volume Management (3 tools)
22
+ #
23
+ # @example Basic usage
24
+ # chat = RubyLLM::Chat.new(api_key: 'your-key', model: 'gpt-4')
25
+ # RubyLLM::Docker.add_all_tools_to_chat(chat)
26
+ # response = chat.ask("How many containers are running?")
14
27
  module Docker
15
28
  class Error < StandardError; end
16
29
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby_llm-docker
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.5
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Aaron F Stanton
@@ -51,6 +51,20 @@ dependencies:
51
51
  - - ">="
52
52
  - !ruby/object:Gem::Version
53
53
  version: '0'
54
+ - !ruby/object:Gem::Dependency
55
+ name: tool_forge
56
+ requirement: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ type: :runtime
62
+ prerelease: false
63
+ version_requirements: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: '0'
54
68
  - !ruby/object:Gem::Dependency
55
69
  name: zeitwerk
56
70
  requirement: !ruby/object:Gem::Requirement