Skip to content

Commit fc393f9

Browse files
authored
Merge pull request #100 from thin-edge/fix-container-version-field
fix(container): use full image in version field
2 parents 7a4f748 + e7bd093 commit fc393f9

File tree

12 files changed

+67
-36
lines changed

12 files changed

+67
-36
lines changed

.github/workflows/test.yaml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,6 @@ jobs:
5858
echo 'C8Y_USER="${{ secrets.C8Y_USER }}"' >> .env
5959
echo 'C8Y_PASSWORD="${{ secrets.C8Y_PASSWORD }}"' >> .env
6060
echo 'PRIVATE_IMAGE="${{ secrets.PRIVATE_IMAGE }}"' >> .env
61-
echo 'PRIVATE_IMAGE_VERSION="${{ secrets.PRIVATE_IMAGE_VERSION }}"' >> .env
6261
echo 'REGISTRY1_REPO="${{ secrets.REGISTRY1_REPO }}"' >> .env
6362
echo 'REGISTRY1_USERNAME="${{ secrets.REGISTRY1_USERNAME }}"' >> .env
6463
echo 'REGISTRY1_PASSWORD="${{ secrets.REGISTRY1_PASSWORD }}"' >> .env

cli/container/list.go

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import (
77
"context"
88
"fmt"
99
"log/slog"
10-
"strings"
1110

1211
"github.com/spf13/cobra"
1312
"github.com/thin-edge/tedge-container-plugin/pkg/cli"
@@ -34,8 +33,7 @@ func NewListCommand(cliContext cli.Cli) *cobra.Command {
3433
stdout := cmd.OutOrStdout()
3534
for _, item := range containers {
3635
if item.ServiceType == container.ContainerType {
37-
version := item.Container.Image[strings.LastIndex(item.Container.Image, "/")+1:]
38-
fmt.Fprintf(stdout, "%s\t%s\n", item.Name, version)
36+
fmt.Fprintf(stdout, "%s\t%s\n", item.Name, container.NormalizeImageRef(item.Container.Image))
3937
}
4038
}
4139
return nil

cli/self/list.go

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -41,16 +41,9 @@ func NewListCommand(cliContext cli.Cli) *cobra.Command {
4141
}
4242

4343
name := strings.TrimPrefix(currentContainer.Name, "/")
44-
version := formatImageName(currentContainer.Config.Image)
44+
version := currentContainer.Config.Image
4545
_, wErr := fmt.Fprintf(cmd.OutOrStdout(), "%s\t%s\n", name, version)
4646
return wErr
4747
},
4848
}
4949
}
50-
51-
func formatImageName(v string) string {
52-
if i := strings.LastIndex(v, "/"); i > -1 && i < len(v)-1 {
53-
return v[i+1:]
54-
}
55-
return v
56-
}

justfile

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,7 @@ init-dotenv:
1111
@echo "C8Y_BASEURL=$C8Y_BASEURL" >> .env
1212
@echo "C8Y_USER=$C8Y_USER" >> .env
1313
@echo "C8Y_PASSWORD=$C8Y_PASSWORD" >> .env
14-
@echo "PRIVATE_IMAGE=docker.io/example/app" >> .env
15-
@echo "PRIVATE_IMAGE_VERSION=app:latest" >> .env
14+
@echo "PRIVATE_IMAGE=docker.io/example/app:latest" >> .env
1615
@echo "REGISTRY1_REPO=docker.io" >> .env
1716
@echo "REGISTRY1_USERNAME=" >> .env
1817
@echo "REGISTRY1_PASSWORD=" >> .env

pkg/container/container.go

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -501,7 +501,13 @@ type ImagePullOptions struct {
501501
// Check if the given docker.io image has fully qualified (e.g. docker.io/library/<image>)
502502
// if not, then expand it to its fully qualified name.
503503
func ResolveDockerIOImage(imageRef string) (string, bool) {
504-
if strings.HasPrefix(imageRef, "docker.io/library/") {
504+
if !strings.HasPrefix(imageRef, "docker.io/") {
505+
return imageRef, false
506+
}
507+
508+
slashCount := strings.Count(imageRef, "/")
509+
510+
if strings.HasPrefix(imageRef, "docker.io/library/") || slashCount >= 2 {
505511
// Is already normalized
506512
return imageRef, false
507513
}
@@ -513,6 +519,11 @@ func ResolveDockerIOImage(imageRef string) (string, bool) {
513519
return "docker.io/library/" + strings.TrimPrefix(imageRef, "docker.io/"), true
514520
}
515521

522+
func NormalizeImageRef(imageRef string) string {
523+
fullRef, _ := ResolveDockerIOImage(imageRef)
524+
return fullRef
525+
}
526+
516527
// Pull a container image. The image will be verified if it exists afterwards
517528
//
518529
// Use credentials function to generate initial credentials

pkg/container/container_test.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package container
2+
3+
import "testing"
4+
5+
func Test_ResolveDockerIOImage(t *testing.T) {
6+
testcases := []struct {
7+
Image string
8+
Expect string
9+
}{
10+
{
11+
Image: "docker.io/library/app",
12+
Expect: "docker.io/library/app",
13+
},
14+
{
15+
Image: "docker.io/other/app2",
16+
Expect: "docker.io/other/app2",
17+
},
18+
{
19+
Image: "foo.io/other/app2",
20+
Expect: "foo.io/other/app2",
21+
},
22+
}
23+
24+
for _, testcase := range testcases {
25+
got, _ := ResolveDockerIOImage(testcase.Image)
26+
27+
if got != testcase.Expect {
28+
t.Errorf("Resolved image does not match expected. got=%s, wanted=%s", got, testcase.Expect)
29+
}
30+
}
31+
32+
}

tests/data/apps/app1/Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
FROM docker.io/nginx
1+
FROM docker.io/library/nginx
22
COPY static /usr/share/nginx/html

tests/data/apps/app2/Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
FROM docker.io/nginx
1+
FROM docker.io/library/nginx
22
COPY static /usr/share/nginx/html

tests/data/apps/app3/Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
FROM docker.io/alpine:3.18
1+
FROM docker.io/library/alpine:3.18
22
ENTRYPOINT [ "/bin/sleep", "infinity" ]

tests/operations-clone.robot

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ Test Tags docker podman
1111
*** Test Cases ***
1212

1313
Check for Update
14-
Create Container app1 httpd:2.4.61-alpine
14+
Create Container app1 docker.io/library/httpd:2.4.61-alpine
1515
DeviceLibrary.Execute Command cmd=tedge-container engine docker container inspect app1 --format "{{.Id}}"
1616

1717
# No update
@@ -24,7 +24,7 @@ Check for Update
2424
DeviceLibrary.Execute Command sudo tedge-container tools container-clone --container app1 --image httpd:2.4.62-alpine --check exp_exit_code=0
2525

2626
Clone Existing Container
27-
Create Container app2 httpd:2.4
27+
Create Container app2 docker.io/library/httpd:2.4
2828
${prev_container_id}= DeviceLibrary.Execute Command cmd=sudo tedge-container engine docker container inspect app2 --format "{{.Id}}"
2929

3030
DeviceLibrary.Execute Command sudo tedge-container tools container-clone --container app2 --force
@@ -33,7 +33,7 @@ Clone Existing Container
3333
Should Not Be Equal ${next_container_id} ${prev_container_id}
3434

3535
Clone Existing Container by Timeout Whilst Waiting For Exit
36-
Create Container app3 httpd:2.4
36+
Create Container app3 docker.io/library/httpd:2.4
3737
${prev_container_id}= DeviceLibrary.Execute Command cmd=sudo tedge-container engine docker container inspect app3 --format "{{.Id}}"
3838

3939
DeviceLibrary.Execute Command sudo tedge-container tools container-clone --container app3 --force --wait-for-exit --stop-timeout 15s exp_exit_code=!0
@@ -42,7 +42,7 @@ Clone Existing Container by Timeout Whilst Waiting For Exit
4242
Should Be Equal ${next_container_id} ${prev_container_id}
4343

4444
Clone Existing Container but Waiting For Exit
45-
Create Container app4 httpd:2.4
45+
Create Container app4 docker.io/library/httpd:2.4
4646
${prev_container_id}= DeviceLibrary.Execute Command cmd=sudo tedge-container engine docker container inspect app4 --format "{{.Id}}"
4747

4848
${operation}= Cumulocity.Execute Shell Command sudo tedge-container tools container-clone --container app4 --force --wait-for-exit --stop-timeout 60s 2>&1

tests/operations-private-registries.robot

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ Test Teardown Collect Logs
99
*** Variables ***
1010

1111
${PRIVATE_IMAGE} %{PRIVATE_IMAGE=}
12-
${PRIVATE_IMAGE_VERSION} %{PRIVATE_IMAGE_VERSION=}
1312
${REGISTRY1_REPO} %{REGISTRY1_REPO=docker.io}
1413
${REGISTRY1_USERNAME} %{REGISTRY1_USERNAME=}
1514
${REGISTRY1_PASSWORD} %{REGISTRY1_PASSWORD=}
@@ -23,7 +22,7 @@ Install/uninstall container package from private repository - credentials file
2322

2423
${operation}= Cumulocity.Install Software {"name": "testapp1", "version": "${PRIVATE_IMAGE}", "softwareType": "container"}
2524
Operation Should Be SUCCESSFUL ${operation} timeout=60
26-
Device Should Have Installed Software {"name": "testapp1", "version": "${PRIVATE_IMAGE_VERSION}", "softwareType": "container"}
25+
Device Should Have Installed Software {"name": "testapp1", "version": "${PRIVATE_IMAGE}", "softwareType": "container"}
2726

2827
Install/uninstall container package from private repository - credentials script
2928
[Tags] docker podman
@@ -33,7 +32,7 @@ Install/uninstall container package from private repository - credentials script
3332

3433
${operation}= Cumulocity.Install Software {"name": "testapp2", "version": "${PRIVATE_IMAGE}", "softwareType": "container"}
3534
Operation Should Be SUCCESSFUL ${operation} timeout=60
36-
Device Should Have Installed Software {"name": "testapp2", "version": "${PRIVATE_IMAGE_VERSION}", "softwareType": "container"}
35+
Device Should Have Installed Software {"name": "testapp2", "version": "${PRIVATE_IMAGE}", "softwareType": "container"}
3736

3837
Install/uninstall container package from private repository - credentials script with cache
3938
[Tags] docker podman
@@ -43,15 +42,15 @@ Install/uninstall container package from private repository - credentials script
4342

4443
${operation}= Cumulocity.Install Software {"name": "testapp2", "version": "${PRIVATE_IMAGE}", "softwareType": "container"}
4544
Operation Should Be SUCCESSFUL ${operation} timeout=60
46-
Device Should Have Installed Software {"name": "testapp2", "version": "${PRIVATE_IMAGE_VERSION}", "softwareType": "container"}
45+
Device Should Have Installed Software {"name": "testapp2", "version": "${PRIVATE_IMAGE}", "softwareType": "container"}
4746

4847
Install/uninstall container package from private repository - engine credentials
4948
[Documentation] login to registry from host
5049
[Tags] podman
5150
DeviceLibrary.Execute Command tedge-container engine docker login ${REGISTRY1_REPO} -u '${REGISTRY1_USERNAME}' --password '${REGISTRY1_PASSWORD}'
5251
${operation}= Cumulocity.Install Software {"name": "testapp3", "version": "${PRIVATE_IMAGE}", "softwareType": "container"}
5352
Operation Should Be SUCCESSFUL ${operation} timeout=60
54-
Device Should Have Installed Software {"name": "testapp3", "version": "${PRIVATE_IMAGE_VERSION}", "softwareType": "container"}
53+
Device Should Have Installed Software {"name": "testapp3", "version": "${PRIVATE_IMAGE}", "softwareType": "container"}
5554

5655
Install/uninstall container package from private repository - docker from docker
5756
[Documentation] login inside a container with the auth file mounted from the host

tests/operations.robot

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -47,16 +47,16 @@ Install container-group with multiple files - app2
4747
Install container-group file app2 1.2.3 app2 ${CURDIR}/data/apps/app2.zip
4848

4949
Install/uninstall container package
50-
${operation}= Cumulocity.Install Software {"name": "webserver", "version": "httpd:2.4", "softwareType": "container"}
50+
${operation}= Cumulocity.Install Software {"name": "webserver", "version": "docker.io/library/httpd:2.4", "softwareType": "container"}
5151
Operation Should Be SUCCESSFUL ${operation} timeout=60
52-
Device Should Have Installed Software {"name": "webserver", "version": "httpd:2.4", "softwareType": "container"}
53-
${operation}= Cumulocity.Execute Shell Command sudo tedge-container engine docker run --rm -t --network tedge docker.io/busybox wget -O- webserver:80;
52+
Device Should Have Installed Software {"name": "webserver", "version": "docker.io/library/httpd:2.4", "softwareType": "container"}
53+
${operation}= Cumulocity.Execute Shell Command sudo tedge-container engine docker run --rm -t --network tedge docker.io/library/busybox wget -O- webserver:80;
5454
Operation Should Be SUCCESSFUL ${operation}
5555
Should Contain ${operation.to_json()["c8y_Command"]["result"]} It works!
5656
Cumulocity.Should Have Services name=webserver service_type=container status=up
5757

5858
# Uninstall
59-
${operation}= Cumulocity.Uninstall Software {"name": "webserver", "version": "httpd:2.4", "softwareType": "container"}
59+
${operation}= Cumulocity.Uninstall Software {"name": "webserver", "version": "docker.io/library/httpd:2.4", "softwareType": "container"}
6060
Operation Should Be SUCCESSFUL ${operation}
6161
Device Should Not Have Installed Software webserver
6262
Cumulocity.Should Have Services name=webserver service_type=container min_count=0 max_count=0
@@ -65,13 +65,13 @@ Install/uninstall container package
6565
Install/uninstall container package from file
6666
${binary_url}= Cumulocity.Create Inventory Binary app3 container file=${CURDIR}/data/apps/app3.tar
6767

68-
${operation}= Cumulocity.Install Software {"name": "app3", "version": "app3", "softwareType": "container", "url": "${binary_url}"}
68+
${operation}= Cumulocity.Install Software {"name": "app3", "version": "docker.io/library/app3:latest", "softwareType": "container", "url": "${binary_url}"}
6969
Operation Should Be SUCCESSFUL ${operation}
70-
Device Should Have Installed Software {"name": "app3", "version": "app3:latest", "softwareType": "container"}
70+
Device Should Have Installed Software {"name": "app3", "version": "docker.io/library/app3:latest", "softwareType": "container"}
7171
Cumulocity.Should Have Services name=app3 service_type=container status=up
7272

7373
# Uninstall
74-
${operation}= Cumulocity.Uninstall Software {"name": "app3", "version": "app3:latest", "softwareType": "container"}
74+
${operation}= Cumulocity.Uninstall Software {"name": "app3", "version": "docker.io/library/app3:latest", "softwareType": "container"}
7575
Operation Should Be SUCCESSFUL ${operation}
7676
Device Should Not Have Installed Software app3
7777
Cumulocity.Should Have Services name=app3 service_type=container min_count=0 max_count=0
@@ -81,7 +81,7 @@ Manual container creation/deletion
8181
${operation}= Cumulocity.Execute Shell Command sudo tedge-container engine docker network create tedge ||:; sudo tedge-container engine docker run -d --network tedge --name manualapp1 httpd:2.4
8282
Operation Should Be SUCCESSFUL ${operation} timeout=60
8383

84-
${operation}= Cumulocity.Execute Shell Command sudo tedge-container engine docker run --rm -t --network tedge docker.io/busybox wget -O- manualapp1:80;
84+
${operation}= Cumulocity.Execute Shell Command sudo tedge-container engine docker run --rm -t --network tedge docker.io/library/busybox wget -O- manualapp1:80;
8585
Operation Should Be SUCCESSFUL ${operation}
8686

8787
Should Contain ${operation.to_json()["c8y_Command"]["result"]} It works!
@@ -152,7 +152,7 @@ Install container-group file
152152
DeviceLibrary.Directory Should Not Be Empty /data/tedge-container-plugin/compose/${package_name}
153153

154154
Device Should Have Installed Software {"name": "${package_name}", "version": "${package_version}", "softwareType": "container-group"}
155-
${operation}= Cumulocity.Execute Shell Command sudo tedge-container engine docker run --rm -t --network tedge docker.io/busybox wget -O- ${service_name}:80
155+
${operation}= Cumulocity.Execute Shell Command sudo tedge-container engine docker run --rm -t --network tedge docker.io/library/busybox wget -O- ${service_name}:80
156156
Operation Should Be SUCCESSFUL ${operation}
157157
Should Contain ${operation.to_json()["c8y_Command"]["result"]} My Custom Web Application
158158
Cumulocity.Should Have Services name=${package_name}@${service_name} service_type=container-group status=up

0 commit comments

Comments
 (0)