ruby_llm-docker 0.0.1 → 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.
- checksums.yaml +4 -4
- data/README.md +255 -11
- data/Rakefile +3 -3
- data/examples/docker_chat.rb +269 -0
- data/examples/list_containers.rb +36 -0
- data/examples/test_chat.rb +81 -0
- data/lib/ruby_llm/docker/build_image.rb +110 -0
- data/lib/ruby_llm/docker/copy_to_container.rb +151 -0
- data/lib/ruby_llm/docker/create_container.rb +124 -0
- data/lib/ruby_llm/docker/create_network.rb +115 -0
- data/lib/ruby_llm/docker/create_volume.rb +107 -0
- data/lib/ruby_llm/docker/exec_container.rb +168 -0
- data/lib/ruby_llm/docker/fetch_container_logs.rb +110 -0
- data/lib/ruby_llm/docker/list_containers.rb +65 -0
- data/lib/ruby_llm/docker/list_images.rb +58 -0
- data/lib/ruby_llm/docker/list_networks.rb +59 -0
- data/lib/ruby_llm/docker/list_volumes.rb +59 -0
- data/lib/ruby_llm/docker/pull_image.rb +103 -0
- data/lib/ruby_llm/docker/push_image.rb +124 -0
- data/lib/ruby_llm/docker/recreate_container.rb +119 -0
- data/lib/ruby_llm/docker/remove_container.rb +92 -0
- data/lib/ruby_llm/docker/remove_image.rb +100 -0
- data/lib/ruby_llm/docker/remove_network.rb +84 -0
- data/lib/ruby_llm/docker/remove_volume.rb +94 -0
- data/lib/ruby_llm/docker/run_container.rb +124 -0
- data/lib/ruby_llm/docker/start_container.rb +74 -0
- data/lib/ruby_llm/docker/stop_container.rb +83 -0
- data/lib/ruby_llm/docker/tag_image.rb +111 -0
- data/lib/ruby_llm/docker/version.rb +11 -2
- data/lib/ruby_llm/docker.rb +66 -3
- data/sig/ruby_llm/docker.rbs +1 -1
- metadata +104 -5
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RubyLLM
|
|
4
|
+
module Docker
|
|
5
|
+
# MCP tool for pushing Docker images to registries.
|
|
6
|
+
#
|
|
7
|
+
# This tool provides the ability to upload Docker images to Docker
|
|
8
|
+
# registries such as Docker Hub, private registries, or cloud-based
|
|
9
|
+
# container registries. It supports various push configurations and
|
|
10
|
+
# authentication scenarios.
|
|
11
|
+
#
|
|
12
|
+
# == Features
|
|
13
|
+
#
|
|
14
|
+
# - Push images to any Docker registry
|
|
15
|
+
# - Support for tagged and untagged pushes
|
|
16
|
+
# - Registry authentication integration
|
|
17
|
+
# - Comprehensive error handling and validation
|
|
18
|
+
# - Multi-registry support
|
|
19
|
+
# - Progress tracking and status reporting
|
|
20
|
+
# - Registry namespace validation
|
|
21
|
+
#
|
|
22
|
+
# == Security Considerations
|
|
23
|
+
#
|
|
24
|
+
# Pushing images involves significant security risks:
|
|
25
|
+
# - **Credential Exposure**: Registry credentials may be exposed
|
|
26
|
+
# - **Image Integrity**: Pushed images become publicly accessible
|
|
27
|
+
# - **Supply Chain Risk**: Malicious images can be distributed
|
|
28
|
+
# - **Registry Security**: Vulnerable registries can be compromised
|
|
29
|
+
# - **Network Exposure**: Push operations traverse networks
|
|
30
|
+
# - **Access Control**: Improper permissions can lead to unauthorized access
|
|
31
|
+
#
|
|
32
|
+
# **Security Recommendations**:
|
|
33
|
+
# - Use secure registry authentication
|
|
34
|
+
# - Scan images for vulnerabilities before pushing
|
|
35
|
+
# - Implement image signing and verification
|
|
36
|
+
# - Use private registries for sensitive images
|
|
37
|
+
# - Monitor registry access and usage
|
|
38
|
+
# - Implement proper RBAC for registry operations
|
|
39
|
+
# - Validate image content before distribution
|
|
40
|
+
#
|
|
41
|
+
# == Parameters
|
|
42
|
+
#
|
|
43
|
+
# - **name**: Image name or ID to push (required)
|
|
44
|
+
# - **tag**: Tag to push (optional, pushes all tags if not specified)
|
|
45
|
+
# - **repo_tag**: Full repo:tag to push (optional, e.g., "registry/repo:tag")
|
|
46
|
+
#
|
|
47
|
+
# == Example Usage
|
|
48
|
+
#
|
|
49
|
+
# # Push to Docker Hub
|
|
50
|
+
# response = PushImage.call(
|
|
51
|
+
# server_context: context,
|
|
52
|
+
# name: "username/myapp",
|
|
53
|
+
# tag: "v1.0.0"
|
|
54
|
+
# )
|
|
55
|
+
#
|
|
56
|
+
# # Push to private registry
|
|
57
|
+
# response = PushImage.call(
|
|
58
|
+
# server_context: context,
|
|
59
|
+
# name: "myapp",
|
|
60
|
+
# repo_tag: "registry.company.com/team/myapp:latest"
|
|
61
|
+
# )
|
|
62
|
+
#
|
|
63
|
+
# # Push all tags
|
|
64
|
+
# response = PushImage.call(
|
|
65
|
+
# server_context: context,
|
|
66
|
+
# name: "username/myapp"
|
|
67
|
+
# )
|
|
68
|
+
#
|
|
69
|
+
# @see Docker CLI push command
|
|
70
|
+
# @since 0.1.0
|
|
71
|
+
PUSH_IMAGE_DEFINITION = ToolForge.define(:push_image) do
|
|
72
|
+
description 'Push a Docker image'
|
|
73
|
+
|
|
74
|
+
param :name,
|
|
75
|
+
type: :string,
|
|
76
|
+
description: 'Image name or ID to push'
|
|
77
|
+
|
|
78
|
+
param :tag,
|
|
79
|
+
type: :string,
|
|
80
|
+
description: 'Tag to push (optional, pushes all tags if not specified)',
|
|
81
|
+
required: false
|
|
82
|
+
|
|
83
|
+
param :repo_tag,
|
|
84
|
+
type: :string,
|
|
85
|
+
description: 'Full repo:tag to push (e.g., "registry/repo:tag") (optional)',
|
|
86
|
+
required: false
|
|
87
|
+
|
|
88
|
+
execute do |name:, tag: nil, repo_tag: nil|
|
|
89
|
+
# Construct the full image identifier
|
|
90
|
+
image_identifier = tag ? "#{name}:#{tag}" : name
|
|
91
|
+
|
|
92
|
+
# Validate that the image name includes a registry/username
|
|
93
|
+
unless name.include?('/') || repo_tag&.include?('/')
|
|
94
|
+
next 'Error: Image name must include registry/username ' \
|
|
95
|
+
"(e.g., 'username/#{name}'). Local images cannot be " \
|
|
96
|
+
'pushed without a registry prefix.'
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
# Verify the image exists
|
|
100
|
+
begin
|
|
101
|
+
::Docker::Image.get(image_identifier)
|
|
102
|
+
rescue ::Docker::Error::NotFoundError
|
|
103
|
+
next "Image #{image_identifier} not found"
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
# Use the Docker CLI to push the image
|
|
107
|
+
push_target = repo_tag || image_identifier
|
|
108
|
+
_, stderr, status = Open3.capture3('docker', 'push', push_target)
|
|
109
|
+
|
|
110
|
+
if status.success?
|
|
111
|
+
"Image #{push_target} pushed successfully"
|
|
112
|
+
else
|
|
113
|
+
error_msg = stderr.strip
|
|
114
|
+
error_msg = 'Failed to push image' if error_msg.empty?
|
|
115
|
+
"Error pushing image: #{error_msg}"
|
|
116
|
+
end
|
|
117
|
+
rescue StandardError => e
|
|
118
|
+
"Error pushing image: #{e.message}"
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
PushImage = PUSH_IMAGE_DEFINITION.to_ruby_llm_tool
|
|
123
|
+
end
|
|
124
|
+
end
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RubyLLM
|
|
4
|
+
module Docker
|
|
5
|
+
# MCP tool for recreating Docker containers.
|
|
6
|
+
#
|
|
7
|
+
# This tool provides a complete container recreation process that stops
|
|
8
|
+
# the existing container, removes it, and creates a new container with
|
|
9
|
+
# the same configuration. This is useful for applying image updates,
|
|
10
|
+
# clearing container state, or resolving container corruption issues.
|
|
11
|
+
#
|
|
12
|
+
# == Features
|
|
13
|
+
#
|
|
14
|
+
# - Complete container recreation with preserved configuration
|
|
15
|
+
# - Automatic stop, remove, and recreate sequence
|
|
16
|
+
# - Preserves original container configuration and settings
|
|
17
|
+
# - Configurable stop timeout for graceful shutdown
|
|
18
|
+
# - Handles both running and stopped containers
|
|
19
|
+
# - Maintains container networking and volume configurations
|
|
20
|
+
#
|
|
21
|
+
# == Security Considerations
|
|
22
|
+
#
|
|
23
|
+
# Container recreation involves several security considerations:
|
|
24
|
+
# - **Service Downtime**: Temporary service interruption during recreation
|
|
25
|
+
# - **Data Loss**: Container file system changes are lost (volumes preserved)
|
|
26
|
+
# - **Resource Allocation**: New container may have different resource usage
|
|
27
|
+
# - **Network Reconfiguration**: IP addresses may change
|
|
28
|
+
# - **State Reset**: Application state within container is lost
|
|
29
|
+
#
|
|
30
|
+
# Plan recreations carefully and coordinate with dependent services.
|
|
31
|
+
#
|
|
32
|
+
# == Parameters
|
|
33
|
+
#
|
|
34
|
+
# - **id**: Container ID or name to recreate (required)
|
|
35
|
+
# - **timeout**: Seconds to wait before killing container when stopping (optional, default: 10)
|
|
36
|
+
#
|
|
37
|
+
# == Process Flow
|
|
38
|
+
#
|
|
39
|
+
# 1. Inspect existing container to capture configuration
|
|
40
|
+
# 2. Stop the running container (if running)
|
|
41
|
+
# 3. Remove the stopped container
|
|
42
|
+
# 4. Create new container with captured configuration
|
|
43
|
+
# 5. Return new container information
|
|
44
|
+
#
|
|
45
|
+
# == Example Usage
|
|
46
|
+
#
|
|
47
|
+
# # Recreate with default timeout
|
|
48
|
+
# response = RecreateContainer.call(
|
|
49
|
+
# server_context: context,
|
|
50
|
+
# id: "web-server"
|
|
51
|
+
# )
|
|
52
|
+
#
|
|
53
|
+
# # Recreate with extended timeout
|
|
54
|
+
# response = RecreateContainer.call(
|
|
55
|
+
# server_context: context,
|
|
56
|
+
# id: "database",
|
|
57
|
+
# timeout: 30
|
|
58
|
+
# )
|
|
59
|
+
#
|
|
60
|
+
# @see ::Docker::Container#stop
|
|
61
|
+
# @see ::Docker::Container#remove
|
|
62
|
+
# @see ::Docker::Container.create
|
|
63
|
+
# @since 0.1.0
|
|
64
|
+
RECREATE_CONTAINER_DEFINITION = ToolForge.define(:recreate_container) do
|
|
65
|
+
description 'Recreate a Docker container (stops, removes, and recreates with same configuration)'
|
|
66
|
+
|
|
67
|
+
param :id,
|
|
68
|
+
type: :string,
|
|
69
|
+
description: 'Container ID or name to recreate'
|
|
70
|
+
|
|
71
|
+
param :timeout,
|
|
72
|
+
type: :integer,
|
|
73
|
+
description: 'Seconds to wait before killing the container when stopping (default: 10)',
|
|
74
|
+
required: false,
|
|
75
|
+
default: 10
|
|
76
|
+
|
|
77
|
+
execute do |id:, timeout: 10|
|
|
78
|
+
# Get the existing container
|
|
79
|
+
old_container = ::Docker::Container.get(id)
|
|
80
|
+
config = old_container.json
|
|
81
|
+
|
|
82
|
+
# Extract configuration we need to preserve
|
|
83
|
+
image = config['Config']['Image']
|
|
84
|
+
name = config['Name']&.delete_prefix('/')
|
|
85
|
+
cmd = config['Config']['Cmd']
|
|
86
|
+
env = config['Config']['Env']
|
|
87
|
+
exposed_ports = config['Config']['ExposedPorts']
|
|
88
|
+
host_config = config['HostConfig']
|
|
89
|
+
|
|
90
|
+
# Stop and remove the old container
|
|
91
|
+
old_container.stop('timeout' => timeout) if config['State']['Running']
|
|
92
|
+
old_container.delete
|
|
93
|
+
|
|
94
|
+
# Create new container with same config
|
|
95
|
+
new_config = {
|
|
96
|
+
'Image' => image,
|
|
97
|
+
'Cmd' => cmd,
|
|
98
|
+
'Env' => env,
|
|
99
|
+
'ExposedPorts' => exposed_ports,
|
|
100
|
+
'HostConfig' => host_config
|
|
101
|
+
}
|
|
102
|
+
new_config['name'] = name if name
|
|
103
|
+
|
|
104
|
+
new_container = ::Docker::Container.create(new_config)
|
|
105
|
+
|
|
106
|
+
# Start if the old one was running
|
|
107
|
+
new_container.start if config['State']['Running']
|
|
108
|
+
|
|
109
|
+
"Container #{id} recreated successfully. New ID: #{new_container.id}"
|
|
110
|
+
rescue ::Docker::Error::NotFoundError
|
|
111
|
+
"Container #{id} not found"
|
|
112
|
+
rescue StandardError => e
|
|
113
|
+
"Error recreating container: #{e.message}"
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
RecreateContainer = RECREATE_CONTAINER_DEFINITION.to_ruby_llm_tool
|
|
118
|
+
end
|
|
119
|
+
end
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RubyLLM
|
|
4
|
+
module Docker
|
|
5
|
+
# MCP tool for removing Docker containers.
|
|
6
|
+
#
|
|
7
|
+
# This tool permanently removes a Docker container from the system,
|
|
8
|
+
# including its file system, configuration, and metadata. This is a
|
|
9
|
+
# destructive operation that cannot be undone. The container must
|
|
10
|
+
# be stopped before removal unless force is specified.
|
|
11
|
+
#
|
|
12
|
+
# == Features
|
|
13
|
+
#
|
|
14
|
+
# - Permanent container removal from system
|
|
15
|
+
# - Supports forced removal of running containers
|
|
16
|
+
# - Optional removal of associated volumes
|
|
17
|
+
# - Handles container identification by ID or name
|
|
18
|
+
# - Provides comprehensive error handling
|
|
19
|
+
# - Frees all associated system resources
|
|
20
|
+
#
|
|
21
|
+
# == Security Considerations
|
|
22
|
+
#
|
|
23
|
+
# Container removal is a destructive operation with implications:
|
|
24
|
+
# - **Data Loss**: Permanently destroys container file system
|
|
25
|
+
# - **Configuration Loss**: Removes container settings and metadata
|
|
26
|
+
# - **Service Disruption**: Eliminates containerized services
|
|
27
|
+
# - **Resource Recovery**: Frees storage, memory, and system resources
|
|
28
|
+
# - **Audit Trail**: May remove forensic evidence if needed
|
|
29
|
+
#
|
|
30
|
+
# Implement proper backup and approval workflows for production systems.
|
|
31
|
+
#
|
|
32
|
+
# == Parameters
|
|
33
|
+
#
|
|
34
|
+
# - **id**: Container ID or name (required)
|
|
35
|
+
# - Accepts full container IDs
|
|
36
|
+
# - Accepts short container IDs (first 12+ characters)
|
|
37
|
+
# - Accepts custom container names
|
|
38
|
+
# - **force**: Force removal of running container (optional, default: false)
|
|
39
|
+
# - **volumes**: Remove associated volumes (optional, default: false)
|
|
40
|
+
#
|
|
41
|
+
# == Example Usage
|
|
42
|
+
#
|
|
43
|
+
# # Remove stopped container
|
|
44
|
+
# response = RemoveContainer.call(
|
|
45
|
+
# server_context: context,
|
|
46
|
+
# id: "old-web-server"
|
|
47
|
+
# )
|
|
48
|
+
#
|
|
49
|
+
# # Force remove running container with volumes
|
|
50
|
+
# response = RemoveContainer.call(
|
|
51
|
+
# server_context: context,
|
|
52
|
+
# id: "problematic-container",
|
|
53
|
+
# force: true,
|
|
54
|
+
# volumes: true
|
|
55
|
+
# )
|
|
56
|
+
#
|
|
57
|
+
# @see ::Docker::Container#remove
|
|
58
|
+
# @since 0.1.0
|
|
59
|
+
REMOVE_CONTAINER_DEFINITION = ToolForge.define(:remove_container) do
|
|
60
|
+
description 'Remove a Docker container'
|
|
61
|
+
|
|
62
|
+
param :id,
|
|
63
|
+
type: :string,
|
|
64
|
+
description: 'Container ID or name'
|
|
65
|
+
|
|
66
|
+
param :force,
|
|
67
|
+
type: :boolean,
|
|
68
|
+
description: 'Force removal of running container (default: false)',
|
|
69
|
+
required: false,
|
|
70
|
+
default: false
|
|
71
|
+
|
|
72
|
+
param :volumes,
|
|
73
|
+
type: :boolean,
|
|
74
|
+
description: 'Remove associated volumes (default: false)',
|
|
75
|
+
required: false,
|
|
76
|
+
default: false
|
|
77
|
+
|
|
78
|
+
execute do |id:, force: false, volumes: false|
|
|
79
|
+
container = ::Docker::Container.get(id)
|
|
80
|
+
container.delete(force: force, v: volumes)
|
|
81
|
+
|
|
82
|
+
"Container #{id} removed successfully"
|
|
83
|
+
rescue ::Docker::Error::NotFoundError
|
|
84
|
+
"Container #{id} not found"
|
|
85
|
+
rescue StandardError => e
|
|
86
|
+
"Error removing container: #{e.message}"
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
RemoveContainer = REMOVE_CONTAINER_DEFINITION.to_ruby_llm_tool
|
|
91
|
+
end
|
|
92
|
+
end
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RubyLLM
|
|
4
|
+
module Docker
|
|
5
|
+
# MCP tool for removing Docker images.
|
|
6
|
+
#
|
|
7
|
+
# This tool provides the ability to delete Docker images from the
|
|
8
|
+
# local Docker daemon. It supports various removal options including
|
|
9
|
+
# forced removal and parent image cleanup management.
|
|
10
|
+
#
|
|
11
|
+
# == Features
|
|
12
|
+
#
|
|
13
|
+
# - Remove images by ID, name, or tag
|
|
14
|
+
# - Force removal of images in use
|
|
15
|
+
# - Control untagged parent image cleanup
|
|
16
|
+
# - Comprehensive error handling
|
|
17
|
+
# - Validation of image existence
|
|
18
|
+
# - Safe removal with dependency checking
|
|
19
|
+
#
|
|
20
|
+
# == Security Considerations
|
|
21
|
+
#
|
|
22
|
+
# Image removal involves important considerations:
|
|
23
|
+
# - **Data Loss**: Removed images cannot be recovered locally
|
|
24
|
+
# - **Service Disruption**: Removing images used by running containers
|
|
25
|
+
# - **Storage Cleanup**: Improper cleanup can leave orphaned layers
|
|
26
|
+
# - **Registry Impact**: Local removal doesn't affect registry copies
|
|
27
|
+
# - **Dependency Conflicts**: Force removal can break container dependencies
|
|
28
|
+
#
|
|
29
|
+
# **Security Recommendations**:
|
|
30
|
+
# - Verify image is not in use before removal
|
|
31
|
+
# - Use force option only when necessary
|
|
32
|
+
# - Consider impact on running containers
|
|
33
|
+
# - Backup important images before removal
|
|
34
|
+
# - Monitor disk space after removal operations
|
|
35
|
+
# - Implement image lifecycle policies
|
|
36
|
+
#
|
|
37
|
+
# == Parameters
|
|
38
|
+
#
|
|
39
|
+
# - **id**: Image ID, name, or name:tag (required)
|
|
40
|
+
# - **force**: Force removal of the image (optional, default: false)
|
|
41
|
+
# - **noprune**: Do not delete untagged parents (optional, default: false)
|
|
42
|
+
#
|
|
43
|
+
# == Example Usage
|
|
44
|
+
#
|
|
45
|
+
# # Remove specific image
|
|
46
|
+
# response = RemoveImage.call(
|
|
47
|
+
# server_context: context,
|
|
48
|
+
# id: "myapp:old-version"
|
|
49
|
+
# )
|
|
50
|
+
#
|
|
51
|
+
# # Force remove image in use
|
|
52
|
+
# response = RemoveImage.call(
|
|
53
|
+
# server_context: context,
|
|
54
|
+
# id: "abc123def456",
|
|
55
|
+
# force: true
|
|
56
|
+
# )
|
|
57
|
+
#
|
|
58
|
+
# # Remove without cleaning parent images
|
|
59
|
+
# response = RemoveImage.call(
|
|
60
|
+
# server_context: context,
|
|
61
|
+
# id: "test-image:latest",
|
|
62
|
+
# noprune: true
|
|
63
|
+
# )
|
|
64
|
+
#
|
|
65
|
+
# @see ::Docker::Image#remove
|
|
66
|
+
# @since 0.1.0
|
|
67
|
+
REMOVE_IMAGE_DEFINITION = ToolForge.define(:remove_image) do
|
|
68
|
+
description 'Remove a Docker image'
|
|
69
|
+
|
|
70
|
+
param :id,
|
|
71
|
+
type: :string,
|
|
72
|
+
description: 'Image ID, name, or name:tag'
|
|
73
|
+
|
|
74
|
+
param :force,
|
|
75
|
+
type: :boolean,
|
|
76
|
+
description: 'Force removal of the image (default: false)',
|
|
77
|
+
required: false,
|
|
78
|
+
default: false
|
|
79
|
+
|
|
80
|
+
param :noprune,
|
|
81
|
+
type: :boolean,
|
|
82
|
+
description: 'Do not delete untagged parents (default: false)',
|
|
83
|
+
required: false,
|
|
84
|
+
default: false
|
|
85
|
+
|
|
86
|
+
execute do |id:, force: false, noprune: false|
|
|
87
|
+
image = ::Docker::Image.get(id)
|
|
88
|
+
image.remove(force: force, noprune: noprune)
|
|
89
|
+
|
|
90
|
+
"Image #{id} removed successfully"
|
|
91
|
+
rescue ::Docker::Error::NotFoundError
|
|
92
|
+
"Image #{id} not found"
|
|
93
|
+
rescue StandardError => e
|
|
94
|
+
"Error removing image: #{e.message}"
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
RemoveImage = REMOVE_IMAGE_DEFINITION.to_ruby_llm_tool
|
|
99
|
+
end
|
|
100
|
+
end
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RubyLLM
|
|
4
|
+
module Docker
|
|
5
|
+
# MCP tool for removing Docker networks.
|
|
6
|
+
#
|
|
7
|
+
# This tool provides the ability to delete Docker networks when they
|
|
8
|
+
# are no longer needed. Network removal helps maintain clean network
|
|
9
|
+
# configurations and prevents resource leaks.
|
|
10
|
+
#
|
|
11
|
+
# == Features
|
|
12
|
+
#
|
|
13
|
+
# - Remove networks by ID or name
|
|
14
|
+
# - Validation of network existence
|
|
15
|
+
# - Comprehensive error handling
|
|
16
|
+
# - Prevention of removing networks in use
|
|
17
|
+
# - Safe cleanup of network resources
|
|
18
|
+
# - Network dependency checking
|
|
19
|
+
#
|
|
20
|
+
# == Security Considerations
|
|
21
|
+
#
|
|
22
|
+
# Network removal involves important considerations:
|
|
23
|
+
# - **Service Disruption**: Removing active networks disconnects containers
|
|
24
|
+
# - **Data Isolation**: Network removal can affect container communication
|
|
25
|
+
# - **Resource Cleanup**: Improper removal can leave network artifacts
|
|
26
|
+
# - **Container Dependencies**: Containers may fail without expected networks
|
|
27
|
+
# - **Network Policies**: Removal affects security and access policies
|
|
28
|
+
#
|
|
29
|
+
# **Security Recommendations**:
|
|
30
|
+
# - Verify no containers are connected before removal
|
|
31
|
+
# - Check for dependent services and applications
|
|
32
|
+
# - Document network removal in change logs
|
|
33
|
+
# - Implement network lifecycle management
|
|
34
|
+
# - Monitor for orphaned network resources
|
|
35
|
+
# - Use network removal as part of cleanup procedures
|
|
36
|
+
#
|
|
37
|
+
# == Parameters
|
|
38
|
+
#
|
|
39
|
+
# - **id**: Network ID or name (required)
|
|
40
|
+
#
|
|
41
|
+
# == Example Usage
|
|
42
|
+
#
|
|
43
|
+
# # Remove network by name
|
|
44
|
+
# response = RemoveNetwork.call(
|
|
45
|
+
# server_context: context,
|
|
46
|
+
# id: "app-network"
|
|
47
|
+
# )
|
|
48
|
+
#
|
|
49
|
+
# # Remove network by ID
|
|
50
|
+
# response = RemoveNetwork.call(
|
|
51
|
+
# server_context: context,
|
|
52
|
+
# id: "abc123def456"
|
|
53
|
+
# )
|
|
54
|
+
#
|
|
55
|
+
# # Clean up test networks
|
|
56
|
+
# response = RemoveNetwork.call(
|
|
57
|
+
# server_context: context,
|
|
58
|
+
# id: "test-isolated-network"
|
|
59
|
+
# )
|
|
60
|
+
#
|
|
61
|
+
# @see ::Docker::Network#delete
|
|
62
|
+
# @since 0.1.0
|
|
63
|
+
REMOVE_NETWORK_DEFINITION = ToolForge.define(:remove_network) do
|
|
64
|
+
description 'Remove a Docker network'
|
|
65
|
+
|
|
66
|
+
param :id,
|
|
67
|
+
type: :string,
|
|
68
|
+
description: 'Network ID or name'
|
|
69
|
+
|
|
70
|
+
execute do |id:|
|
|
71
|
+
network = ::Docker::Network.get(id)
|
|
72
|
+
network.delete
|
|
73
|
+
|
|
74
|
+
"Network #{id} removed successfully"
|
|
75
|
+
rescue ::Docker::Error::NotFoundError
|
|
76
|
+
"Network #{id} not found"
|
|
77
|
+
rescue StandardError => e
|
|
78
|
+
"Error removing network: #{e.message}"
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
RemoveNetwork = REMOVE_NETWORK_DEFINITION.to_ruby_llm_tool
|
|
83
|
+
end
|
|
84
|
+
end
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RubyLLM
|
|
4
|
+
module Docker
|
|
5
|
+
# MCP tool for removing Docker volumes.
|
|
6
|
+
#
|
|
7
|
+
# This tool provides the ability to delete Docker volumes when they
|
|
8
|
+
# are no longer needed. Volume removal is critical for preventing
|
|
9
|
+
# storage leaks and maintaining clean Docker environments.
|
|
10
|
+
#
|
|
11
|
+
# == Features
|
|
12
|
+
#
|
|
13
|
+
# - Remove volumes by name
|
|
14
|
+
# - Force removal of volumes in use
|
|
15
|
+
# - Validation of volume existence
|
|
16
|
+
# - Comprehensive error handling
|
|
17
|
+
# - Safe volume cleanup procedures
|
|
18
|
+
# - Prevention of accidental data loss
|
|
19
|
+
#
|
|
20
|
+
# == Security Considerations
|
|
21
|
+
#
|
|
22
|
+
# Volume removal involves critical data considerations:
|
|
23
|
+
# - **Data Loss**: Removed volumes and their data are permanently deleted
|
|
24
|
+
# - **Service Disruption**: Removing volumes can break running containers
|
|
25
|
+
# - **Data Recovery**: Volume data cannot be recovered after removal
|
|
26
|
+
# - **Container Dependencies**: Applications may fail without expected volumes
|
|
27
|
+
# - **Storage Cleanup**: Improper removal can leave orphaned data
|
|
28
|
+
# - **Backup Requirements**: Critical data should be backed up before removal
|
|
29
|
+
#
|
|
30
|
+
# **Security Recommendations**:
|
|
31
|
+
# - Always backup critical data before volume removal
|
|
32
|
+
# - Verify no containers are using the volume
|
|
33
|
+
# - Use force option only when absolutely necessary
|
|
34
|
+
# - Document volume removal in change management
|
|
35
|
+
# - Implement volume lifecycle and retention policies
|
|
36
|
+
# - Monitor storage usage after volume removal
|
|
37
|
+
# - Consider data migration instead of removal
|
|
38
|
+
#
|
|
39
|
+
# == Parameters
|
|
40
|
+
#
|
|
41
|
+
# - **name**: Volume name (required)
|
|
42
|
+
# - **force**: Force removal of the volume (optional, default: false)
|
|
43
|
+
#
|
|
44
|
+
# == Example Usage
|
|
45
|
+
#
|
|
46
|
+
# # Remove unused volume
|
|
47
|
+
# response = RemoveVolume.call(
|
|
48
|
+
# server_context: context,
|
|
49
|
+
# name: "old-app-data"
|
|
50
|
+
# )
|
|
51
|
+
#
|
|
52
|
+
# # Force remove volume in use
|
|
53
|
+
# response = RemoveVolume.call(
|
|
54
|
+
# server_context: context,
|
|
55
|
+
# name: "stuck-volume",
|
|
56
|
+
# force: true
|
|
57
|
+
# )
|
|
58
|
+
#
|
|
59
|
+
# # Clean up test volumes
|
|
60
|
+
# response = RemoveVolume.call(
|
|
61
|
+
# server_context: context,
|
|
62
|
+
# name: "test-data-volume"
|
|
63
|
+
# )
|
|
64
|
+
#
|
|
65
|
+
# @see ::Docker::Volume#remove
|
|
66
|
+
# @since 0.1.0
|
|
67
|
+
REMOVE_VOLUME_DEFINITION = ToolForge.define(:remove_volume) do
|
|
68
|
+
description 'Remove a Docker volume'
|
|
69
|
+
|
|
70
|
+
param :name,
|
|
71
|
+
type: :string,
|
|
72
|
+
description: 'Volume name'
|
|
73
|
+
|
|
74
|
+
param :force,
|
|
75
|
+
type: :boolean,
|
|
76
|
+
description: 'Force removal of the volume (default: false)',
|
|
77
|
+
required: false,
|
|
78
|
+
default: false
|
|
79
|
+
|
|
80
|
+
execute do |name:, force: false|
|
|
81
|
+
volume = ::Docker::Volume.get(name)
|
|
82
|
+
volume.remove(force: force)
|
|
83
|
+
|
|
84
|
+
"Volume #{name} removed successfully"
|
|
85
|
+
rescue ::Docker::Error::NotFoundError
|
|
86
|
+
"Volume #{name} not found"
|
|
87
|
+
rescue StandardError => e
|
|
88
|
+
"Error removing volume: #{e.message}"
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
RemoveVolume = REMOVE_VOLUME_DEFINITION.to_ruby_llm_tool
|
|
93
|
+
end
|
|
94
|
+
end
|