kitchen-dokken 2.23.1 → 2.23.3
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/lib/kitchen/driver/dokken.rb +105 -26
- data/lib/kitchen/driver/dokken_version.rb +1 -1
- data/lib/kitchen/helpers.rb +1 -3
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 9bbe79ca0ad5a4b71659c1359871a9e4c86f6e243d83d694ab76341f94a0e6c0
|
|
4
|
+
data.tar.gz: 2e6dd411ce0d408331cf312249d208c6b6345382cc94d2d83cba0cf7b407d0be
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: a14d2a57ab4bdb76e6192107fd2f0c185df2f1fab90522c1fa45546420c8a508e0adfb9b893a56c2c9ef6e84c4b7fd5cf1428f578b614f788659b523e6219753
|
|
7
|
+
data.tar.gz: df6506e366a8379682f5bbbfc3e3b1574d841a3da048d7ab35d61b944f4b28996277cf30907fa1b1de3b21aa36c52fd01521844344c51c0ec976cd93b396ed1e
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
# limitations under the License.
|
|
17
17
|
|
|
18
18
|
require "digest" unless defined?(Digest)
|
|
19
|
+
require "json" unless defined?(JSON)
|
|
19
20
|
require "kitchen"
|
|
20
21
|
require "tmpdir" unless defined?(Dir.mktmpdir)
|
|
21
22
|
require "docker"
|
|
@@ -80,7 +81,7 @@ module Kitchen
|
|
|
80
81
|
default_config :write_timeout, 3600
|
|
81
82
|
default_config :user_ns_mode, nil
|
|
82
83
|
default_config :creds_file, nil
|
|
83
|
-
default_config :docker_config_creds,
|
|
84
|
+
default_config :docker_config_creds, true
|
|
84
85
|
|
|
85
86
|
# (see Base#create)
|
|
86
87
|
def create(state)
|
|
@@ -370,7 +371,7 @@ module Kitchen
|
|
|
370
371
|
config["HostConfig"]["UsernsMode"] = "host"
|
|
371
372
|
end
|
|
372
373
|
|
|
373
|
-
runner_container = run_container(config)
|
|
374
|
+
runner_container = run_container(config, platform: self[:platform])
|
|
374
375
|
state[:runner_container] = runner_container.json
|
|
375
376
|
end
|
|
376
377
|
|
|
@@ -397,6 +398,12 @@ module Kitchen
|
|
|
397
398
|
},
|
|
398
399
|
}
|
|
399
400
|
end
|
|
401
|
+
# Deliberately not pinned to config[:platform]: this container only
|
|
402
|
+
# serves kitchen's files over ssh, so its architecture is irrelevant to
|
|
403
|
+
# the system under test. The data image is built locally from
|
|
404
|
+
# almalinux:9 (see Helpers#create_data_image) and is therefore always
|
|
405
|
+
# host-architecture -- pinning it fails outright whenever the platform
|
|
406
|
+
# under test differs from the host.
|
|
400
407
|
data_container = run_container(config)
|
|
401
408
|
state[:data_container] = data_container.json
|
|
402
409
|
end
|
|
@@ -443,7 +450,9 @@ module Kitchen
|
|
|
443
450
|
"NetworkMode" => self[:network_mode],
|
|
444
451
|
},
|
|
445
452
|
}
|
|
446
|
-
|
|
453
|
+
# /opt/chef from this container is mounted into the runner, so it
|
|
454
|
+
# has to be built for the same architecture as the runner.
|
|
455
|
+
chef_container = create_container(config, platform: self[:platform])
|
|
447
456
|
state[:chef_container] = chef_container.json
|
|
448
457
|
rescue ::Docker::Error, StandardError => e
|
|
449
458
|
raise "driver - #{chef_container_name} failed to create #{e}"
|
|
@@ -504,20 +513,68 @@ module Kitchen
|
|
|
504
513
|
@docker_config_creds
|
|
505
514
|
end
|
|
506
515
|
|
|
516
|
+
# The `auths` key `docker login` itself writes for Docker Hub.
|
|
517
|
+
DOCKER_HUB_REGISTRY_KEY = "https://index.docker.io/v1/".freeze
|
|
518
|
+
|
|
519
|
+
# Registry hosts that all refer to Docker Hub. Docker writes the legacy
|
|
520
|
+
# v1 URL above, but hand-written and tool-generated configs use any of
|
|
521
|
+
# these. Listed in preference order.
|
|
522
|
+
DOCKER_HUB_HOSTS = %w{index.docker.io docker.io registry-1.docker.io}.freeze
|
|
523
|
+
|
|
524
|
+
# An explicit "no credentials" value. Returning nil here instead would let
|
|
525
|
+
# docker-api fall back to the process-global ::Docker.creds, which
|
|
526
|
+
# authenticate! populates from creds_file and never clears -- so another
|
|
527
|
+
# instance's private registry password would be sent to this registry,
|
|
528
|
+
# which is the very leak this scoping exists to prevent.
|
|
529
|
+
NO_DOCKER_CREDS = {}.freeze
|
|
530
|
+
|
|
531
|
+
# Return the registry host an image reference points at, or nil when the
|
|
532
|
+
# reference resolves to Docker Hub. The leading path component only names
|
|
533
|
+
# a registry when it contains a "." or a ":", or is exactly "localhost" --
|
|
534
|
+
# the same heuristic Docker uses to tell "quay.io/org/image" apart from
|
|
535
|
+
# the Hub shorthand "dokken/almalinux-8".
|
|
536
|
+
def image_registry_host(image)
|
|
537
|
+
first, remainder = image.split("/", 2)
|
|
538
|
+
return nil if remainder.nil?
|
|
539
|
+
return nil unless first.include?(".") || first.include?(":") || first == "localhost"
|
|
540
|
+
|
|
541
|
+
first
|
|
542
|
+
end
|
|
543
|
+
|
|
544
|
+
# Look up the ~/.docker/config.json entry that applies to an image's
|
|
545
|
+
# registry. Returns nil when that registry has no entry so the pull is
|
|
546
|
+
# attempted anonymously, rather than offering it another registry's
|
|
547
|
+
# credentials.
|
|
548
|
+
# Pick the config.json key that holds the Docker Hub credentials. A
|
|
549
|
+
# config may spell Hub several ways, so prefer the canonical key and then
|
|
550
|
+
# a fixed alias order rather than whichever happens to be listed first.
|
|
551
|
+
def docker_hub_creds_key
|
|
552
|
+
keys = docker_config_creds.keys.select { |k| DOCKER_HUB_HOSTS.include?(parse_registry_host(k)) }
|
|
553
|
+
return if keys.empty?
|
|
554
|
+
|
|
555
|
+
keys.find { |k| k == DOCKER_HUB_REGISTRY_KEY } ||
|
|
556
|
+
keys.min_by { |k| DOCKER_HUB_HOSTS.index(parse_registry_host(k)) }
|
|
557
|
+
end
|
|
558
|
+
|
|
559
|
+
def docker_config_creds_for_image(image)
|
|
560
|
+
host = image_registry_host(image)
|
|
561
|
+
|
|
562
|
+
key = if host.nil? || DOCKER_HUB_HOSTS.include?(host)
|
|
563
|
+
docker_hub_creds_key
|
|
564
|
+
else
|
|
565
|
+
docker_config_creds.keys.find { |k| parse_registry_host(k) == host }
|
|
566
|
+
end
|
|
567
|
+
return if key.nil?
|
|
568
|
+
|
|
569
|
+
c = docker_config_creds[key]
|
|
570
|
+
c.respond_to?(:call) ? c.call : c
|
|
571
|
+
end
|
|
572
|
+
|
|
507
573
|
def docker_creds_for_image(image)
|
|
508
574
|
return docker_creds if config[:creds_file]
|
|
575
|
+
return NO_DOCKER_CREDS unless config[:docker_config_creds]
|
|
509
576
|
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
# NOTE: Try to use DockerHub auth if exact registry match isn't found
|
|
513
|
-
default_registry = "https://index.docker.io/v1/"
|
|
514
|
-
if docker_config_creds.key?(image_registry)
|
|
515
|
-
c = docker_config_creds[image_registry]
|
|
516
|
-
c.respond_to?(:call) ? c.call : c
|
|
517
|
-
elsif docker_config_creds.key?(default_registry)
|
|
518
|
-
c = docker_config_creds[default_registry]
|
|
519
|
-
c.respond_to?(:call) ? c.call : c
|
|
520
|
-
end
|
|
577
|
+
docker_config_creds_for_image(image) || NO_DOCKER_CREDS
|
|
521
578
|
end
|
|
522
579
|
|
|
523
580
|
def pull_platform_image
|
|
@@ -596,18 +653,17 @@ module Kitchen
|
|
|
596
653
|
end
|
|
597
654
|
end
|
|
598
655
|
|
|
599
|
-
def create_container(args)
|
|
656
|
+
def create_container(args, platform: nil)
|
|
600
657
|
with_retries { @container = ::Docker::Container.get(args["name"], {}, docker_connection) }
|
|
601
658
|
rescue
|
|
602
659
|
with_retries do
|
|
603
660
|
args["Env"] = [] if args["Env"].nil?
|
|
604
661
|
args["Env"] << "TEST_KITCHEN=1"
|
|
605
662
|
args["Env"] << "CI=#{ENV["CI"]}" if ENV.include? "CI"
|
|
606
|
-
args["Platform"] = config[:platform]
|
|
607
663
|
info "Creating container #{args["name"]}"
|
|
608
664
|
debug "driver - create_container args #{args}"
|
|
609
665
|
with_retries do
|
|
610
|
-
@container =
|
|
666
|
+
@container = create_container_for_platform(args.clone, platform)
|
|
611
667
|
rescue ::Docker::Error::ConflictError
|
|
612
668
|
debug "driver - rescue ConflictError: #{args["name"]}"
|
|
613
669
|
with_retries { @container = ::Docker::Container.get(args["name"], {}, docker_connection) }
|
|
@@ -618,8 +674,25 @@ module Kitchen
|
|
|
618
674
|
end
|
|
619
675
|
end
|
|
620
676
|
|
|
621
|
-
|
|
622
|
-
|
|
677
|
+
# Create a container, optionally pinned to an OCI platform.
|
|
678
|
+
#
|
|
679
|
+
# /containers/create takes `platform` as a *query* parameter, but
|
|
680
|
+
# Docker::Container.create only ever forwards `name` to the query string
|
|
681
|
+
# and dumps everything else into the request body. A "Platform" body key
|
|
682
|
+
# is therefore accepted and silently ignored by the daemon, which is why
|
|
683
|
+
# the platform config had no effect on container creation. Post directly
|
|
684
|
+
# when a platform is wanted; otherwise use the gem as before.
|
|
685
|
+
def create_container_for_platform(args, platform)
|
|
686
|
+
return ::Docker::Container.create(args, docker_connection) if platform.to_s.empty?
|
|
687
|
+
|
|
688
|
+
query = { "name" => args["name"], "platform" => platform }
|
|
689
|
+
body = args.reject { |k, _| k == "name" }
|
|
690
|
+
docker_connection.post("/containers/create", query, body: JSON.dump(body))
|
|
691
|
+
::Docker::Container.get(args["name"], {}, docker_connection)
|
|
692
|
+
end
|
|
693
|
+
|
|
694
|
+
def run_container(args, platform: nil)
|
|
695
|
+
create_container(args, platform: platform)
|
|
623
696
|
with_retries do
|
|
624
697
|
@container.start
|
|
625
698
|
@container = ::Docker::Container.get(args["name"], {}, docker_connection)
|
|
@@ -664,7 +737,7 @@ module Kitchen
|
|
|
664
737
|
|
|
665
738
|
def chef_container_name
|
|
666
739
|
prefix = instance.provisioner[:product_name] == "cinc" ? "cinc" : "chef"
|
|
667
|
-
config[:platform] != "" ? "#{prefix}-#{chef_version}-" + config[:platform].
|
|
740
|
+
config[:platform] != "" ? "#{prefix}-#{chef_version}-" + config[:platform].tr("/", "-") : "#{prefix}-#{chef_version}"
|
|
668
741
|
end
|
|
669
742
|
|
|
670
743
|
def chef_image
|
|
@@ -733,18 +806,24 @@ module Kitchen
|
|
|
733
806
|
original_image = Docker::Image.get(path, { "platform" => oci_platform(config[:platform]) }, docker_connection)
|
|
734
807
|
end
|
|
735
808
|
|
|
736
|
-
new_image = Docker::Image.create({ "fromImage" => path, "platform" => config[:platform] }, docker_creds_for_image(
|
|
809
|
+
new_image = Docker::Image.create({ "fromImage" => path, "platform" => config[:platform] }, docker_creds_for_image(path), docker_connection)
|
|
737
810
|
|
|
738
811
|
!(original_image&.id&.start_with?(new_image.id))
|
|
739
812
|
end
|
|
740
813
|
end
|
|
741
814
|
|
|
815
|
+
# Convert an "os/arch[/variant]" platform string into the JSON OCI
|
|
816
|
+
# platform spec the Docker API expects as an image filter. The variant
|
|
817
|
+
# matters: the daemon will not match a filter of
|
|
818
|
+
# {"os":"linux","architecture":"amd64"} against a linux/amd64/v2 image,
|
|
819
|
+
# so dropping it makes every image lookup for a variant image miss.
|
|
742
820
|
def oci_platform(platform)
|
|
743
|
-
if
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
821
|
+
return platform if platform.nil? || !platform.include?("/")
|
|
822
|
+
|
|
823
|
+
os, architecture, variant = platform.split("/")
|
|
824
|
+
spec = { os: os, architecture: architecture }
|
|
825
|
+
spec[:variant] = variant unless variant.nil? || variant.empty?
|
|
826
|
+
spec.to_json
|
|
748
827
|
end
|
|
749
828
|
|
|
750
829
|
def runner_container_name
|
data/lib/kitchen/helpers.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: kitchen-dokken
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.23.
|
|
4
|
+
version: 2.23.3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Sean OMeara
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-
|
|
11
|
+
date: 2026-07-28 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: docker-api
|