Skip to content

Commit

Permalink
Merge pull request #423 from flatcar/krnowak/move-oem-mountpoint
Browse files Browse the repository at this point in the history
another sysext test + /usr/share/oem -> /oem
  • Loading branch information
krnowak authored May 30, 2023
2 parents 5e94997 + 0a8b738 commit 01c37c4
Show file tree
Hide file tree
Showing 9 changed files with 660 additions and 210 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,12 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
### Added

- `DefaultUser` parameter when registering a test to use a user different from `core` ([#424](https://github.com/flatcar/mantle/pull/424))
- `systemd.sysext.custom-oem` for testing the activation of the OEM sysext image ([#423](https://github.com/flatcar/mantle/pull/423))

### Change

- Some tests dealing with OEM partition were duplicated or adapted for the OEM partition mountpoint move. The older versions of Flatcar will run tests for the old mountpoint location, the new enough versions - for both mountpoint locations. ([#423](https://github.com/flatcar/mantle/pull/423))

### Removed

### Fixed
Expand Down
20 changes: 14 additions & 6 deletions kola/harness.go
Original file line number Diff line number Diff line change
Expand Up @@ -680,8 +680,8 @@ func findExecDir() string {
return filepath.Dir(p)
}

// ScpKolet searches for a kolet binary and copies it to the machine.
func ScpKolet(c cluster.TestCluster, mArch string) {
// UploadKolet searches for a kolet binary and copies it to the machine.
func UploadKolet(c cluster.TestCluster, mArch string) error {
for _, d := range []string{
".",
findExecDir(),
Expand All @@ -691,21 +691,29 @@ func ScpKolet(c cluster.TestCluster, mArch string) {
kolet := filepath.Join(d, "kolet")
if _, err := os.Stat(kolet); err == nil {
if err := c.DropFile(kolet); err != nil {
c.Fatalf("dropping kolet binary: %v", err)
return fmt.Errorf("dropping kolet binary: %w", err)
}
// The default SELinux rules do not allow init_t to execute user_home_t
if Options.Distribution == "rhcos" || Options.Distribution == "fcos" {
for _, machine := range c.Machines() {
out, stderr, err := machine.SSH("sudo chcon -t bin_t kolet")
if err != nil {
c.Fatalf("running chcon on kolet: %s: %s: %v", out, stderr, err)
return fmt.Errorf("running chcon on kolet: %s: %s: %w", out, stderr, err)
}
}
}
return
return nil
}
}
c.Fatalf("Unable to locate kolet binary for %s", mArch)
return fmt.Errorf("Unable to locate kolet binary for %s", mArch)
}

// ScpKolet searches for a kolet binary and copies it to the
// machine. It's fatal if it fails.
func ScpKolet(c cluster.TestCluster, mArch string) {
if err := UploadKolet(c, mArch); err != nil {
c.Fatal(err)
}
}

// CheckConsole checks some console output for badness and returns short
Expand Down
171 changes: 39 additions & 132 deletions kola/tests/devcontainer/devcontainer.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,48 +14,32 @@
package devcontainer

import (
"bytes"
"encoding/base64"
"errors"
"fmt"
"os"
"strings"
"text/template"
"time"
"unicode"

"github.com/coreos/go-semver/semver"

"github.com/flatcar/mantle/kola"
"github.com/flatcar/mantle/kola/cluster"
"github.com/flatcar/mantle/kola/register"
"github.com/flatcar/mantle/platform"
"github.com/flatcar/mantle/kola/tests/util"
"github.com/flatcar/mantle/platform/conf"
"github.com/flatcar/mantle/platform/local"
"github.com/flatcar/mantle/platform/machine/qemu"
"github.com/flatcar/mantle/platform/machine/unprivqemu"
"github.com/flatcar/mantle/util"
)

// Both template parameters may contain @ARCH@ and @VERSION@
// placeholders, which will be substituted by real values at test run
// time.
type scriptTemplateParameters struct {
BinhostURLTemplate string
ImageDirectoryURLTemplate string
BinhostURLTemplate string
}

type configTemplateParameters struct {
DevContainerScriptBase64Contents string
DownloadLibraryBase64Contents string
MainScriptBase64Contents string
}

func trimLeftSpace(contents string) string {
return strings.TrimLeftFunc(contents, unicode.IsSpace)
}

var (
devContainerScriptTemplate = trimLeftSpace(`
devContainerScript = util.TrimLeftSpace(`
#!/bin/bash
set -euo pipefail
Expand All @@ -76,49 +60,21 @@ zcat /proc/config.gz >/usr/src/linux/.config
exec make -C /usr/src/linux "-j$(nproc)" modules_prepare V=1
`)

scriptPrologTemplate = trimLeftSpace(`
scriptPrologTemplate = util.TrimLeftSpace(`
#!/bin/bash
set -euo pipefail
set -x
function process_template() {
local template="${1}"; shift
local arch="${1}"; shift
local version="${1}"; shift
local result="${template}"
set -euo pipefail
result="${result//@ARCH@/${arch}}"
result="${result//@VERSION@/${version}}"
source /home/core/download-library.sh
echo "${result}"
}
download_dev_container_image flatcar_developer_container.bin
source /usr/share/coreos/release
ARCH="${FLATCAR_RELEASE_BOARD/-usr/}"
VERSION="${FLATCAR_RELEASE_VERSION}"
IMAGE_URL=$(process_template '{{ .ImageDirectoryURLTemplate }}/flatcar_developer_container.bin.bz2' "${ARCH}" "${VERSION}")
echo "Fetching developer container from ${IMAGE_URL}"
# Stolen from copy_from_buildcache in ci_automation_common.sh. Not
# using --output-dir option as this seems to be quite a new addition
# and curl on older version of Flatcar does not understand it.
curl --fail --silent --show-error --location --retry-delay 1 --retry 60 \
--retry-connrefused --retry-max-time 60 --connect-timeout 20 \
--remote-name "${IMAGE_URL}"
bzip2cat=bzcat
if command -v lbzcat; then
bzip2cat=lbzcat
fi
# The image file takes over 6Gb after normal unpacking, but a lot of
# it is just zeros. Use cp --sparse=always to avoid unnecessary disk
# space waste. Especially that we may not have 6Gb of disk space
# available.
cp --sparse=always <("${bzip2cat}" flatcar_developer_container.bin.bz2) flatcar_developer_container.bin
# PORTAGE_BINHOST and EXPECTED_VERSION are meant to be propagated to
# the dev container as environment variables.
Expand All @@ -137,7 +93,7 @@ VAR_TMP_DIR="${workdir}/tmp"
mkdir -p "${USR_SRC_DIR}" "${VAR_TMP_DIR}"
`)

systemdNspawnScriptBody = trimLeftSpace(`
systemdNspawnScriptBody = util.TrimLeftSpace(`
sudo systemd-nspawn \
--console=pipe \
--setenv=PORTAGE_BINHOST="${PORTAGE_BINHOST}" \
Expand All @@ -151,7 +107,7 @@ sudo systemd-nspawn \
/bin/bash /home/core/dev-container-script
`)

dockerScriptBody = trimLeftSpace(`
dockerScriptBody = util.TrimLeftSpace(`
# TODO: It would much much better if we provided dev-container as a
# docker image on ghcr.io.
Expand Down Expand Up @@ -180,7 +136,7 @@ docker run \
/bin/bash /home/core/dev-container-script
`)

configTemplate = trimLeftSpace(`
configTemplate = util.TrimLeftSpace(`
storage:
files:
- path: /home/core/dev-container-script
Expand All @@ -193,6 +149,16 @@ storage:
name: core
group:
name: core
- path: /home/core/download-library.sh
filesystem: root
mode: 0644
contents:
remote:
url: "data:text/plain;base64,{{ .DownloadLibraryBase64Contents }}"
user:
name: core
group:
name: core
- path: /home/core/main-script
filesystem: root
mode: 0755
Expand All @@ -216,7 +182,7 @@ func init() {
Distros: []string{"cl"},
MinVersion: semver.Version{Major: 2592},
NativeFuncs: map[string]func() error{
"Http": Serve,
"Http": util.Serve,
},
})
register.Register(&register.Test{
Expand All @@ -229,7 +195,7 @@ func init() {
// TODO: Revisit this flag when updating SELinux policies.
Flags: []register.Flag{register.NoEnableSelinux},
NativeFuncs: map[string]func() error{
"Http": Serve,
"Http": util.Serve,
},
})
}
Expand All @@ -243,109 +209,50 @@ func withDocker(c cluster.TestCluster) {
}

func runDevContainerTest(c cluster.TestCluster, scriptBody string) {
devcontainerURL := kola.DevcontainerURL
if kola.DevcontainerFile != "" {
// This URL is deterministic as it runs on the started machine.
devcontainerURL = "http://localhost:8080"
downloadLibrary, err := util.DevContainerDownloadLibrary()
if err != nil {
c.Fatalf("creating a dev container download script failed: %v", err)
}

scriptParameters := scriptTemplateParameters{
BinhostURLTemplate: kola.DevcontainerBinhostURL,
ImageDirectoryURLTemplate: devcontainerURL,
BinhostURLTemplate: kola.DevcontainerBinhostURL,
}

userdata, err := prepareUserData(scriptParameters, scriptBody)
userdata, err := prepareUserData(scriptParameters, scriptBody, downloadLibrary)
if err != nil {
c.Fatalf("preparing user data failed: %v", err)
}
machine, err := newMachineWithLargeDisk(c, userdata)
machine, err := util.NewMachineWithLargeDisk(c, "5G", userdata)
if err != nil {
c.Fatalf("creating a machine failed: %v", err)
}

if kola.DevcontainerFile != "" {
configureHTTPServer(c, machine)
err = util.ConfigureDevContainerHTTPServer(c, machine)
if err != nil {
c.Fatalf("configuring local HTTP server for dev container image failed: %v", err)
}

if _, err := c.SSH(machine, "/home/core/main-script"); err != nil {
c.Fatalf("main script failed: %v", err)
}
}

func prepareUserData(scriptParameters scriptTemplateParameters, scriptBody string) (*conf.UserData, error) {
prolog, err := executeTemplate(scriptPrologTemplate, "script prolog", scriptParameters)
func prepareUserData(scriptParameters scriptTemplateParameters, scriptBody, downloadLibrary string) (*conf.UserData, error) {
prolog, err := util.ExecNamedTemplate(scriptPrologTemplate, "script prolog", scriptParameters)
if err != nil {
return nil, err
}
mainScript := fmt.Sprintf("%s%s", prolog, scriptBody)
mainScriptBase64 := base64.StdEncoding.EncodeToString(([]byte)(mainScript))
devContainerScript, err := executeTemplate(devContainerScriptTemplate, "dev container script", scriptParameters)
if err != nil {
return nil, err
}
devContainerScriptBase64 := base64.StdEncoding.EncodeToString(([]byte)(devContainerScript))
mainScriptBase64 := util.ToBase64(mainScript)
downloadLibraryBase64 := util.ToBase64(downloadLibrary)
devContainerScriptBase64 := util.ToBase64(devContainerScript)
configParameters := configTemplateParameters{
DevContainerScriptBase64Contents: devContainerScriptBase64,
DownloadLibraryBase64Contents: downloadLibraryBase64,
MainScriptBase64Contents: mainScriptBase64,
}
config, err := executeTemplate(configTemplate, "cloud config", configParameters)
config, err := util.ExecNamedTemplate(configTemplate, "cloud config", configParameters)
if err != nil {
return nil, err
}
return conf.ContainerLinuxConfig(config), nil
}

func executeTemplate(contents, name string, parameters any) (string, error) {
tmpl, err := template.New(name).Parse(contents)
if err != nil {
return "", fmt.Errorf("parsing %s as a template failed: %w", name, err)
}
buf := bytes.Buffer{}
if err := tmpl.Execute(&buf, parameters); err != nil {
return "", fmt.Errorf("executing %s template failed: %w", name, err)
}
return buf.String(), nil
}

func newMachineWithLargeDisk(c cluster.TestCluster, userData *conf.UserData) (platform.Machine, error) {
options := platform.MachineOptions{
ExtraPrimaryDiskSize: "5G",
}
switch pc := c.Cluster.(type) {
case *qemu.Cluster:
return pc.NewMachineWithOptions(userData, options)
case *unprivqemu.Cluster:
return pc.NewMachineWithOptions(userData, options)
}
return nil, errors.New("unknown cluster type, this test should only be running on qemu or qemu-unpriv platforms")
}

func Serve() error {
httpServer := local.SimpleHTTP{}
return httpServer.Serve()
}

func configureHTTPServer(c cluster.TestCluster, srv platform.Machine) {
// manually copy Kolet on the host, as the initial size cluster is 0.
kola.ScpKolet(c, strings.SplitN(kola.QEMUOptions.Board, "-", 2)[0])

in, err := os.Open(kola.DevcontainerFile)
if err != nil {
c.Fatalf("opening dev container file: %v", err)
}

defer in.Close()

if err := platform.InstallFile(in, srv, "/var/www/flatcar_developer_container.bin.bz2"); err != nil {
c.Fatalf("copying dev container to HTTP server: %v", err)
}

c.MustSSH(srv, fmt.Sprintf("sudo systemd-run --quiet ./kolet run %s Http", c.H.Name()))

if err := util.WaitUntilReady(60*time.Second, 5*time.Second, func() (bool, error) {
_, _, err := srv.SSH(fmt.Sprintf("curl %s:8080", srv.PrivateIP()))
return err == nil, nil
}); err != nil {
c.Fatal("timed out waiting for http server to become active")
}
}
Loading

0 comments on commit 01c37c4

Please sign in to comment.