Skip to content

Commit

Permalink
implement mos boot and support simple service network
Browse files Browse the repository at this point in the history
Closes #4
Closes #7

Implement 'mos boot' which activates all services.

Implement a 'simple' network type for services, which
isolates a service in a netns with a simple veth on the
lxcbr0, with specified host ports forwarded into the
container.

layers/install: add a zot service layer which uses the
simple network.

update to v0.0.17 bootkit for 4M firmware
kvm provider: specify bootindex 'off' for nics
add a hidden subcommand to verify an install.yaml

Signed-off-by: Serge Hallyn <[email protected]>
  • Loading branch information
hallyn committed Oct 28, 2023
1 parent d02b04f commit bba830c
Show file tree
Hide file tree
Showing 24 changed files with 481 additions and 34 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ jobs:
file: 'layers/stacker.yaml'
build-args: |
ZOT_VERSION=2.0.0-rc5
ROOTFS_VERSION=v0.0.15.230901
ROOTFS_VERSION=v0.0.17.231018
url: docker://zothub.io/machine/bootstrap
tags: ${{ github.event.release.tag_name }}
username: ${{ secrets.ZOTHUB_USERNAME }}
Expand Down
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ ORAS_VERSION := 1.0.0-rc.1
REGCTL := $(TOOLSDIR)/bin/regctl
REGCTL_VERSION := 0.5.0
TOPDIR := $(shell git rev-parse --show-toplevel)
BOOTKIT_VERSION ?= "v0.0.15.230901"
BOOTKIT_VERSION ?= "v0.0.17.231018"
ROOTFS_VERSION = $(BOOTKIT_VERSION)

archout = $(shell arch)
Expand All @@ -33,7 +33,7 @@ all: mosctl mosb trust $(ZOT) $(ORAS) $(REGCTL)

VERSION_LDFLAGS=-X github.com/project-machine/mos/pkg/mosconfig.Version=$(MAIN_VERSION) \
-X github.com/project-machine/mos/pkg/trust.Version=$(MAIN_VERSION) \
-X github.com/project-machine/mos/pkg/mosconfig.LayerVersion=0.0.3 \
-X github.com/project-machine/mos/pkg/mosconfig.LayerVersion=0.0.4 \
-X github.com/project-machine/mos/pkg/trust.BootkitVersion=$(BOOTKIT_VERSION)

mosctl: .made-gofmt $(GO_SRC)
Expand Down
30 changes: 30 additions & 0 deletions cmd/mosb/main.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
package main

import (
"fmt"
"os"

"github.com/apex/log"
"github.com/project-machine/mos/pkg/mosconfig"
"github.com/urfave/cli"
"gopkg.in/yaml.v2"
)

func main() {
Expand All @@ -16,6 +18,7 @@ func main() {
manifestCmd,
mkBootCmd,
mkProvisionCmd,
readSpec,
}
app.Flags = []cli.Flag{
cli.BoolFlag{
Expand All @@ -35,3 +38,30 @@ func main() {
log.Fatalf("%v\n", err)
}
}

var readSpec = cli.Command{
Name: "readspec",
Usage: "read a manifest.yaml and print out resulting struct",
Action: doReadSpec,
Hidden: true,
UsageText: `in-file
in-file: file to read`,
}

func doReadSpec(ctx *cli.Context) error {
args := ctx.Args()
if len(args) < 1 {
return fmt.Errorf("input file is a required positional argument")
}

bytes, err := os.ReadFile(args[0])
if err != nil {
return err
}
var manifest mosconfig.ImportFile
if err = yaml.Unmarshal(bytes, &manifest); err != nil {
return err
}
fmt.Printf("result: %#v", manifest)
return nil
}
28 changes: 28 additions & 0 deletions cmd/mosctl/boot.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package main

import (
"github.com/pkg/errors"
"github.com/project-machine/mos/pkg/mosconfig"
"github.com/urfave/cli"
)

var bootCmd = cli.Command{
Name: "boot",
Usage: "start all services listed in mos manifest",
Action: doBootCmd,
}

func doBootCmd(ctx *cli.Context) error {
opts := mosconfig.DefaultMosOptions()
mos, err := mosconfig.OpenMos(opts)
if err != nil {
return errors.Wrapf(err, "Failed opening mos")
}

err = mos.Boot()
if err != nil {
return errors.Wrapf(err, "Failed to boot")
}

return nil
}
1 change: 1 addition & 0 deletions cmd/mosctl/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ func main() {
app.Commands = []cli.Command{
createBootFsCmd,
activateCmd,
bootCmd,
installCmd,
mountCmd,
updateCmd,
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ require (
github.com/opencontainers/umoci v0.4.8-0.20220412065115-12453f247749
github.com/pkg/errors v0.9.1
github.com/plus3it/gorecurcopy v0.0.1
github.com/project-machine/bootkit v0.0.15
github.com/project-machine/bootkit v0.0.0-20230906152517-964838ab8d93
github.com/project-machine/machine v0.1.2
github.com/project-stacker/stacker v0.21.2
github.com/rekby/gpt v0.0.0-20200219180433-a930afbc6edc
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -2691,8 +2691,8 @@ github.com/pquerna/cachecontrol v0.1.0/go.mod h1:NrUG3Z7Rdu85UNR3vm7SOsl1nFIeSiQ
github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U=
github.com/proglottis/gpgme v0.1.3 h1:Crxx0oz4LKB3QXc5Ea0J19K/3ICfy3ftr5exgUK1AU0=
github.com/proglottis/gpgme v0.1.3/go.mod h1:fPbW/EZ0LvwQtH8Hy7eixhp1eF3G39dtx7GUN+0Gmy0=
github.com/project-machine/bootkit v0.0.15 h1:EAeilYMiBnsliLc+3BejqIwN8seir2fQ8aL8Lg93mkY=
github.com/project-machine/bootkit v0.0.15/go.mod h1:02BdQ6/ClxWdwPOIVYxpRNJIJD2eFcg8iz2Q1phJchU=
github.com/project-machine/bootkit v0.0.0-20230906152517-964838ab8d93 h1:OfYRKrxfjxyYUOUNCY8bpNaEhE6xk4QcZb+1rRfZmaw=
github.com/project-machine/bootkit v0.0.0-20230906152517-964838ab8d93/go.mod h1:02BdQ6/ClxWdwPOIVYxpRNJIJD2eFcg8iz2Q1phJchU=
github.com/project-machine/machine v0.1.2 h1:/detDExvftlN+PvJWP57tUS6NFLPtHWc+m3b4/NhFq4=
github.com/project-machine/machine v0.1.2/go.mod h1:pjru0EkLoBhdLQ1szLxJIqiMkUgezdwMjsaq/ijBZOw=
github.com/project-machine/qcli v0.2.1 h1:rIRItjdkeBbD4NIxYyTkxCeJIolGHdniJ51Phfg2Ols=
Expand Down
16 changes: 16 additions & 0 deletions layers/install/load-mos-modules
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#!/bin/bash

mountpoint /lib/modules && { echo "already mounted"; exit 0; }

mkdir -p /bootkit
mosctl --debug mount --target=bootkit --dest=/bootkit
mkdir -p /lib/modules
mount /bootkit/bootkit/modules.squashfs /lib/modules/

udevadm trigger
modprobe virtio-net
modprobe br_netfilter
modprobe iptables_nat
modprobe iptables_mangle
dhclient
systemctl start lxc-net
18 changes: 18 additions & 0 deletions layers/install/mos-boot-setup.service
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
[Unit]
Description=mos-boot-setup
After=local-fs.target
After=systemd-journal-flush.service logs.mount
Requires=local-fs.target
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/bin/mosctl boot
StandardOutput=journal+console
StandardError=journal+console

# Journal namespaces implementation also affects the mount namespaces.
# Assigning a separate journal namespace to Atomix process hides mount points
# like /config and /tmp from the "main" user namespace.
# LogNamespace=atomix
[Install]
WantedBy=multi-user.target
12 changes: 12 additions & 0 deletions layers/install/mos-modules.service
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[Unit]
Description=Load mos modules
After=local-fs.target

[Service]
Type=oneshot
RemainAfterExit=true
ExecStart=/usr/bin/load-mos-modules
StandardOutput=journal+console

[Install]
WantedBy=multi-user.target
34 changes: 34 additions & 0 deletions layers/install/stacker.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ install-rootfs-pkg:
cryptsetup \
dosfstools \
e2fsprogs \
efibootmgr \
iproute2 \
isc-dhcp-client \
keyutils \
Expand All @@ -37,6 +38,25 @@ install-rootfs-pkg:
DHCP=yes
END
demo-zot:
from:
type: built
tag: install-rootfs-pkg
import:
- zot-config.json
- start-zot
- https://github.com/project-zot/zot/releases/download/v${{ZOT_VERSION}}/zot-linux-amd64-minimal
entrypoint: /usr/bin/start-zot
run: |
#!/bin/sh -ex
cp /stacker/imports/zot-config.json /etc/
cp /stacker/imports/start-zot /usr/bin/start-zot
chmod 755 /usr/bin/start-zot
cp /stacker/imports/zot-linux-amd64-minimal /usr/bin/zot
chmod 755 /usr/bin/zot
# The rootfs which we want to run on the system
# Note this is for demo purposes only. No one should ever
# use this as the target layer.
Expand All @@ -47,6 +67,9 @@ demo-target-rootfs:
import:
- ../../mosctl
- ../provision/console-helper
- load-mos-modules
- mos-modules.service
- mos-boot-setup.service
run: |
#!/bin/sh -ex
writefile() {
Expand All @@ -68,10 +91,21 @@ demo-target-rootfs:
DHCP=yes
END
# lxc needed for mosctl to activate a service \\
# git needed for mosctl to read manifest
pkgtool install git lxc
cd /stacker/imports
cp mosctl console-helper /usr/bin
( cd /usr/bin && chmod 755 mosctl console-helper )
cp /stacker/imports/load-mos-modules /usr/bin/
chmod 755 /usr/bin/load-mos-modules
cp /stacker/imports/mos-modules.service /etc/systemd/system/
systemctl enable mos-modules.service
cp /stacker/imports/mos-boot-setup.service /etc/systemd/system
systemctl enable mos-boot-setup.service
echo root:passw0rd | chpasswd
systemctl enable serial-getty@ttyS0
annotations:
Expand Down
12 changes: 12 additions & 0 deletions layers/install/start-zot
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#!/bin/bash

if [ -n "$IPV4" ]; then
sed -i "s/0.0.0.0/${IPV4%/*}/" /etc/zot-config.json
elif [ -n "$IPV6" ]; then
sed -i "s/0.0.0.0/${IPV6%/*}/" /etc/zot-config.json
fi

# Should mos or lxc be doing this for us?
ip route add default via 10.0.3.1

exec /usr/bin/zot serve /etc/zot-config.json
14 changes: 14 additions & 0 deletions layers/install/zot-config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"distSpecVersion": "1.0.1-dev",
"storage": {
"rootDirectory": "/zot",
"gc": false
},
"http": {
"address": "0.0.0.0",
"port": "5000"
},
"log": {
"level": "error"
}
}
24 changes: 21 additions & 3 deletions pkg/mosconfig/files.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,24 @@ const CurrentInstallFileVersion = 1
type TargetNetworkType string

const (
HostNetwork TargetNetworkType = "host"
NoNetwork TargetNetworkType = "none"
HostNetwork TargetNetworkType = "host"
NoNetwork TargetNetworkType = "none"
SimpleNetwork TargetNetworkType = "simple"
)

// Target Network configuration
// Type dictates which type
// Address is an ipv4 or ipv6 address.
// Ports are ipfilter rules to allow inbound masq.
//
// We will likely want to change this to an array of
// nics, like lxc.net.[i].*. But for now let's just
// support one
type TargetNetwork struct {
Type TargetNetworkType `json:"type"`
Type TargetNetworkType `json:"type" yaml:"type"`
Address string `json:"ipv4" yaml:"ipv4"`
Address6 string `json:"ipv6" yaml:"ipv6"`
Ports []SimplePort `json:"ports" yaml:"ports"`
}

// Service type defines how a service is run.
Expand Down Expand Up @@ -126,8 +138,14 @@ func (s *SysTargets) Contains(needle SysTarget) (SysTarget, bool) {
}

type SysManifest struct {
// Persistent stored information
UidMaps []IdmapSet `json:"uidmaps"`
SysTargets []SysTarget `json:"targets"`

// Runtime information
DefaultNic string
UsedPorts map[uint]string // map of hostport -> running target name
IpAddrs map[string]string // map of ip4 ip6 addr -> running target name
}

func (sm *SysManifest) GetTarget(target string) (*SysTarget, error) {
Expand Down
2 changes: 2 additions & 0 deletions pkg/mosconfig/manifest.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,8 @@ func (mos *Mos) initManifest(manifestPath, manifestCert, manifestCA, configPath
sysmanifest := SysManifest{
UidMaps: uidmaps,
SysTargets: targets,
UsedPorts: make(map[uint]string),
IpAddrs: make(map[string]string),
}

bytes, err := json.Marshal(&sysmanifest)
Expand Down
Loading

0 comments on commit bba830c

Please sign in to comment.