Skip to content

Commit

Permalink
process-user-data: create generic file provider for userdata
Browse files Browse the repository at this point in the history
The docker provider currently looks up a certain path to find a user
data file. We can generalize this to use it also for config disks.

In mkosi the process-user-data service has a soft dependency on a mount
unit that will mount a confidisk with the label "cidata". the service
can then consume the userdata from the mount point.

This will enable mkosi x86_64 images to work on libvirt unmodified.

Signed-off-by: Magnus Kulke <[email protected]>
  • Loading branch information
mkulke authored and stevenhorsman committed Dec 2, 2024
1 parent 5612135 commit bf5c3fb
Show file tree
Hide file tree
Showing 7 changed files with 36 additions and 16 deletions.
3 changes: 2 additions & 1 deletion src/cloud-api-adaptor/pkg/paths/paths.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@ const (
InitDataPath = "/run/peerpod/initdata"
AgentCfgPath = "/run/peerpod/agent-config.toml"
ForwarderCfgPath = "/run/peerpod/daemon.json"
DockerUserDataPath = "/peerpod/userdata.json"
DockerUserDataPath = "/run/peerpod/userdata"
UserDataPath = "/run/media/cidata/user-data"
)
10 changes: 7 additions & 3 deletions src/cloud-api-adaptor/pkg/userdata/heuristics.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"os"

. "github.com/confidential-containers/cloud-api-adaptor/src/cloud-api-adaptor/pkg/paths"
"github.com/klauspost/cpuid/v2"
)

Expand All @@ -27,7 +28,10 @@ func isGCPVM(ctx context.Context) bool {
return err == nil
}

func isDockerContainer() bool {
_, err := os.ReadFile("/.dockerenv")
return err == nil
func hasUserDataFile() bool {
_, err := os.Stat(UserDataPath)
if err != nil && os.IsNotExist(err) {
return false
}
return true
}
13 changes: 6 additions & 7 deletions src/cloud-api-adaptor/pkg/userdata/provision.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,11 +105,11 @@ func (g GCPUserDataProvider) GetUserData(ctx context.Context) ([]byte, error) {
return imdsGet(ctx, url, true, []kvPair{{"Metadata-Flavor", "Google"}})
}

type DockerUserDataProvider struct{ DefaultRetry }
type FileUserDataProvider struct{ DefaultRetry }

func (a DockerUserDataProvider) GetUserData(ctx context.Context) ([]byte, error) {
path := DockerUserDataPath
logger.Printf("provider: Docker, userDataPath: %s\n", path)
func (a FileUserDataProvider) GetUserData(ctx context.Context) ([]byte, error) {
path := UserDataPath
logger.Printf("provider: File, userDataPath: %s\n", path)
userData, err := os.ReadFile(path)
if err != nil {
return nil, fmt.Errorf("failed to read file: %s", err)
Expand All @@ -119,11 +119,10 @@ func (a DockerUserDataProvider) GetUserData(ctx context.Context) ([]byte, error)
}

func newProvider(ctx context.Context) (UserDataProvider, error) {

// This checks for the presence of a file and doesn't rely on http req like the
// azure, aws ones, thereby making it faster and hence checking this first
if isDockerContainer() {
return DockerUserDataProvider{}, nil
if hasUserDataFile() {
return FileUserDataProvider{}, nil
}

if isAzureVM() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
[Unit]
# mount configdisk if available
Wants=run-media-cidata.mount

[Service]
ExecStartPost=-/bin/bash -c 'tpm2_pcrextend 8:sha256=$(cat /run/peerpod/initdata.digest)'
ExecStartPost=-/bin/bash -c 'tpm2_pcrextend 8:sha384=$(cat /run/peerpod/initdata.digest)'
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[Unit]
Description=Mount cloud-config ISO with label 'cidata'
After=network.target

[Mount]
What=/dev/disk/by-label/cidata
Where=/run/media/cidata
Type=iso9660
Options=ro

[Install]
WantedBy=multi-user.target
6 changes: 3 additions & 3 deletions src/cloud-providers/docker/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ func (p *dockerProvider) CreateInstance(ctx context.Context, podName, sandboxID
return nil, err
}
// Write userdata to a file named after the instance name in the data directory
// File name: $data-dir/instanceName-userdata.json
// File name: $data-dir/instanceName-userdata
// File content: userdata
instanceUserdataFile, err := provider.WriteUserData(instanceName, userData, p.DataDir)
if err != nil {
Expand All @@ -72,12 +72,12 @@ func (p *dockerProvider) CreateInstance(ctx context.Context, podName, sandboxID

// Create volume binding for the container

// mount userdata to /peerpods/userdata.json
// mount userdata to /run/media/cidata/user-data
// This file will be read by process-user-data and daemon.json will be written to
// /run/peerpods/daemon.json at runtime
volumeBinding := []string{
// note: we are not importing that path from the CAA package to avoid circular dependencies
fmt.Sprintf("%s:%s", instanceUserdataFile, "/peerpods/userdata.json"),
fmt.Sprintf("%s:%s", instanceUserdataFile, "/run/media/cidata/user-data"),
}

// Add host bind mount for /run/kata-containers and /run/image to avoid
Expand Down
4 changes: 2 additions & 2 deletions src/cloud-providers/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ func DefaultToEnv(field *string, env, fallback string) {

func WriteUserData(instanceName string, userData string, dataDir string) (string, error) {
// Write userdata to a file named after the instance name in the dataDir directory
// File name: $dataDir/${instanceName}-userdata.json
// File name: $dataDir/${instanceName}-userdata
// File content: userdata

// Check if the dataDir directory exists
Expand All @@ -173,7 +173,7 @@ func WriteUserData(instanceName string, userData string, dataDir string) (string
}

// Create file path
filePath := filepath.Join(dataDir, instanceName+"-userdata.json")
filePath := filepath.Join(dataDir, instanceName+"-userdata")

// Write userdata to a file in the temp directory
err = os.WriteFile(filePath, []byte(userData), 0644)
Expand Down

0 comments on commit bf5c3fb

Please sign in to comment.