summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libpod/runtime_ctr.go5
-rw-r--r--pkg/bindings/images/build.go2
-rw-r--r--pkg/checkpoint/checkpoint_restore.go7
-rw-r--r--pkg/machine/fcos.go57
-rw-r--r--test/e2e/checkpoint_test.go4
-rw-r--r--test/e2e/common_test.go14
-rw-r--r--test/e2e/network_create_test.go22
-rw-r--r--test/e2e/network_test.go57
-rw-r--r--test/e2e/run_networking_test.go91
-rw-r--r--test/system/070-build.bats28
-rw-r--r--vendor/github.com/coreos/stream-metadata-go/release/release.go112
-rw-r--r--vendor/github.com/coreos/stream-metadata-go/release/rhcos/rhcos.go14
-rw-r--r--vendor/github.com/coreos/stream-metadata-go/release/translate.go196
-rw-r--r--vendor/modules.txt2
14 files changed, 585 insertions, 26 deletions
diff --git a/libpod/runtime_ctr.go b/libpod/runtime_ctr.go
index 3799b463f..44364100e 100644
--- a/libpod/runtime_ctr.go
+++ b/libpod/runtime_ctr.go
@@ -192,6 +192,11 @@ func (r *Runtime) initContainerVariables(rSpec *spec.Spec, config *ContainerConf
}
// Reset the log path to point to the default
ctr.config.LogPath = ""
+ // Later in validate() the check is for nil. JSONDeepCopy sets it to an empty
+ // object. Resetting it to nil if it was nil before.
+ if config.StaticMAC == nil {
+ ctr.config.StaticMAC = nil
+ }
}
ctr.config.Spec = rSpec
diff --git a/pkg/bindings/images/build.go b/pkg/bindings/images/build.go
index a363f2c6e..c508cb767 100644
--- a/pkg/bindings/images/build.go
+++ b/pkg/bindings/images/build.go
@@ -352,11 +352,13 @@ func Build(ctx context.Context, containerFiles []string, options entities.BuildO
}
c = tmpFile.Name()
}
+ c = filepath.Clean(c)
cfDir := filepath.Dir(c)
if absDir, err := filepath.EvalSymlinks(cfDir); err == nil {
name := filepath.ToSlash(strings.TrimPrefix(c, cfDir+string(filepath.Separator)))
c = filepath.Join(absDir, name)
}
+
containerfile, err := filepath.Abs(c)
if err != nil {
logrus.Errorf("Cannot find absolute path of %v: %v", c, err)
diff --git a/pkg/checkpoint/checkpoint_restore.go b/pkg/checkpoint/checkpoint_restore.go
index 1ebd6a455..270b5b6c4 100644
--- a/pkg/checkpoint/checkpoint_restore.go
+++ b/pkg/checkpoint/checkpoint_restore.go
@@ -140,6 +140,13 @@ func CRImportCheckpoint(ctx context.Context, runtime *libpod.Runtime, restoreOpt
return nil, errors.Errorf("pod %s does not share the network namespace", ctrConfig.Pod)
}
ctrConfig.NetNsCtr = infraContainer.ID()
+ for net, opts := range ctrConfig.Networks {
+ opts.StaticIPs = nil
+ opts.StaticMAC = nil
+ ctrConfig.Networks[net] = opts
+ }
+ ctrConfig.StaticIP = nil
+ ctrConfig.StaticMAC = nil
}
if ctrConfig.PIDNsCtr != "" {
diff --git a/pkg/machine/fcos.go b/pkg/machine/fcos.go
index 60ab471ee..4d3e2edf4 100644
--- a/pkg/machine/fcos.go
+++ b/pkg/machine/fcos.go
@@ -14,6 +14,7 @@ import (
"strings"
"github.com/coreos/stream-metadata-go/fedoracoreos"
+ "github.com/coreos/stream-metadata-go/release"
"github.com/coreos/stream-metadata-go/stream"
"github.com/pkg/errors"
@@ -28,6 +29,14 @@ var (
Format string = "qcow2.xz"
)
+const (
+ // Used for testing the latest podman in fcos
+ // special builds
+ podmanTesting = "podman-testing"
+ PodmanTestingHost = "fedorapeople.org"
+ PodmanTestingURL = "groups/podman/testing"
+)
+
type FcosDownload struct {
Download
}
@@ -111,14 +120,39 @@ func getFcosArch() string {
return arch
}
+// getStreamURL is a wrapper for the fcos.GetStream URL
+// so that we can inject a special stream and url for
+// testing podman before it merges into fcos builds
+func getStreamURL(streamType string) url2.URL {
+ // For the podmanTesting stream type, we point to
+ // a custom url on fedorapeople.org
+ if streamType == podmanTesting {
+ return url2.URL{
+ Scheme: "https",
+ Host: PodmanTestingHost,
+ Path: fmt.Sprintf("%s/%s.json", PodmanTestingURL, "podman4"),
+ }
+ }
+ return fedoracoreos.GetStreamURL(streamType)
+}
+
// This should get Exported and stay put as it will apply to all fcos downloads
// getFCOS parses fedoraCoreOS's stream and returns the image download URL and the release version
func getFCOSDownload(imageStream string) (*fcosDownloadInfo, error) {
var (
fcosstable stream.Stream
+ altMeta release.Release
streamType string
)
+
+ // This is being hard set to testing. Once podman4 is in the
+ // fcos trees, we should remove it and re-release at least on
+ // macs.
+ imageStream = "podman-testing"
+
switch imageStream {
+ case "podman-testing":
+ streamType = "podman-testing"
case "testing", "":
streamType = fedoracoreos.StreamTesting
case "next":
@@ -128,7 +162,7 @@ func getFCOSDownload(imageStream string) (*fcosDownloadInfo, error) {
default:
return nil, errors.Errorf("invalid stream %s: valid streams are `testing` and `stable`", imageStream)
}
- streamurl := fedoracoreos.GetStreamURL(streamType)
+ streamurl := getStreamURL(streamType)
resp, err := http.Get(streamurl.String())
if err != nil {
return nil, err
@@ -142,6 +176,27 @@ func getFCOSDownload(imageStream string) (*fcosDownloadInfo, error) {
logrus.Error(err)
}
}()
+ if imageStream == podmanTesting {
+ if err := json.Unmarshal(body, &altMeta); err != nil {
+ return nil, err
+ }
+
+ arches, ok := altMeta.Architectures[getFcosArch()]
+ if !ok {
+ return nil, fmt.Errorf("unable to pull VM image: no targetArch in stream")
+ }
+ qcow2, ok := arches.Media.Qemu.Artifacts["qcow2.xz"]
+ if !ok {
+ return nil, fmt.Errorf("unable to pull VM image: no qcow2.xz format in stream")
+ }
+ disk := qcow2.Disk
+
+ return &fcosDownloadInfo{
+ Location: disk.Location,
+ Sha256Sum: disk.Sha256,
+ CompressionType: "xz",
+ }, nil
+ }
if err := json.Unmarshal(body, &fcosstable); err != nil {
return nil, err
diff --git a/test/e2e/checkpoint_test.go b/test/e2e/checkpoint_test.go
index 5f1e4b1d1..5abc672e9 100644
--- a/test/e2e/checkpoint_test.go
+++ b/test/e2e/checkpoint_test.go
@@ -1081,10 +1081,6 @@ var _ = Describe("Podman checkpoint", func() {
})
namespaceCombination := []string{
- "cgroup,ipc,net,uts,pid",
- "cgroup,ipc,net,uts",
- "cgroup,ipc,net",
- "cgroup,ipc",
"ipc,net,uts,pid",
"ipc,net,uts",
"ipc,net",
diff --git a/test/e2e/common_test.go b/test/e2e/common_test.go
index f843a8984..b1cd76d27 100644
--- a/test/e2e/common_test.go
+++ b/test/e2e/common_test.go
@@ -771,15 +771,15 @@ func SkipIfNotActive(unit string, reason string) {
}
}
-func SkipIfNetavark(p *PodmanTestIntegration) {
- if p.NetworkBackend == Netavark {
- Skip("This test is not compatible with the netavark network backend")
+func SkipIfCNI(p *PodmanTestIntegration) {
+ if p.NetworkBackend == CNI {
+ Skip("this test is not compatible with the CNI network backend")
}
}
-func SkipUntilAardvark(p *PodmanTestIntegration) {
+func SkipIfNetavark(p *PodmanTestIntegration) {
if p.NetworkBackend == Netavark {
- Skip("Re-enable when aardvark is functional")
+ Skip("This test is not compatible with the netavark network backend")
}
}
@@ -1038,3 +1038,7 @@ func ncz(port int) bool {
}
return false
}
+
+func createNetworkName(name string) string {
+ return name + stringid.GenerateNonCryptoID()[:10]
+}
diff --git a/test/e2e/network_create_test.go b/test/e2e/network_create_test.go
index 7589adaab..395759ee6 100644
--- a/test/e2e/network_create_test.go
+++ b/test/e2e/network_create_test.go
@@ -330,8 +330,8 @@ var _ = Describe("Podman network create", func() {
Expect(nc).To(ExitWithError())
})
- It("podman network create with internal should not have dnsname", func() {
- SkipUntilAardvark(podmanTest)
+ It("podman CNI network create with internal should not have dnsname", func() {
+ SkipIfNetavark(podmanTest)
net := "internal-test" + stringid.GenerateNonCryptoID()
nc := podmanTest.Podman([]string{"network", "create", "--internal", net})
nc.WaitWithDefaultTimeout()
@@ -348,6 +348,24 @@ var _ = Describe("Podman network create", func() {
Expect(nc.OutputToString()).ToNot(ContainSubstring("dnsname"))
})
+ It("podman Netavark network create with internal should have dnsname", func() {
+ SkipIfCNI(podmanTest)
+ net := "internal-test" + stringid.GenerateNonCryptoID()
+ nc := podmanTest.Podman([]string{"network", "create", "--internal", net})
+ nc.WaitWithDefaultTimeout()
+ defer podmanTest.removeNetwork(net)
+ Expect(nc).Should(Exit(0))
+ // Not performing this check on remote tests because it is a logrus error which does
+ // not come back via stderr on the remote client.
+ if !IsRemote() {
+ Expect(nc.ErrorToString()).To(BeEmpty())
+ }
+ nc = podmanTest.Podman([]string{"network", "inspect", net})
+ nc.WaitWithDefaultTimeout()
+ Expect(nc).Should(Exit(0))
+ Expect(nc.OutputToString()).To(ContainSubstring(`"dns_enabled": true`))
+ })
+
It("podman network create with invalid name", func() {
for _, name := range []string{"none", "host", "bridge", "private", "slirp4netns", "container", "ns"} {
nc := podmanTest.Podman([]string{"network", "create", name})
diff --git a/test/e2e/network_test.go b/test/e2e/network_test.go
index bd30a1f5d..89a9005f5 100644
--- a/test/e2e/network_test.go
+++ b/test/e2e/network_test.go
@@ -466,10 +466,61 @@ var _ = Describe("Podman network", func() {
Expect(lines[1]).To(Equal(netName2))
})
- It("podman network with multiple aliases", func() {
- SkipUntilAardvark(podmanTest)
+ It("podman CNI network with multiple aliases", func() {
+ SkipIfNetavark(podmanTest)
+ var worked bool
+ netName := createNetworkName("aliasTest")
+ session := podmanTest.Podman([]string{"network", "create", netName})
+ session.WaitWithDefaultTimeout()
+ defer podmanTest.removeNetwork(netName)
+ Expect(session).Should(Exit(0))
+
+ interval := time.Duration(250 * time.Millisecond)
+ for i := 0; i < 6; i++ {
+ n := podmanTest.Podman([]string{"network", "exists", netName})
+ n.WaitWithDefaultTimeout()
+ worked = n.ExitCode() == 0
+ if worked {
+ break
+ }
+ time.Sleep(interval)
+ interval *= 2
+ }
+
+ top := podmanTest.Podman([]string{"run", "-dt", "--name=web", "--network=" + netName, "--network-alias=web1", "--network-alias=web2", nginx})
+ top.WaitWithDefaultTimeout()
+ Expect(top).Should(Exit(0))
+ interval = time.Duration(250 * time.Millisecond)
+ // Wait for the nginx service to be running
+ for i := 0; i < 6; i++ {
+ // Test curl against the container's name
+ c1 := podmanTest.Podman([]string{"run", "--dns-search", "dns.podman", "--network=" + netName, nginx, "curl", "web"})
+ c1.WaitWithDefaultTimeout()
+ worked = c1.ExitCode() == 0
+ if worked {
+ break
+ }
+ time.Sleep(interval)
+ interval *= 2
+ }
+ Expect(worked).To(BeTrue())
+
+ // Nginx is now running so no need to do a loop
+ // Test against the first alias
+ c2 := podmanTest.Podman([]string{"run", "--dns-search", "dns.podman", "--network=" + netName, nginx, "curl", "web1"})
+ c2.WaitWithDefaultTimeout()
+ Expect(c2).Should(Exit(0))
+
+ // Test against the second alias
+ c3 := podmanTest.Podman([]string{"run", "--dns-search", "dns.podman", "--network=" + netName, nginx, "curl", "web2"})
+ c3.WaitWithDefaultTimeout()
+ Expect(c3).Should(Exit(0))
+ })
+
+ It("podman Netavark network with multiple aliases", func() {
+ SkipIfCNI(podmanTest)
var worked bool
- netName := "aliasTest" + stringid.GenerateNonCryptoID()
+ netName := createNetworkName("aliasTest")
session := podmanTest.Podman([]string{"network", "create", netName})
session.WaitWithDefaultTimeout()
defer podmanTest.removeNetwork(netName)
diff --git a/test/e2e/run_networking_test.go b/test/e2e/run_networking_test.go
index 4c056df10..aa1887f84 100644
--- a/test/e2e/run_networking_test.go
+++ b/test/e2e/run_networking_test.go
@@ -715,8 +715,8 @@ EXPOSE 2004-2005/tcp`, ALPINE)
Expect(run.OutputToString()).To(ContainSubstring(ipAddr))
})
- It("podman cni network works across user ns", func() {
- SkipUntilAardvark(podmanTest)
+ It("podman CNI network works across user ns", func() {
+ SkipIfNetavark(podmanTest)
netName := stringid.GenerateNonCryptoID()
create := podmanTest.Podman([]string{"network", "create", netName})
create.WaitWithDefaultTimeout()
@@ -740,6 +740,31 @@ EXPOSE 2004-2005/tcp`, ALPINE)
Expect(log.OutputToString()).To(Equal("podman"))
})
+ It("podman Netavark network works across user ns", func() {
+ SkipIfCNI(podmanTest)
+ netName := createNetworkName("")
+ create := podmanTest.Podman([]string{"network", "create", netName})
+ create.WaitWithDefaultTimeout()
+ Expect(create).Should(Exit(0))
+ defer podmanTest.removeNetwork(netName)
+
+ name := "nc-server"
+ run := podmanTest.Podman([]string{"run", "--log-driver", "k8s-file", "-d", "--name", name, "--net", netName, ALPINE, "nc", "-l", "-p", "9480"})
+ run.WaitWithDefaultTimeout()
+ Expect(run).Should(Exit(0))
+
+ // NOTE: we force the k8s-file log driver to make sure the
+ // tests are passing inside a container.
+ run = podmanTest.Podman([]string{"run", "--log-driver", "k8s-file", "--rm", "--net", netName, "--uidmap", "0:1:4096", ALPINE, "sh", "-c", fmt.Sprintf("echo podman | nc -w 1 %s.dns.podman 9480", name)})
+ run.WaitWithDefaultTimeout()
+ Expect(run).Should(Exit(0))
+
+ log := podmanTest.Podman([]string{"logs", name})
+ log.WaitWithDefaultTimeout()
+ Expect(log).Should(Exit(0))
+ Expect(log.OutputToString()).To(Equal("podman"))
+ })
+
It("podman run with new:pod and static-ip", func() {
netName := stringid.GenerateNonCryptoID()
ipAddr := "10.25.40.128"
@@ -814,14 +839,50 @@ EXPOSE 2004-2005/tcp`, ALPINE)
pingTest("--net=private")
})
- It("podman run check dnsname plugin", func() {
- SkipUntilAardvark(podmanTest)
+ It("podman run check dnsname plugin with CNI", func() {
+ SkipIfNetavark(podmanTest)
+ pod := "testpod"
+ session := podmanTest.Podman([]string{"pod", "create", "--name", pod})
+ session.WaitWithDefaultTimeout()
+ Expect(session).Should(Exit(0))
+
+ net := createNetworkName("IntTest")
+ session = podmanTest.Podman([]string{"network", "create", net})
+ session.WaitWithDefaultTimeout()
+ defer podmanTest.removeNetwork(net)
+ Expect(session).Should(Exit(0))
+
+ pod2 := "testpod2"
+ session = podmanTest.Podman([]string{"pod", "create", "--network", net, "--name", pod2})
+ session.WaitWithDefaultTimeout()
+ Expect(session).Should(Exit(0))
+
+ session = podmanTest.Podman([]string{"run", "--name", "con1", "--network", net, ALPINE, "nslookup", "con1"})
+ session.WaitWithDefaultTimeout()
+ Expect(session).Should(Exit(0))
+
+ session = podmanTest.Podman([]string{"run", "--name", "con2", "--pod", pod, "--network", net, ALPINE, "nslookup", "con2"})
+ session.WaitWithDefaultTimeout()
+ Expect(session).Should(Exit(0))
+
+ session = podmanTest.Podman([]string{"run", "--name", "con3", "--pod", pod2, ALPINE, "nslookup", "con1"})
+ session.WaitWithDefaultTimeout()
+ Expect(session).Should(Exit(1))
+ Expect(session.ErrorToString()).To(ContainSubstring("can't resolve 'con1'"))
+
+ session = podmanTest.Podman([]string{"run", "--name", "con4", "--network", net, ALPINE, "nslookup", pod2 + ".dns.podman"})
+ session.WaitWithDefaultTimeout()
+ Expect(session).Should(Exit(0))
+ })
+
+ It("podman run check dnsname plugin with Netavark", func() {
+ SkipIfCNI(podmanTest)
pod := "testpod"
session := podmanTest.Podman([]string{"pod", "create", "--name", pod})
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(0))
- net := "IntTest" + stringid.GenerateNonCryptoID()
+ net := createNetworkName("IntTest")
session = podmanTest.Podman([]string{"network", "create", net})
session.WaitWithDefaultTimeout()
defer podmanTest.removeNetwork(net)
@@ -850,9 +911,23 @@ EXPOSE 2004-2005/tcp`, ALPINE)
Expect(session).Should(Exit(0))
})
- It("podman run check dnsname adds dns search domain", func() {
- SkipUntilAardvark(podmanTest)
- net := "dnsname" + stringid.GenerateNonCryptoID()
+ It("podman run check dnsname adds dns search domain with CNI", func() {
+ SkipIfNetavark(podmanTest)
+ net := createNetworkName("dnsname")
+ session := podmanTest.Podman([]string{"network", "create", net})
+ session.WaitWithDefaultTimeout()
+ defer podmanTest.removeNetwork(net)
+ Expect(session).Should(Exit(0))
+
+ session = podmanTest.Podman([]string{"run", "--network", net, ALPINE, "cat", "/etc/resolv.conf"})
+ session.WaitWithDefaultTimeout()
+ Expect(session).Should(Exit(0))
+ Expect(session.OutputToString()).To(ContainSubstring("search dns.podman"))
+ })
+
+ It("podman run check dnsname adds dns search domain with Netavark", func() {
+ SkipIfCNI(podmanTest)
+ net := createNetworkName("dnsname")
session := podmanTest.Podman([]string{"network", "create", net})
session.WaitWithDefaultTimeout()
defer podmanTest.removeNetwork(net)
diff --git a/test/system/070-build.bats b/test/system/070-build.bats
index d5f7365e8..a95acd986 100644
--- a/test/system/070-build.bats
+++ b/test/system/070-build.bats
@@ -88,12 +88,10 @@ EOF
containerfile=$PODMAN_TMPDIR/Containerfile
cat >$containerfile <<EOF
FROM $IMAGE
-RUN apk add nginx
RUN echo $rand_content > /$rand_filename
EOF
- # The 'apk' command can take a long time to fetch files; bump timeout
- PODMAN_TIMEOUT=240 run_podman build -t build_test -f - --format=docker $tmpdir < $containerfile
+ run_podman build -t build_test -f - --format=docker $tmpdir < $containerfile
is "$output" ".*COMMIT" "COMMIT seen in log"
run_podman run --rm build_test cat /$rand_filename
@@ -188,6 +186,30 @@ EOF
run_podman rmi -f build_test $iid
}
+@test "podman build test -f ./relative" {
+ rand_filename=$(random_string 20)
+ rand_content=$(random_string 50)
+
+ tmpdir=$PODMAN_TMPDIR/build-test
+ mkdir -p $tmpdir
+ mkdir -p $PODMAN_TMPDIR/reldir
+
+ containerfile=$PODMAN_TMPDIR/reldir/Containerfile
+ cat >$containerfile <<EOF
+FROM $IMAGE
+RUN echo $rand_content > /$rand_filename
+EOF
+
+ cd $PODMAN_TMPDIR
+ run_podman build -t build_test -f ./reldir/Containerfile --format=docker $tmpdir
+ is "$output" ".*COMMIT" "COMMIT seen in log"
+
+ run_podman run --rm build_test cat /$rand_filename
+ is "$output" "$rand_content" "reading generated file in image"
+
+ run_podman rmi -f build_test
+}
+
@test "podman build - URLs" {
tmpdir=$PODMAN_TMPDIR/build-test
mkdir -p $tmpdir
diff --git a/vendor/github.com/coreos/stream-metadata-go/release/release.go b/vendor/github.com/coreos/stream-metadata-go/release/release.go
new file mode 100644
index 000000000..84a032703
--- /dev/null
+++ b/vendor/github.com/coreos/stream-metadata-go/release/release.go
@@ -0,0 +1,112 @@
+// Package release contains APIs for interacting with a
+// particular "release". Avoid this unless you are sure
+// you need it. It's expected that CoreOS users interact
+// with streams instead.
+package release
+
+import (
+ relrhcos "github.com/coreos/stream-metadata-go/release/rhcos"
+)
+
+// Index models the release index:
+// https://github.com/coreos/fedora-coreos-tracker/tree/master/metadata/release-index
+type Index struct {
+ Note string `json:"note"` // used to note to users not to consume the release metadata index
+ Releases []IndexRelease `json:"releases"`
+ Metadata Metadata `json:"metadata"`
+ Stream string `json:"stream"`
+}
+
+// IndexRelease is a "release pointer" from a release index
+type IndexRelease struct {
+ Commits []IndexReleaseCommit `json:"commits"`
+ Version string `json:"version"`
+ MetadataURL string `json:"metadata"`
+}
+
+// IndexReleaseCommit describes an ostree commit plus architecture
+type IndexReleaseCommit struct {
+ Architecture string `json:"architecture"`
+ Checksum string `json:"checksum"`
+}
+
+// Release contains details from release.json
+type Release struct {
+ Release string `json:"release"`
+ Stream string `json:"stream"`
+ Metadata Metadata `json:"metadata"`
+ Architectures map[string]Arch `json:"architectures"`
+}
+
+// Metadata is common metadata that contains last-modified
+type Metadata struct {
+ LastModified string `json:"last-modified"`
+}
+
+// Arch release details
+type Arch struct {
+ Commit string `json:"commit"`
+ Media Media `json:"media"`
+ RHELCoreOSExtensions *relrhcos.Extensions `json:"rhel-coreos-extensions,omitempty"`
+}
+
+// Media contains release details for various platforms
+type Media struct {
+ Aliyun *PlatformBase `json:"aliyun"`
+ Aws *PlatformAws `json:"aws"`
+ Azure *PlatformBase `json:"azure"`
+ Digitalocean *PlatformBase `json:"digitalocean"`
+ Exoscale *PlatformBase `json:"exoscale"`
+ Gcp *PlatformGcp `json:"gcp"`
+ Ibmcloud *PlatformBase `json:"ibmcloud"`
+ Metal *PlatformBase `json:"metal"`
+ Openstack *PlatformBase `json:"openstack"`
+ Qemu *PlatformBase `json:"qemu"`
+ Vmware *PlatformBase `json:"vmware"`
+ Vultr *PlatformBase `json:"vultr"`
+}
+
+// PlatformBase with no cloud images
+type PlatformBase struct {
+ Artifacts map[string]ImageFormat `json:"artifacts"`
+}
+
+// PlatformAws contains AWS image information
+type PlatformAws struct {
+ PlatformBase
+ Images map[string]CloudImage `json:"images"`
+}
+
+// PlatformGcp GCP image detail
+type PlatformGcp struct {
+ PlatformBase
+ Image *GcpImage `json:"image"`
+}
+
+// ImageFormat contains all artifacts for a single OS image
+type ImageFormat struct {
+ Disk *Artifact `json:"disk,omitempty"`
+ Kernel *Artifact `json:"kernel,omitempty"`
+ Initramfs *Artifact `json:"initramfs,omitempty"`
+ Rootfs *Artifact `json:"rootfs,omitempty"`
+}
+
+// Artifact represents one image file, plus its metadata
+type Artifact struct {
+ Location string `json:"location"`
+ Signature string `json:"signature"`
+ Sha256 string `json:"sha256"`
+ UncompressedSha256 string `json:"uncompressed-sha256,omitempty"`
+}
+
+// CloudImage generic image detail
+type CloudImage struct {
+ Image string `json:"image"`
+}
+
+// GcpImage represents a GCP cloud image
+type GcpImage struct {
+ Project string `json:"project,omitempty"`
+ Family string `json:"family,omitempty"`
+ Name string `json:"name,omitempty"`
+}
diff --git a/vendor/github.com/coreos/stream-metadata-go/release/rhcos/rhcos.go b/vendor/github.com/coreos/stream-metadata-go/release/rhcos/rhcos.go
new file mode 100644
index 000000000..aeae2c8be
--- /dev/null
+++ b/vendor/github.com/coreos/stream-metadata-go/release/rhcos/rhcos.go
@@ -0,0 +1,14 @@
+package rhcos
+
+// Extensions is data specific to Red Hat Enterprise Linux CoreOS
+type Extensions struct {
+ AzureDisk *AzureDisk `json:"azure-disk,omitempty"`
+}
+
+// AzureDisk represents an Azure cloud image.
+type AzureDisk struct {
+ // URL to an image already stored in Azure infrastructure
+ // that can be copied into an image gallery. Avoid creating VMs directly
+ // from this URL as that may lead to performance limitations.
+ URL string `json:"url,omitempty"`
+}
diff --git a/vendor/github.com/coreos/stream-metadata-go/release/translate.go b/vendor/github.com/coreos/stream-metadata-go/release/translate.go
new file mode 100644
index 000000000..518c75eb9
--- /dev/null
+++ b/vendor/github.com/coreos/stream-metadata-go/release/translate.go
@@ -0,0 +1,196 @@
+package release
+
+import (
+ "github.com/coreos/stream-metadata-go/stream"
+ "github.com/coreos/stream-metadata-go/stream/rhcos"
+)
+
+func mapArtifact(ra *Artifact) *stream.Artifact {
+ if ra == nil {
+ return nil
+ }
+ return &stream.Artifact{
+ Location: ra.Location,
+ Signature: ra.Signature,
+ Sha256: ra.Sha256,
+ UncompressedSha256: ra.UncompressedSha256,
+ }
+}
+
+func mapFormats(m map[string]ImageFormat) map[string]stream.ImageFormat {
+ r := make(map[string]stream.ImageFormat)
+ for k, v := range m {
+ r[k] = stream.ImageFormat{
+ Disk: mapArtifact(v.Disk),
+ Kernel: mapArtifact(v.Kernel),
+ Initramfs: mapArtifact(v.Initramfs),
+ Rootfs: mapArtifact(v.Rootfs),
+ }
+ }
+ return r
+}
+
+// Convert a release architecture to a stream architecture
+func (releaseArch *Arch) toStreamArch(rel *Release) stream.Arch {
+ artifacts := make(map[string]stream.PlatformArtifacts)
+ cloudImages := stream.Images{}
+ var rhcosExt *rhcos.Extensions
+ relRHCOSExt := releaseArch.RHELCoreOSExtensions
+ if relRHCOSExt != nil {
+ rhcosExt = &rhcos.Extensions{}
+ }
+ if releaseArch.Media.Aws != nil {
+ artifacts["aws"] = stream.PlatformArtifacts{
+ Release: rel.Release,
+ Formats: mapFormats(releaseArch.Media.Aws.Artifacts),
+ }
+ awsAmis := stream.AwsImage{
+ Regions: make(map[string]stream.AwsRegionImage),
+ }
+ if releaseArch.Media.Aws.Images != nil {
+ for region, ami := range releaseArch.Media.Aws.Images {
+ ri := stream.AwsRegionImage{Release: rel.Release, Image: ami.Image}
+ awsAmis.Regions[region] = ri
+
+ }
+ cloudImages.Aws = &awsAmis
+ }
+ }
+
+ if releaseArch.Media.Azure != nil {
+ artifacts["azure"] = stream.PlatformArtifacts{
+ Release: rel.Release,
+ Formats: mapFormats(releaseArch.Media.Azure.Artifacts),
+ }
+
+ if relRHCOSExt != nil {
+ az := relRHCOSExt.AzureDisk
+ if az != nil {
+ rhcosExt.AzureDisk = &rhcos.AzureDisk{
+ Release: rel.Release,
+ URL: az.URL,
+ }
+ }
+ }
+ // In the future this is where we'd also add FCOS Marketplace data.
+ // See https://github.com/coreos/stream-metadata-go/issues/13
+ }
+
+ if releaseArch.Media.Aliyun != nil {
+ artifacts["aliyun"] = stream.PlatformArtifacts{
+ Release: rel.Release,
+ Formats: mapFormats(releaseArch.Media.Aliyun.Artifacts),
+ }
+ }
+
+ if releaseArch.Media.Exoscale != nil {
+ artifacts["exoscale"] = stream.PlatformArtifacts{
+ Release: rel.Release,
+ Formats: mapFormats(releaseArch.Media.Exoscale.Artifacts),
+ }
+ }
+
+ if releaseArch.Media.Vultr != nil {
+ artifacts["vultr"] = stream.PlatformArtifacts{
+ Release: rel.Release,
+ Formats: mapFormats(releaseArch.Media.Vultr.Artifacts),
+ }
+ }
+
+ if releaseArch.Media.Gcp != nil {
+ artifacts["gcp"] = stream.PlatformArtifacts{
+ Release: rel.Release,
+ Formats: mapFormats(releaseArch.Media.Gcp.Artifacts),
+ }
+
+ if releaseArch.Media.Gcp.Image != nil {
+ cloudImages.Gcp = &stream.GcpImage{
+ Name: releaseArch.Media.Gcp.Image.Name,
+ Family: releaseArch.Media.Gcp.Image.Family,
+ Project: releaseArch.Media.Gcp.Image.Project,
+ }
+ }
+ }
+
+ if releaseArch.Media.Digitalocean != nil {
+ artifacts["digitalocean"] = stream.PlatformArtifacts{
+ Release: rel.Release,
+ Formats: mapFormats(releaseArch.Media.Digitalocean.Artifacts),
+ }
+
+ /* We're producing artifacts but they're not yet available
+ in DigitalOcean as distribution images.
+ digitalOceanImage := stream.CloudImage{Image: fmt.Sprintf("fedora-coreos-%s", Stream)}
+ cloudImages.Digitalocean = &digitalOceanImage
+ */
+ }
+
+ if releaseArch.Media.Ibmcloud != nil {
+ artifacts["ibmcloud"] = stream.PlatformArtifacts{
+ Release: rel.Release,
+ Formats: mapFormats(releaseArch.Media.Ibmcloud.Artifacts),
+ }
+ }
+
+ // if releaseArch.Media.Packet != nil {
+ // packet := StreamMediaDetails{
+ // Release: rel.Release,
+ // Formats: releaseArch.Media.Packet.Artifacts,
+ // }
+ // artifacts.Packet = &packet
+
+ // packetImage := StreamCloudImage{Image: fmt.Sprintf("fedora_coreos_%s", rel.Stream)}
+ // cloudImages.Packet = &packetImage
+ // }
+
+ if releaseArch.Media.Openstack != nil {
+ artifacts["openstack"] = stream.PlatformArtifacts{
+ Release: rel.Release,
+ Formats: mapFormats(releaseArch.Media.Openstack.Artifacts),
+ }
+ }
+
+ if releaseArch.Media.Qemu != nil {
+ artifacts["qemu"] = stream.PlatformArtifacts{
+ Release: rel.Release,
+ Formats: mapFormats(releaseArch.Media.Qemu.Artifacts),
+ }
+ }
+
+ // if releaseArch.Media.Virtualbox != nil {
+ // virtualbox := StreamMediaDetails{
+ // Release: rel.Release,
+ // Formats: releaseArch.Media.Virtualbox.Artifacts,
+ // }
+ // artifacts.Virtualbox = &virtualbox
+ // }
+
+ if releaseArch.Media.Vmware != nil {
+ artifacts["vmware"] = stream.PlatformArtifacts{
+ Release: rel.Release,
+ Formats: mapFormats(releaseArch.Media.Vmware.Artifacts),
+ }
+ }
+
+ if releaseArch.Media.Metal != nil {
+ artifacts["metal"] = stream.PlatformArtifacts{
+ Release: rel.Release,
+ Formats: mapFormats(releaseArch.Media.Metal.Artifacts),
+ }
+ }
+
+ return stream.Arch{
+ Artifacts: artifacts,
+ Images: cloudImages,
+ RHELCoreOSExtensions: rhcosExt,
+ }
+}
+
+// ToStreamArchitectures converts a release to a stream
+func (rel *Release) ToStreamArchitectures() map[string]stream.Arch {
+ streamArch := make(map[string]stream.Arch)
+ for arch, releaseArch := range rel.Architectures {
+ streamArch[arch] = releaseArch.toStreamArch(rel)
+ }
+ return streamArch
+}
diff --git a/vendor/modules.txt b/vendor/modules.txt
index 9260511f5..f6042a041 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -291,6 +291,8 @@ github.com/coreos/go-systemd/v22/sdjournal
## explicit
github.com/coreos/stream-metadata-go/fedoracoreos
github.com/coreos/stream-metadata-go/fedoracoreos/internals
+github.com/coreos/stream-metadata-go/release
+github.com/coreos/stream-metadata-go/release/rhcos
github.com/coreos/stream-metadata-go/stream
github.com/coreos/stream-metadata-go/stream/rhcos
# github.com/cyphar/filepath-securejoin v0.2.3