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.
- checksums.yaml +4 -4
- data/examples/docker_chat.rb +41 -0
- data/lib/ruby_llm/docker/build_image.rb +64 -65
- data/lib/ruby_llm/docker/copy_to_container.rb +89 -134
- data/lib/ruby_llm/docker/create_container.rb +64 -86
- data/lib/ruby_llm/docker/create_network.rb +63 -79
- data/lib/ruby_llm/docker/create_volume.rb +57 -79
- data/lib/ruby_llm/docker/exec_container.rb +94 -111
- data/lib/ruby_llm/docker/fetch_container_logs.rb +63 -85
- data/lib/ruby_llm/docker/list_containers.rb +46 -40
- data/lib/ruby_llm/docker/list_images.rb +34 -55
- data/lib/ruby_llm/docker/list_networks.rb +35 -57
- data/lib/ruby_llm/docker/list_volumes.rb +35 -64
- data/lib/ruby_llm/docker/pull_image.rb +24 -48
- data/lib/ruby_llm/docker/push_image.rb +60 -89
- data/lib/ruby_llm/docker/recreate_container.rb +47 -79
- data/lib/ruby_llm/docker/remove_container.rb +48 -76
- data/lib/ruby_llm/docker/remove_image.rb +53 -95
- data/lib/ruby_llm/docker/remove_network.rb +42 -78
- data/lib/ruby_llm/docker/remove_volume.rb +52 -85
- data/lib/ruby_llm/docker/run_container.rb +73 -53
- data/lib/ruby_llm/docker/start_container.rb +35 -58
- data/lib/ruby_llm/docker/stop_container.rb +40 -66
- data/lib/ruby_llm/docker/tag_image.rb +67 -95
- data/lib/ruby_llm/docker/version.rb +10 -1
- data/lib/ruby_llm/docker.rb +13 -0
- metadata +15 -1
|
@@ -2,80 +2,58 @@
|
|
|
2
2
|
|
|
3
3
|
module RubyLLM
|
|
4
4
|
module Docker
|
|
5
|
-
#
|
|
5
|
+
# MCP tool for listing Docker networks.
|
|
6
6
|
#
|
|
7
|
-
# This tool provides
|
|
8
|
-
# the system
|
|
9
|
-
#
|
|
10
|
-
# configuration, drivers, and connected containers.
|
|
7
|
+
# This tool provides comprehensive information about all Docker networks
|
|
8
|
+
# configured on the system. It returns detailed network configuration
|
|
9
|
+
# including IPAM settings, connected containers, and network drivers.
|
|
11
10
|
#
|
|
12
11
|
# == Features
|
|
13
12
|
#
|
|
14
|
-
# -
|
|
15
|
-
# -
|
|
16
|
-
# -
|
|
17
|
-
# -
|
|
18
|
-
# - Includes
|
|
13
|
+
# - Lists all Docker networks (built-in and custom)
|
|
14
|
+
# - Provides detailed network configuration
|
|
15
|
+
# - Shows IPAM (IP Address Management) settings
|
|
16
|
+
# - Displays connected containers
|
|
17
|
+
# - Includes driver information and options
|
|
18
|
+
# - Reports network scope and capabilities
|
|
19
19
|
#
|
|
20
|
-
# ==
|
|
20
|
+
# == Security Considerations
|
|
21
21
|
#
|
|
22
|
-
#
|
|
23
|
-
# - **Network
|
|
24
|
-
# - **
|
|
25
|
-
# - **
|
|
26
|
-
# - **
|
|
27
|
-
# - **IPAM**: IP Address Management configuration
|
|
28
|
-
# - **Connected Containers**: Containers attached to the network
|
|
29
|
-
# - **Options**: Driver-specific configuration options
|
|
22
|
+
# Network information can be sensitive as it reveals:
|
|
23
|
+
# - **Network Topology**: Internal network architecture
|
|
24
|
+
# - **IP Addressing**: Subnet configurations and ranges
|
|
25
|
+
# - **Container Connectivity**: Service interconnections
|
|
26
|
+
# - **Network Isolation**: Security boundary configurations
|
|
30
27
|
#
|
|
31
|
-
#
|
|
28
|
+
# Restrict access to this tool in production environments.
|
|
32
29
|
#
|
|
33
|
-
#
|
|
34
|
-
# - Exposes network architecture and segmentation
|
|
35
|
-
# - Shows container connectivity patterns
|
|
36
|
-
# - May reveal internal network design
|
|
37
|
-
# - Could aid in network reconnaissance
|
|
30
|
+
# == Return Format
|
|
38
31
|
#
|
|
39
|
-
#
|
|
40
|
-
# -
|
|
41
|
-
# -
|
|
42
|
-
# -
|
|
43
|
-
# -
|
|
32
|
+
# Returns an array of network objects with comprehensive metadata:
|
|
33
|
+
# - Network names and IDs
|
|
34
|
+
# - Driver types and configurations
|
|
35
|
+
# - IPAM settings and subnet information
|
|
36
|
+
# - Connected container details
|
|
37
|
+
# - Network options and labels
|
|
38
|
+
# - Scope and capability flags
|
|
44
39
|
#
|
|
45
40
|
# == Example Usage
|
|
46
41
|
#
|
|
47
|
-
#
|
|
48
|
-
#
|
|
42
|
+
# networks = ListNetworks.call(server_context: context)
|
|
43
|
+
# networks.each do |network|
|
|
44
|
+
# puts "#{network['Name']}: #{network['Driver']}"
|
|
45
|
+
# end
|
|
49
46
|
#
|
|
50
|
-
# @
|
|
51
|
-
# # Get available networks before container creation
|
|
52
|
-
# networks_response = ListNetworks.call(server_context: context)
|
|
53
|
-
# # Use network information to select appropriate networks
|
|
54
|
-
#
|
|
55
|
-
# @see CreateNetwork
|
|
56
|
-
# @see RemoveNetwork
|
|
57
|
-
# @see Docker::Network.all
|
|
47
|
+
# @see ::Docker::Network.all
|
|
58
48
|
# @since 0.1.0
|
|
59
|
-
|
|
49
|
+
LIST_NETWORKS_DEFINITION = ToolForge.define(:list_networks) do
|
|
60
50
|
description 'List Docker networks'
|
|
61
51
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
# This method retrieves information about all Docker networks, including
|
|
65
|
-
# both system-created networks (bridge, host, none) and user-defined
|
|
66
|
-
# custom networks. The information includes comprehensive metadata for
|
|
67
|
-
# each network.
|
|
68
|
-
#
|
|
69
|
-
# @return [String] comprehensive network information
|
|
70
|
-
#
|
|
71
|
-
# @example List all networks
|
|
72
|
-
# response = tool.execute
|
|
73
|
-
# # Returns detailed info for all Docker networks
|
|
74
|
-
#
|
|
75
|
-
# @see Docker::Network.all
|
|
76
|
-
def execute
|
|
77
|
-
::Docker::Network.all.map(&:info).to_s
|
|
52
|
+
execute do
|
|
53
|
+
::Docker::Network.all.map(&:info)
|
|
78
54
|
end
|
|
79
55
|
end
|
|
56
|
+
|
|
57
|
+
ListNetworks = LIST_NETWORKS_DEFINITION.to_ruby_llm_tool
|
|
80
58
|
end
|
|
81
59
|
end
|
|
@@ -2,87 +2,58 @@
|
|
|
2
2
|
|
|
3
3
|
module RubyLLM
|
|
4
4
|
module Docker
|
|
5
|
-
#
|
|
5
|
+
# MCP tool for listing Docker volumes.
|
|
6
6
|
#
|
|
7
|
-
# This tool provides
|
|
8
|
-
#
|
|
9
|
-
#
|
|
7
|
+
# This tool provides comprehensive information about all Docker volumes
|
|
8
|
+
# configured on the system. It returns detailed volume metadata including
|
|
9
|
+
# mount points, drivers, usage statistics, and associated containers.
|
|
10
10
|
#
|
|
11
11
|
# == Features
|
|
12
12
|
#
|
|
13
|
-
# -
|
|
14
|
-
# -
|
|
15
|
-
# -
|
|
16
|
-
# -
|
|
17
|
-
# - Includes
|
|
13
|
+
# - Lists all Docker volumes (named and anonymous)
|
|
14
|
+
# - Provides detailed volume metadata
|
|
15
|
+
# - Shows mount points and storage locations
|
|
16
|
+
# - Displays driver information and options
|
|
17
|
+
# - Includes creation timestamps and labels
|
|
18
|
+
# - Reports volume scope and capabilities
|
|
18
19
|
#
|
|
19
|
-
# ==
|
|
20
|
-
#
|
|
21
|
-
# The response typically includes:
|
|
22
|
-
# - **Volume Name**: Unique identifier for the volume
|
|
23
|
-
# - **Driver**: Volume driver (local, nfs, etc.)
|
|
24
|
-
# - **Mountpoint**: Physical location on host filesystem
|
|
25
|
-
# - **Labels**: User-defined metadata labels
|
|
26
|
-
# - **Options**: Driver-specific configuration options
|
|
27
|
-
# - **Scope**: Volume scope (local, global)
|
|
28
|
-
# - **CreatedAt**: Volume creation timestamp
|
|
29
|
-
#
|
|
30
|
-
# == Volume Types
|
|
20
|
+
# == Security Considerations
|
|
31
21
|
#
|
|
32
|
-
#
|
|
33
|
-
# - **
|
|
34
|
-
# - **
|
|
35
|
-
# - **
|
|
36
|
-
# - **
|
|
22
|
+
# Volume information can reveal sensitive details about:
|
|
23
|
+
# - **Data Storage**: Persistent data locations and structures
|
|
24
|
+
# - **File System Access**: Mount points and storage paths
|
|
25
|
+
# - **Container Dependencies**: Volume usage patterns
|
|
26
|
+
# - **Data Persistence**: Backup and recovery points
|
|
37
27
|
#
|
|
38
|
-
#
|
|
28
|
+
# Monitor access to this tool and implement appropriate controls.
|
|
39
29
|
#
|
|
40
|
-
#
|
|
41
|
-
# - Exposes data storage architecture
|
|
42
|
-
# - Shows volume naming patterns
|
|
43
|
-
# - May reveal application data locations
|
|
44
|
-
# - Could aid in data discovery attacks
|
|
30
|
+
# == Return Format
|
|
45
31
|
#
|
|
46
|
-
#
|
|
47
|
-
# -
|
|
48
|
-
# -
|
|
49
|
-
# -
|
|
50
|
-
# -
|
|
32
|
+
# Returns an array of volume objects with comprehensive metadata:
|
|
33
|
+
# - Volume names and mount points
|
|
34
|
+
# - Driver types and configurations
|
|
35
|
+
# - Creation timestamps
|
|
36
|
+
# - Labels and options
|
|
37
|
+
# - Scope information
|
|
38
|
+
# - Storage usage details
|
|
51
39
|
#
|
|
52
40
|
# == Example Usage
|
|
53
41
|
#
|
|
54
|
-
#
|
|
55
|
-
#
|
|
56
|
-
#
|
|
57
|
-
#
|
|
58
|
-
# # Get available volumes before container creation
|
|
59
|
-
# volumes_response = ListVolumes.call(server_context: context)
|
|
60
|
-
# # Use volume information to select appropriate storage
|
|
42
|
+
# volumes = ListVolumes.call(server_context: context)
|
|
43
|
+
# volumes.each do |volume|
|
|
44
|
+
# puts "#{volume['Name']}: #{volume['Mountpoint']}"
|
|
45
|
+
# end
|
|
61
46
|
#
|
|
62
|
-
# @see
|
|
63
|
-
# @see RemoveVolume
|
|
64
|
-
# @see Docker::Volume.all
|
|
47
|
+
# @see ::Docker::Volume.all
|
|
65
48
|
# @since 0.1.0
|
|
66
|
-
|
|
49
|
+
LIST_VOLUMES_DEFINITION = ToolForge.define(:list_volumes) do
|
|
67
50
|
description 'List Docker volumes'
|
|
68
51
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
# This method retrieves information about all Docker volumes, including
|
|
72
|
-
# both named volumes created by users and anonymous volumes created
|
|
73
|
-
# automatically by containers. The information includes comprehensive
|
|
74
|
-
# metadata for each volume.
|
|
75
|
-
#
|
|
76
|
-
# @return [String] comprehensive volume information
|
|
77
|
-
#
|
|
78
|
-
# @example List all volumes
|
|
79
|
-
# response = tool.execute
|
|
80
|
-
# # Returns detailed info for all Docker volumes
|
|
81
|
-
#
|
|
82
|
-
# @see Docker::Volume.all
|
|
83
|
-
def execute
|
|
84
|
-
::Docker::Volume.all.map(&:info).to_s
|
|
52
|
+
execute do
|
|
53
|
+
::Docker::Volume.all.map(&:info)
|
|
85
54
|
end
|
|
86
55
|
end
|
|
56
|
+
|
|
57
|
+
ListVolumes = LIST_VOLUMES_DEFINITION.to_ruby_llm_tool
|
|
87
58
|
end
|
|
88
59
|
end
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
module RubyLLM
|
|
4
4
|
module Docker
|
|
5
|
-
#
|
|
5
|
+
# MCP tool for pulling Docker images from registries.
|
|
6
6
|
#
|
|
7
7
|
# This tool provides the ability to download Docker images from Docker
|
|
8
8
|
# registries (like Docker Hub) to the local system. It supports flexible
|
|
@@ -26,7 +26,7 @@ module RubyLLM
|
|
|
26
26
|
# - **Supply Chain Attacks**: Legitimate-looking images may be malicious
|
|
27
27
|
# - **Resource Consumption**: Large images can consume significant disk space
|
|
28
28
|
#
|
|
29
|
-
# Security
|
|
29
|
+
# **Security Recommendations**:
|
|
30
30
|
# - Only pull images from trusted registries and publishers
|
|
31
31
|
# - Verify image signatures when available
|
|
32
32
|
# - Scan pulled images for vulnerabilities
|
|
@@ -42,67 +42,41 @@ module RubyLLM
|
|
|
42
42
|
# - If no tag specified, default to "latest"
|
|
43
43
|
# - Supports all Docker tag conventions
|
|
44
44
|
#
|
|
45
|
+
# == Parameters
|
|
46
|
+
#
|
|
47
|
+
# - **from_image**: Image name to pull (required, e.g., "ubuntu" or "ubuntu:22.04")
|
|
48
|
+
# - **tag**: Tag to pull (optional, defaults to "latest" if not specified in from_image)
|
|
49
|
+
#
|
|
45
50
|
# == Example Usage
|
|
46
51
|
#
|
|
47
52
|
# # Pull latest version
|
|
48
|
-
# PullImage.call(
|
|
53
|
+
# response = PullImage.call(
|
|
49
54
|
# server_context: context,
|
|
50
55
|
# from_image: "nginx"
|
|
51
56
|
# )
|
|
52
57
|
#
|
|
53
58
|
# # Pull specific version
|
|
54
|
-
# PullImage.call(
|
|
59
|
+
# response = PullImage.call(
|
|
55
60
|
# server_context: context,
|
|
56
|
-
# from_image: "postgres
|
|
61
|
+
# from_image: "postgres",
|
|
62
|
+
# tag: "13.8"
|
|
57
63
|
# )
|
|
58
64
|
#
|
|
59
|
-
#
|
|
60
|
-
# PullImage.call(
|
|
61
|
-
# server_context: context,
|
|
62
|
-
# from_image: "redis",
|
|
63
|
-
# tag: "7-alpine"
|
|
64
|
-
# )
|
|
65
|
-
#
|
|
66
|
-
# @see BuildImage
|
|
67
|
-
# @see ListImages
|
|
68
|
-
# @see Docker::Image.create
|
|
65
|
+
# @see ::Docker::Image.create
|
|
69
66
|
# @since 0.1.0
|
|
70
|
-
|
|
67
|
+
PULL_IMAGE_DEFINITION = ToolForge.define(:pull_image) do
|
|
71
68
|
description 'Pull a Docker image'
|
|
72
69
|
|
|
73
|
-
param :from_image,
|
|
74
|
-
|
|
70
|
+
param :from_image,
|
|
71
|
+
type: :string,
|
|
72
|
+
description: 'Image name to pull (e.g., "ubuntu" or "ubuntu:22.04")'
|
|
73
|
+
|
|
74
|
+
param :tag,
|
|
75
|
+
type: :string,
|
|
76
|
+
description: 'Tag to pull (optional, defaults to "latest" if not specified in from_image)',
|
|
77
|
+
required: false
|
|
75
78
|
|
|
76
|
-
|
|
77
|
-
#
|
|
78
|
-
# This method downloads the specified image from a Docker registry to
|
|
79
|
-
# the local system. It handles tag resolution automatically and provides
|
|
80
|
-
# feedback on the pull operation status.
|
|
81
|
-
#
|
|
82
|
-
# @param from_image [String] image name (may include registry and tag)
|
|
83
|
-
# @param server_context [Object] RubyLLM context (unused but required)
|
|
84
|
-
# @param tag [String, nil] specific tag to pull (overrides tag in from_image)
|
|
85
|
-
#
|
|
86
|
-
# @return [RubyLLM::Tool::Response] pull operation results with image ID
|
|
87
|
-
#
|
|
88
|
-
# @raise [Docker::Error::NotFoundError] if image doesn't exist in registry
|
|
89
|
-
# @raise [StandardError] for network or authentication failures
|
|
90
|
-
#
|
|
91
|
-
# @example Pull official image
|
|
92
|
-
# response = PullImage.call(
|
|
93
|
-
# server_context: context,
|
|
94
|
-
# from_image: "ubuntu:22.04"
|
|
95
|
-
# )
|
|
96
|
-
#
|
|
97
|
-
# @example Pull from custom registry
|
|
98
|
-
# response = PullImage.call(
|
|
99
|
-
# server_context: context,
|
|
100
|
-
# from_image: "registry.example.com/myapp",
|
|
101
|
-
# tag: "v1.0"
|
|
102
|
-
# )
|
|
103
|
-
#
|
|
104
|
-
# @see Docker::Image.create
|
|
105
|
-
def execute(from_image:, tag: nil)
|
|
79
|
+
execute do |from_image:, tag: nil|
|
|
106
80
|
# If tag is provided separately, append it to from_image
|
|
107
81
|
# If from_image already has a tag (contains :), use as-is
|
|
108
82
|
# Otherwise default to :latest
|
|
@@ -123,5 +97,7 @@ module RubyLLM
|
|
|
123
97
|
"Error pulling image: #{e.message}"
|
|
124
98
|
end
|
|
125
99
|
end
|
|
100
|
+
|
|
101
|
+
PullImage = PULL_IMAGE_DEFINITION.to_ruby_llm_tool
|
|
126
102
|
end
|
|
127
103
|
end
|
|
@@ -1,153 +1,124 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require 'json'
|
|
4
|
-
require 'open3'
|
|
5
|
-
|
|
6
3
|
module RubyLLM
|
|
7
4
|
module Docker
|
|
8
|
-
#
|
|
5
|
+
# MCP tool for pushing Docker images to registries.
|
|
9
6
|
#
|
|
10
|
-
# This tool provides the ability to upload Docker images to Docker
|
|
11
|
-
# such as Docker Hub, private registries, or cloud-based
|
|
12
|
-
#
|
|
13
|
-
#
|
|
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.
|
|
14
11
|
#
|
|
15
12
|
# == Features
|
|
16
13
|
#
|
|
17
|
-
# - Push images to any
|
|
18
|
-
# -
|
|
19
|
-
# -
|
|
20
|
-
# -
|
|
21
|
-
# -
|
|
22
|
-
# -
|
|
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
|
|
23
21
|
#
|
|
24
|
-
# ==
|
|
22
|
+
# == Security Considerations
|
|
25
23
|
#
|
|
26
24
|
# Pushing images involves significant security risks:
|
|
27
25
|
# - **Credential Exposure**: Registry credentials may be exposed
|
|
28
|
-
# - **
|
|
29
|
-
# - **
|
|
30
|
-
# - **
|
|
31
|
-
# - **
|
|
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
|
|
32
31
|
#
|
|
33
|
-
#
|
|
34
|
-
# -
|
|
35
|
-
# - Scan images for
|
|
36
|
-
# - Use private registries for sensitive applications
|
|
32
|
+
# **Security Recommendations**:
|
|
33
|
+
# - Use secure registry authentication
|
|
34
|
+
# - Scan images for vulnerabilities before pushing
|
|
37
35
|
# - Implement image signing and verification
|
|
38
|
-
# -
|
|
39
|
-
# -
|
|
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
40
|
#
|
|
41
|
-
# ==
|
|
41
|
+
# == Parameters
|
|
42
42
|
#
|
|
43
|
-
#
|
|
44
|
-
# -
|
|
45
|
-
# -
|
|
46
|
-
# - Examples: `username/myapp`, `registry.company.com/team/app`
|
|
47
|
-
# - Local image names (without `/`) cannot be pushed
|
|
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")
|
|
48
46
|
#
|
|
49
47
|
# == Example Usage
|
|
50
48
|
#
|
|
51
49
|
# # Push to Docker Hub
|
|
52
|
-
# PushImage.call(
|
|
50
|
+
# response = PushImage.call(
|
|
53
51
|
# server_context: context,
|
|
54
|
-
# name: "
|
|
55
|
-
# tag: "v1.0"
|
|
52
|
+
# name: "username/myapp",
|
|
53
|
+
# tag: "v1.0.0"
|
|
56
54
|
# )
|
|
57
55
|
#
|
|
58
56
|
# # Push to private registry
|
|
59
|
-
# PushImage.call(
|
|
57
|
+
# response = PushImage.call(
|
|
60
58
|
# server_context: context,
|
|
61
|
-
# name: "
|
|
62
|
-
#
|
|
59
|
+
# name: "myapp",
|
|
60
|
+
# repo_tag: "registry.company.com/team/myapp:latest"
|
|
63
61
|
# )
|
|
64
62
|
#
|
|
65
|
-
# # Push
|
|
66
|
-
# PushImage.call(
|
|
63
|
+
# # Push all tags
|
|
64
|
+
# response = PushImage.call(
|
|
67
65
|
# server_context: context,
|
|
68
|
-
# name: "myapp"
|
|
69
|
-
# repo_tag: "myregistry.com/myuser/myapp:v2.0"
|
|
66
|
+
# name: "username/myapp"
|
|
70
67
|
# )
|
|
71
68
|
#
|
|
72
|
-
# @see
|
|
73
|
-
# @see TagImage
|
|
74
|
-
# @see BuildImage
|
|
69
|
+
# @see Docker CLI push command
|
|
75
70
|
# @since 0.1.0
|
|
76
|
-
|
|
71
|
+
PUSH_IMAGE_DEFINITION = ToolForge.define(:push_image) do
|
|
77
72
|
description 'Push a Docker image'
|
|
78
73
|
|
|
79
|
-
param :name,
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
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
|
|
84
82
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
# @param name [String] image name or ID to push
|
|
92
|
-
# @param server_context [Object] RubyLLM context (unused but required)
|
|
93
|
-
# @param tag [String, nil] specific tag to push
|
|
94
|
-
# @param repo_tag [String, nil] complete repository:tag specification
|
|
95
|
-
#
|
|
96
|
-
# @return [RubyLLM::Tool::Response] push operation results
|
|
97
|
-
#
|
|
98
|
-
# @raise [StandardError] for push failures or authentication issues
|
|
99
|
-
#
|
|
100
|
-
# @example Push tagged image to Docker Hub
|
|
101
|
-
# response = PushImage.call(
|
|
102
|
-
# server_context: context,
|
|
103
|
-
# name: "myuser/webapp",
|
|
104
|
-
# tag: "v1.2.3"
|
|
105
|
-
# )
|
|
106
|
-
#
|
|
107
|
-
# @example Push to private registry
|
|
108
|
-
# response = tool.execute(
|
|
109
|
-
# name: "internal-registry.com/team/service",
|
|
110
|
-
# tag: "latest"
|
|
111
|
-
# )
|
|
112
|
-
#
|
|
113
|
-
# @see Docker::Image.get
|
|
114
|
-
def execute(name:, tag: nil, repo_tag: nil)
|
|
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|
|
|
115
89
|
# Construct the full image identifier
|
|
116
90
|
image_identifier = tag ? "#{name}:#{tag}" : name
|
|
117
91
|
|
|
118
92
|
# Validate that the image name includes a registry/username
|
|
119
|
-
# Images without a registry prefix will fail to push to Docker Hub
|
|
120
93
|
unless name.include?('/') || repo_tag&.include?('/')
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
return error_msg
|
|
94
|
+
next 'Error: Image name must include registry/username ' \
|
|
95
|
+
"(e.g., 'username/#{name}'). Local images cannot be " \
|
|
96
|
+
'pushed without a registry prefix.'
|
|
125
97
|
end
|
|
126
98
|
|
|
127
99
|
# Verify the image exists
|
|
128
100
|
begin
|
|
129
101
|
::Docker::Image.get(image_identifier)
|
|
130
102
|
rescue ::Docker::Error::NotFoundError
|
|
131
|
-
|
|
103
|
+
next "Image #{image_identifier} not found"
|
|
132
104
|
end
|
|
133
105
|
|
|
134
106
|
# Use the Docker CLI to push the image
|
|
135
|
-
# This way we leverage Docker's native credential handling
|
|
136
107
|
push_target = repo_tag || image_identifier
|
|
137
108
|
_, stderr, status = Open3.capture3('docker', 'push', push_target)
|
|
138
109
|
|
|
139
110
|
if status.success?
|
|
140
111
|
"Image #{push_target} pushed successfully"
|
|
141
112
|
else
|
|
142
|
-
# Extract the error message from stderr
|
|
143
113
|
error_msg = stderr.strip
|
|
144
114
|
error_msg = 'Failed to push image' if error_msg.empty?
|
|
145
|
-
|
|
146
115
|
"Error pushing image: #{error_msg}"
|
|
147
116
|
end
|
|
148
117
|
rescue StandardError => e
|
|
149
118
|
"Error pushing image: #{e.message}"
|
|
150
119
|
end
|
|
151
120
|
end
|
|
121
|
+
|
|
122
|
+
PushImage = PUSH_IMAGE_DEFINITION.to_ruby_llm_tool
|
|
152
123
|
end
|
|
153
124
|
end
|