Skip to content
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions pkg/bib/container/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package container

import (
"encoding/json"
"errors"
"fmt"
"os"
"os/exec"
Expand All @@ -16,6 +17,7 @@ import (
type Container struct {
id string
root string
arch string
}

// New creates a new running container from the given image reference.
Expand Down Expand Up @@ -62,6 +64,15 @@ func New(ref string) (*Container, error) {
c = nil
}
}()
// not all containers set {{.Architecture}} so fallback
c.arch, err = findContainerArchInspect(c.id, ref)
if err != nil {
var err2 error
c.arch, err2 = findContainerArchUname(c.id, ref)
if err2 != nil {
return nil, errors.Join(err, err2)
}
}

/* #nosec G204 */
output, err = exec.Command("podman", "mount", c.id).Output()
Expand Down Expand Up @@ -98,6 +109,11 @@ func (c *Container) Root() string {
return c.root
}

// Arch returns the architecture of the container
func (c *Container) Arch() string {
return c.arch
}

// Reads a file from the container
func (c *Container) ReadFile(path string) ([]byte, error) {
/* #nosec G204 */
Expand Down Expand Up @@ -168,3 +184,27 @@ func (c *Container) DefaultRootfsType() (string, error) {

return fsType, nil
}

func findContainerArchInspect(cntId, ref string) (string, error) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AFAIK the associated image always has an arch, I was able to retrieve the arch for ubi9 like this:

obudai@outland ~> podman ps
CONTAINER ID  IMAGE                                   COMMAND     CREATED             STATUS             PORTS       NAMES
2eaa8a5d582c  registry.access.redhat.com/ubi9:latest  /bin/bash   About a minute ago  Up About a minute              charming_dubinsky
obudai@outland ~> podman inspect -f '{{.Image}}' 2eaa8a5d582c
28fbac8f0a2b3ee82129b9feaae59d029a5eba93e5372002d2612d965979101a
obudai@outland ~> podman image inspect -f '{{.Architecture}}' 28fbac8f0a2b3ee82129b9feaae59d029a5eba93e5372002d2612d965979101a
arm64

Could be a tad cleaner than execing? Not sure. Alternatively, we can just always exec so there's just one codepath.

/* #nosec G204 */
output, err := exec.Command("podman", "inspect", "-f", "{{.Architecture}}", cntId).Output()
if err != nil {
if err, ok := err.(*exec.ExitError); ok {
return "", fmt.Errorf("inspecting container %q failed: %w\nstderr:\n%s", ref, err, err.Stderr)
}
return "", fmt.Errorf("inspecting %s container failed with generic error: %w", ref, err)
}
return strings.TrimSpace(string(output)), nil
}

func findContainerArchUname(cntId, ref string) (string, error) {
/* #nosec G204 */
output, err := exec.Command("podman", "exec", cntId, "uname", "-m").Output()
if err != nil {
if err, ok := err.(*exec.ExitError); ok {
return "", fmt.Errorf("running 'uname -m' from container %q failed: %w\nstderr:\n%s", cntId, err, err.Stderr)
}
return "", fmt.Errorf("running 'uname -m' from container %q failed with generic error: %w", cntId, err)
}
return strings.TrimSpace(string(output)), nil
}