Skip to content

Commit

Permalink
cloud-config: add support for CDH config
Browse files Browse the repository at this point in the history
fixes #1720

This change will add a write_files entry to the cloud-config file that
is produced by CAA. aa-kbc-params are converted into a config file with
kbc name and kbc url.

process-user-data has been made more flexible to also support this
entry.

guest-components in versions.yaml has been updated to a new revision
that requires a cdh config file.

the kata-agent service unit has been extended to have the env
CDH_CONFIG_FILE=/run/confidential-containers/cdh.toml set, which is the
path that we add as a cloud-config directive.

guest-components are now being compiled with all attesters built-in by
default.

Signed-off-by: Magnus Kulke <magnuskulke@microsoft.com>
  • Loading branch information
mkulke committed Mar 15, 2024
1 parent e190fed commit 39cdd02
Show file tree
Hide file tree
Showing 9 changed files with 219 additions and 48 deletions.
5 changes: 4 additions & 1 deletion .github/workflows/azure-podvm-image-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -79,13 +79,16 @@ jobs:

- name: Install build dependencies
run: |
sudo curl -sL https://download.01.org/intel-sgx/sgx_repo/ubuntu/intel-sgx-deb.key | sudo gpg --dearmor --output /usr/share/keyrings/intel-sgx.gpg
sudo echo 'deb [arch=amd64 signed-by=/usr/share/keyrings/intel-sgx.gpg] https://download.01.org/intel-sgx/sgx_repo/ubuntu jammy main' | sudo tee /etc/apt/sources.list.d/intel-sgx.list
sudo apt-get update
sudo apt-get install -y \
clang \
gcc \
libdevmapper-dev \
libgpgme-dev \
libssl-dev \
libtdx-attest-dev \
libtss2-dev \
pkg-config \
protobuf-compiler
Expand All @@ -110,7 +113,7 @@ jobs:
rm -r "${GOPATH}/bin/yq"
- name: Build binaries
run: make binaries LIBC=gnu AA_KBC=cc_kbc_az_snp_vtpm
run: make binaries LIBC=gnu AA_KBC=cc_kbc

- uses: azure/login@v1
name: 'Az CLI login'
Expand Down
6 changes: 4 additions & 2 deletions cmd/process-user-data/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (

cmdUtil "github.com/confidential-containers/cloud-api-adaptor/cmd"
"github.com/confidential-containers/cloud-api-adaptor/pkg/agent"
"github.com/confidential-containers/cloud-api-adaptor/pkg/cdh"
daemon "github.com/confidential-containers/cloud-api-adaptor/pkg/forwarder"
"github.com/confidential-containers/cloud-api-adaptor/pkg/userdata"
"github.com/spf13/cobra"
Expand Down Expand Up @@ -36,17 +37,18 @@ var rootCmd = &cobra.Command{
}

func init() {
var agentConfigPath, daemonConfigPath string
var agentConfigPath, cdhConfigPath, daemonConfigPath string
var fetchTimeout int

rootCmd.PersistentFlags().BoolVarP(&versionFlag, "version", "v", false, "Print the version")
rootCmd.PersistentFlags().StringVarP(&daemonConfigPath, "daemon-config-path", "d", daemon.DefaultConfigPath, "Path to a daemon config file")
rootCmd.PersistentFlags().StringVarP(&cdhConfigPath, "cdh-config-path", "d", cdh.ConfigFilePath, "Path to a CDH config file")

var provisionFilesCmd = &cobra.Command{
Use: "provision-files",
Short: "Provision required files based on user data",
RunE: func(_ *cobra.Command, _ []string) error {
cfg := userdata.NewConfig(defaultAuthJsonPath, daemonConfigPath, fetchTimeout)
cfg := userdata.NewConfig(defaultAuthJsonPath, daemonConfigPath, cdhConfigPath, fetchTimeout)
return userdata.ProvisionFiles(cfg)
},
SilenceUsage: true, // Silence usage on error
Expand Down
12 changes: 12 additions & 0 deletions pkg/adaptor/cloud/cloud.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (

"github.com/confidential-containers/cloud-api-adaptor/pkg/adaptor/k8sops"
"github.com/confidential-containers/cloud-api-adaptor/pkg/adaptor/proxy"
"github.com/confidential-containers/cloud-api-adaptor/pkg/cdh"
"github.com/confidential-containers/cloud-api-adaptor/pkg/forwarder"
"github.com/confidential-containers/cloud-api-adaptor/pkg/podnetwork"
"github.com/confidential-containers/cloud-api-adaptor/pkg/util"
Expand Down Expand Up @@ -281,6 +282,17 @@ func (s *cloudService) CreateVM(ctx context.Context, req *pb.CreateVMRequest) (r
},
}

if s.aaKBCParams != "" {
toml, err := cdh.CreateConfigFile(s.aaKBCParams)
if err != nil {
return nil, fmt.Errorf("creating CDH config: %w", err)
}
cloudConfig.WriteFiles = append(cloudConfig.WriteFiles, cloudinit.WriteFile{
Path: cdh.ConfigFilePath,
Content: toml,
})
}

sandbox := &sandbox{
id: sid,
podName: pod,
Expand Down
45 changes: 45 additions & 0 deletions pkg/cdh/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package cdh

import (
"fmt"
"strings"

"github.com/pelletier/go-toml/v2"
)

const (
ConfigFilePath = "/run/confidential-containers/cdh.toml"
Socket = "unix://run/confidential-containers/cdh.sock"
)

type Config struct {
Socket string `toml:"socket"`
KBC KBCConfig `toml:"kbc"`
}

type KBCConfig struct {
Name string `toml:"name"`
URL string `toml:"url"`
}

func parseAAKBCParams(aaKBCParams string) (*Config, error) {
parts := strings.SplitN(aaKBCParams, "::", 2)
if len(parts) != 2 {
return nil, fmt.Errorf("Invalid aa-kbs-params input: %s", aaKBCParams)
}
name, url := parts[0], parts[1]
kbcConfig := KBCConfig{name, url}
return &Config{Socket, kbcConfig}, nil
}

func CreateConfigFile(aaKBCParams string) (string, error) {
config, err := parseAAKBCParams(aaKBCParams)
if err != nil {
return "", err
}
bytes, err := toml.Marshal(config)
if err != nil {
return "", err
}
return string(bytes), nil
}
38 changes: 38 additions & 0 deletions pkg/cdh/config_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package cdh

import (
"fmt"
"testing"

"github.com/pelletier/go-toml/v2"
)

func TestCDHConfigFileFromAAKBCParams(t *testing.T) {
refdoc := `
socket = "%s"
[kbc]
name = "cc_kbc"
url = "http://1.2.3.4:8080"
`
refdoc = fmt.Sprintf(refdoc, Socket)
var refcfg Config
err := toml.Unmarshal([]byte(refdoc), &refcfg)
if err != nil {
panic(err)
}

config, err := parseAAKBCParams("cc_kbc::http://1.2.3.4:8080")
if err != nil {
t.Error(err)
}

if config.KBC.Name != refcfg.KBC.Name {
t.Errorf("Expected %s, got %s", refcfg.KBC.Name, config.KBC.Name)
}
if config.KBC.URL != refcfg.KBC.URL {
t.Errorf("Expected %s, got %s", refcfg.KBC.URL, config.KBC.URL)
}
if config.Socket != refcfg.Socket {
t.Errorf("Expected %s, got %s", refcfg.Socket, config.Socket)
}
}
46 changes: 28 additions & 18 deletions pkg/userdata/provision.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,20 @@ import (

var logger = log.New(log.Writer(), "[userdata/provision] ", log.LstdFlags|log.Lmsgprefix)

type paths struct {
authJson string
cdhConfig string
daemonConfig string
}

type Config struct {
authJsonPath string
daemonConfigPath string
fetchTimeout int
fetchTimeout int
paths paths
}

func NewConfig(authJsonPath, daemonConfigPath string, fetchTimeout int) *Config {
return &Config{authJsonPath, daemonConfigPath, fetchTimeout}
func NewConfig(authJsonPath, daemonConfigPath, cdhConfig string, fetchTimeout int) *Config {
cfgPaths := paths{authJsonPath, cdhConfig, daemonConfigPath}
return &Config{fetchTimeout, cfgPaths}
}

type WriteFile struct {
Expand Down Expand Up @@ -127,19 +133,14 @@ func parseDaemonConfig(content []byte) (*daemon.Config, error) {
return &dc, nil
}

func findDaemonConfigEntry(path string, cc *CloudConfig) (*daemon.Config, []byte, error) {
func findConfigEntry(path string, cc *CloudConfig) []byte {
for _, wf := range cc.WriteFiles {
if wf.Path != path {
continue
}
bytes := []byte(wf.Content)
daemonConfig, err := parseDaemonConfig(bytes)
if err != nil {
return nil, nil, err
}
return daemonConfig, bytes, nil
return []byte(wf.Content)
}
return nil, nil, fmt.Errorf("failed to find entry for %s in cloud config", path)
return nil
}

func writeFile(path string, bytes []byte) error {
Expand All @@ -152,18 +153,27 @@ func writeFile(path string, bytes []byte) error {
}

func processCloudConfig(cfg *Config, cc *CloudConfig) error {
daemonConfig, bytes, err := findDaemonConfigEntry(cfg.daemonConfigPath, cc)
bytes := findConfigEntry(cfg.paths.daemonConfig, cc)
if bytes == nil {
return fmt.Errorf("failed to find daemon config entry in cloud config")
}
daemonConfig, err := parseDaemonConfig(bytes)
if err != nil {
return fmt.Errorf("failed to process daemon config: %w", err)
return fmt.Errorf("failed to parse daemon config: %w", err)
}

if err = writeFile(cfg.daemonConfigPath, bytes); err != nil {
if err = writeFile(cfg.paths.daemonConfig, bytes); err != nil {
return fmt.Errorf("failed to write daemon config file: %w", err)
}

if bytes := findConfigEntry(cfg.paths.cdhConfig, cc); bytes != nil {
if err = writeFile(cfg.paths.cdhConfig, bytes); err != nil {
return fmt.Errorf("failed to write cdh config file: %w", err)
}
}

if daemonConfig.AuthJson != "" {
bytes := []byte(daemonConfig.AuthJson)
if err = writeFile(cfg.authJsonPath, bytes); err != nil {
if err = writeFile(cfg.paths.authJson, bytes); err != nil {
return fmt.Errorf("failed to write auth json file: %w", err)
}
}
Expand Down
Loading

0 comments on commit 39cdd02

Please sign in to comment.