feat: initial commit with changesupdated code that was 5 years old so it works again
@@ -1,6 +1,6 @@
The MIT License (MIT)
-Copyright (c) 2020 EthicDevs & Place Technology Limited
+Copyright (c) 2020 Place Technology Limited
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
@@ -15,8 +15,7 @@ Client structure has been designed to mirror API provided by the [official pytho
```yaml
dependencies:
docker:
- git: https://gitfoss.dev/ethicdevs/crystal-docker-api.git
- branch: master
+ github: aca-labs/crystal-docker
```
2. Run `shards install`
@@ -35,6 +34,5 @@ Read [the docs](https://aca-labs.github.io/crystal-docker/).
## Contributors
-- [Willi Wonka](https://gitfoss.dev/willi.wonka38) - maintainer
-- [Kim Burgess](https://github.com/kimburgess) - creator
+- [Kim Burgess](https://github.com/kimburgess) - creator and maintainer
- [Jerome Gravel-Niquet](https://github.com/jeromegn) - `HTTP::Client` and `OpenSSL` extensions from the original [docker.cr lib](https://github.com/jeromegn/docker.cr)
@@ -1,9 +1,8 @@
name: docker
-version: 0.4.4
+version: 0.2.0
crystal: ">= 0.36.1"
license: MIT
authors:
- - Willi Wonka <willi.wonka38@proton.me>
- Kim Burgess <kim@acaprojects.com>
- Caspian Baska <email@caspian.computer>
@@ -9,7 +9,6 @@ require "../errors"
require "./containers"
require "./daemon"
require "./images"
-require "./volumes"
# Low-level wrapper for the Docker Engine API.
#
@@ -33,7 +32,7 @@ class Docker::Api::ApiClient
case uri.scheme
when "unix"
- # puts "unix socket connection to: #{@socket_path}\n"
+ puts "unix socket connection to: #{@socket_path}\n"
@socket_path = @socket_path.gsub(/unix:\/\//, "")
@socket = UNIXSocket.new(@socket_path)
else
@@ -43,11 +42,7 @@ class Docker::Api::ApiClient
{% for method in %w(get post put head delete patch options) %}
# Builds and executes a GET/POST/... request on a unix socket.
- def unix_{{method.id}}(
- path : String,
- headers : HTTP::Headers? = nil,
- body : HTTP::Client::BodyType? = nil
- )
+ def unix_{{method.id}}(path : String, headers : HTTP::Headers? = nil, body : String? = nil)
headers ||= HTTP::Headers.new
headers = headers.dup
@@ -100,28 +95,12 @@ class Docker::Api::ApiClient
response
end
- # cleanup response body send over docker socket
raw = res_str
- .gsub("10f1\r\n", "") # ?
- .gsub("10f", "") # ?
.gsub("11\r\n", "") # ?
.gsub("11c4\r\n", "") # ?
.gsub("0\r\n", "") # ?
- .gsub("1321\r\n", "") # ?
- .gsub("1322\r\n", "") # ?
- .gsub("13\r\n", "") # ?
- .gsub("14\r\n", "") # ?
- .gsub("1d\r\n", "") # ?
- .gsub("4f\r\n", "") # ?
- .gsub("3a\r\n", "") # ?
- .gsub("3e\r\n", "") # ?
- .gsub("5e\r\n", "") # ?
-
- # pp path
- # pp raw
- # puts "\n"
-
- # Parse status line, headers and body
+
+ # # Parse status line, headers and body
head, body = raw.split("\r\n\r\n", 2)
body = body.chomp("\r\n").chomp("\r\n")
status_line, *header_lines = head.split("\r\n")
@@ -211,5 +190,4 @@ class Docker::Api::ApiClient
include Containers
include Daemon
include Images
- include Volumes
end
@@ -44,7 +44,9 @@ module Docker::Api::Containers
#
# Similar to the `docker start` command, but doesn’t support attach options.
def start(id : String)
+ puts "start container id: #{id}\n"
response = post "/containers/#{id}/start"
+ p! response
nil
end
@@ -116,63 +118,6 @@ module Docker::Api::Containers
nil
end
- # Exec commands inside a container.
- def exec(id : String, command : Array(String))
- # create the exec request
- props = {
- "AttachStdout": true,
- "AttachStderr": true,
- "Cmd": command,
- "Env": {
- "FOO": "foo",
- }, # make it configurable
- }
-
- exec_res = post "/containers/#{id}/exec", body: props.to_jsonbody
- exec_id = JSON.parse(exec_res.body).as_h["Id"]
-
- props = {
- "Detach": false,
- "Tty": false,
- }
-
- start_exec_res = post "/containers/#{id}/exec/start", body: props.to_json
- nil
- end
-
- # Get logs from a container
- def logs(
- id : String,
- stdout : Bool? = true,
- stderr : Bool? = true,
- follow : Bool? = true,
- )
- response = get "/containers/#{id}/logs?stdout=#{stdout ? 1 : 0}&stderr=#{stderr ? 1 : 0}&follow=#{follow ? 1 : 0}"
- response.body
- end
-
- # Retrieve an archive from a container
- def get_archive(id : String, path : String) : Bytes
- params = HTTP::Params.build do |param|
- param.add "path", path
- end
- response = get "/containers/#{id}/archive?#{params}"
- response.body.to_slice
- end
-
- # Send an archive to a container
- def put_archive(id : String, path : String, archive : Bytes)
- headers = HTTP::Headers.new
- headers["Content-Type"] = "application/x-tar"
- headers["Content-Length"] = archive.size.to_s
- params = HTTP::Params.build do |param|
- param.add "path", path
- end
- body = archive.to_slice
- response = put "/containers/#{id}/archive?#{params}", headers, body
- response.body
- end
-
# Block until a container stops, then returns the exit code.
#
# Similar to `docker wait` command.
@@ -66,15 +66,4 @@ module Docker::Api::Images
response = get "/images/#{id}/json"
Models::Image.from_json response.body
end
-
- # Pull an image from a registry.
- #
- # Identical to the `docker pull` command.
- def pull_image(name : String, tag : String? = nil)
- params = HTTP::Params.build do |param|
- param.add "fromImage", name
- param.add "tag", tag.to_s unless tag.nil?
- end
- response = post "/images/create?#{params}"
- end
end
@@ -135,7 +135,7 @@ module Docker::Api::Models
# @[JSON::Field(key: "KernelMemory")]
# getter kernel_memory : Int32
@[JSON::Field(key: "OomKillDisable")]
- getter oom_kill_disable : Bool?
+ getter oom_kill_disable : Bool
@[JSON::Field(key: "OomScoreAdj")]
getter joom_score_adj : Int32
@[JSON::Field(key: "NetworkMode")]
@@ -5,7 +5,7 @@ module Docker::Api::Models
@[JSON::Field(key: "Id")]
getter id : String
@[JSON::Field(key: "Container")]
- getter container : String?
+ getter container : String
@[JSON::Field(key: "Comment")]
getter comment : String
@[JSON::Field(key: "Os")]
@@ -1,20 +0,0 @@
-require "./response"
-
-module Docker::Api::Models
- struct Volume < Response
- @[JSON::Field(key: "CreatedAt")]
- getter created_at : String
- @[JSON::Field(key: "Driver")]
- getter driver : String
- @[JSON::Field(key: "Labels")]
- getter labels : Hash(String, String)?
- @[JSON::Field(key: "Mountpoint")]
- getter mountpoint : String
- @[JSON::Field(key: "Name")]
- getter name : String
- @[JSON::Field(key: "Options")]
- getter options : Hash(String, String)? # Docker::Api::Volume::Options
- @[JSON::Field(key: "Scope")]
- getter scope : String
- end
-end
@@ -1,20 +0,0 @@
-require "../../tools"
-require "./models/volume"
-
-# API queries for image interaction.
-module Docker::Api::Volumes
- def list(filters : Hash(String, Array(String)))
- response = @client.get("/volumes", query: filters)
-
- Docker::Api::Models::Volume
- .from_json_array(response.body)
- end
-
- def create(name : String)
- body = { "Name" => name }.to_json
- response = @client.post("/volumes/create", body: body)
-
- Docker::Api::Models::Volume
- .from_json(response.body)
- end
-end
@@ -1,20 +0,0 @@
-require "./api_client_wrapper"
-require "./api/models/container"
-
-# Interact with a single container that exists on a docker client.
-class Docker::Archive
- include Docker::ApiClientWrapper
-
- def initialize(@client : Docker::Api::ApiClient, @id : String)
- end
-
- # Method to get an archive from container
- def get(path : String)
- @client.get_archive @id, path
- end
-
- # Method to send an archive to container
- def put(path : String, archive : Bytes)
- @client.put_archive @id, path, archive
- end
-end
@@ -1,7 +1,6 @@
require "./api_client_wrapper"
require "./containers"
require "./images"
-require "./volumes"
# A client for communicating with a Docker server.
#
@@ -16,18 +15,10 @@ class Docker::Client
@client = Docker::Api::ApiClient.new base_url, @api_version
end
- # Provides access to container management.
- def containers
- Containers.new @client
- end
-
- # Provides access to image management.
- def images
- Images.new @client
- end
-
- # Provides access to volume management.
- def volumes
- Volumes.new @client
- end
+ {% for component in %w(containers images) %}
+ # Provide an object for managing {{component.id}}. See `Docker::{{component.id.capitalize}}`.
+ def {{component.id}} : {{component.id.capitalize}}
+ @{{component.id}} ||= {{component.id.capitalize}}.new client
+ end
+ {% end %}
end
@@ -1,8 +1,6 @@
require "./api_client_wrapper"
require "./api/models/container"
-require "./archive"
-
# Interact with a single container that exists on a docker client.
class Docker::Container
include Docker::ApiClientWrapper
@@ -51,16 +49,6 @@ class Docker::Container
attrs.state.status
end
- def archive
- Docker::Archive.new(client, id)
- end
-
- # Run command inside the container.
- def exec(command : Array(String))
- client.exec id, command
- self
- end
-
# Start this container.
def start
client.start id
@@ -126,11 +114,6 @@ class Docker::Container
self
end
- # Get logs from the container.
- def logs
- client.logs id
- end
-
# Block until the container stops, then return its exit code.
def wait(condition = nil)
response = client.wait id, condition
@@ -58,13 +58,4 @@ class Docker::Images
image_ids = client.images(all, name, filters).map &.id
image_ids.map &->get(String)
end
-
- # Pull an image from a registry.
- def pull(image : String, tag : String? = nil)
- parts = image.split(":")
- name = parts.first
- tag = parts.last if tag.nil?
-
- client.pull_image(name, tag)
- end
end
@@ -1,21 +0,0 @@
-require "./api_client_wrapper"
-require "./api/models/volume"
-
-# Interact with a single container that exists on a docker client.
-class Docker::Volumes
- include Docker::ApiClientWrapper
-
- def initialize(@client : Docker::Api::ApiClient)
- end
-
- # Method to get an archive from container
- def list(filters : Hash(String, Array(String)))
- # filters: { "name" => [vid] }
- @client.list_volume filters
- end
-
- # Method to send an archive to container
- def create(name : String)
- @client.create_volume name
- end
-end