mirror of
https://github.com/kairos-io/immucore.git
synced 2025-04-27 11:12:30 +00:00
Initial import
This commit is contained in:
parent
17b12a535e
commit
2b6de44b9d
3
README.md
Normal file
3
README.md
Normal file
@ -0,0 +1,3 @@
|
||||
# immucore
|
||||
|
||||
The Kairos immutability management interface
|
25
go.mod
Normal file
25
go.mod
Normal file
@ -0,0 +1,25 @@
|
||||
module github.com/kairos-io/immucore
|
||||
|
||||
go 1.19
|
||||
|
||||
require (
|
||||
github.com/containerd/containerd v1.6.15
|
||||
github.com/deniswernert/go-fstab v0.0.0-20141204152952-eb4090f26517
|
||||
github.com/moby/sys/mountinfo v0.5.0
|
||||
github.com/urfave/cli v1.22.10
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/Microsoft/go-winio v0.5.2 // indirect
|
||||
github.com/Microsoft/hcsshim v0.9.6 // indirect
|
||||
github.com/containerd/cgroups v1.0.4 // indirect
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0 // indirect
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/russross/blackfriday/v2 v2.0.1 // indirect
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect
|
||||
github.com/sirupsen/logrus v1.8.1 // indirect
|
||||
go.opencensus.io v0.23.0 // indirect
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f // indirect
|
||||
)
|
25
internal/cmd/commands.go
Normal file
25
internal/cmd/commands.go
Normal file
@ -0,0 +1,25 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"github.com/kairos-io/immucore/pkg/mount"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
var Commands = []cli.Command{
|
||||
|
||||
{
|
||||
Name: "load",
|
||||
Usage: "notify <event> <config dir>...",
|
||||
UsageText: "emits the given event with a generic event payload",
|
||||
Description: `
|
||||
Sends a generic event payload with the configuration found in the scanned directories.
|
||||
`,
|
||||
Aliases: []string{},
|
||||
Flags: []cli.Flag{},
|
||||
Action: func(c *cli.Context) error {
|
||||
|
||||
mount.MountOverlayFS()
|
||||
return nil
|
||||
},
|
||||
},
|
||||
}
|
32
main.go
Normal file
32
main.go
Normal file
@ -0,0 +1,32 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/kairos-io/immucore/internal/cmd"
|
||||
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
// Apply Immutability profiles.
|
||||
func main() {
|
||||
app := &cli.App{
|
||||
Name: "immucore",
|
||||
Version: "0.1",
|
||||
Author: "Kairos authors",
|
||||
Usage: "kairos agent start",
|
||||
Description: `
|
||||
`,
|
||||
UsageText: ``,
|
||||
Copyright: "kairos authors",
|
||||
|
||||
Commands: cmd.Commands,
|
||||
}
|
||||
|
||||
err := app.Run(os.Args)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
182
pkg/mount/mount.go
Normal file
182
pkg/mount/mount.go
Normal file
@ -0,0 +1,182 @@
|
||||
package mount
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/containerd/containerd/mount"
|
||||
"github.com/deniswernert/go-fstab"
|
||||
"github.com/kairos-io/immucore/pkg/profile"
|
||||
"github.com/moby/sys/mountinfo"
|
||||
)
|
||||
|
||||
func MountOverlayFS() {
|
||||
mount.All([]mount.Mount{}, "foo")
|
||||
}
|
||||
|
||||
// https://github.com/kairos-io/packages/blob/94aa3bef3d1330cb6c6905ae164f5004b6a58b8c/packages/system/dracut/immutable-rootfs/30cos-immutable-rootfs/cos-mount-layout.sh#L129
|
||||
func BaseOverlay(overlay profile.Overlay) (fstab.Mount, error) {
|
||||
if err := os.MkdirAll(overlay.Base, 0700); err != nil {
|
||||
return fstab.Mount{}, err
|
||||
}
|
||||
|
||||
dat := strings.Split(overlay.BackingBase, ":")
|
||||
|
||||
if len(dat) != 2 {
|
||||
return fstab.Mount{}, fmt.Errorf("invalid backing base. must be a tmpfs with a size or a block device. e.g. tmpfs:30%%, block:/dev/sda1. Input: %s", overlay.BackingBase)
|
||||
}
|
||||
|
||||
t := dat[0]
|
||||
switch t {
|
||||
case "tmpfs":
|
||||
tmpMount := mount.Mount{Type: "tmpfs", Source: "tmpfs", Options: []string{"defaults", fmt.Sprintf("size=%s", dat[1])}}
|
||||
err := mount.All([]mount.Mount{tmpMount}, overlay.Base)
|
||||
|
||||
fstab := mountToStab(tmpMount)
|
||||
fstab.File = overlay.BackingBase
|
||||
|
||||
return *fstab, err
|
||||
case "block":
|
||||
blockMount := mount.Mount{Type: "auto", Source: dat[1]}
|
||||
err := mount.All([]mount.Mount{blockMount}, overlay.Base)
|
||||
|
||||
fstab := mountToStab(blockMount)
|
||||
fstab.File = overlay.BackingBase
|
||||
fstab.MntOps["default"] = ""
|
||||
|
||||
return *fstab, err
|
||||
default:
|
||||
return fstab.Mount{}, fmt.Errorf("invalid overlay backing base type")
|
||||
}
|
||||
}
|
||||
|
||||
func mountToStab(m mount.Mount) *fstab.Mount {
|
||||
opts := map[string]string{}
|
||||
for _, o := range m.Options {
|
||||
if strings.Contains(o, "=") {
|
||||
dat := strings.Split(o, "=")
|
||||
key := dat[0]
|
||||
value := dat[1]
|
||||
opts[key] = value
|
||||
} else {
|
||||
opts[o] = ""
|
||||
}
|
||||
}
|
||||
return &fstab.Mount{
|
||||
Spec: m.Source,
|
||||
VfsType: m.Type,
|
||||
MntOps: opts,
|
||||
Freq: 0,
|
||||
PassNo: 0,
|
||||
}
|
||||
}
|
||||
|
||||
func MountEphemeral(path []string) {
|
||||
|
||||
}
|
||||
|
||||
func MountPeristentPaths() {
|
||||
|
||||
}
|
||||
|
||||
func createIfNotExists(path string) error {
|
||||
if _, err := os.Stat(path); os.IsNotExist(err) {
|
||||
return os.MkdirAll(path, os.ModePerm)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func appendSlash(path string) string {
|
||||
if !strings.HasSuffix(path, "/") {
|
||||
return fmt.Sprintf("%s/", path)
|
||||
}
|
||||
|
||||
return path
|
||||
}
|
||||
|
||||
// https://github.com/kairos-io/packages/blob/94aa3bef3d1330cb6c6905ae164f5004b6a58b8c/packages/system/dracut/immutable-rootfs/30cos-immutable-rootfs/cos-mount-layout.sh#L183
|
||||
func mountBind(mountpoint, root, stateTarget string) (fstab.Mount, error) {
|
||||
mountpoint = strings.TrimLeft(mountpoint, "/") // normalize, remove / upfront as we are going to re-use it in subdirs
|
||||
rootMount := filepath.Join(root, mountpoint)
|
||||
bindMountPath := strings.ReplaceAll(mountpoint, "/", "-")
|
||||
|
||||
stateDir := filepath.Join(root, stateTarget, fmt.Sprintf("%s.bind", bindMountPath))
|
||||
|
||||
if mounted, _ := mountinfo.Mounted(rootMount); !mounted {
|
||||
if err := createIfNotExists(rootMount); err != nil {
|
||||
return fstab.Mount{}, err
|
||||
}
|
||||
|
||||
if err := createIfNotExists(stateDir); err != nil {
|
||||
return fstab.Mount{}, err
|
||||
}
|
||||
|
||||
syncState(appendSlash(rootMount), appendSlash(stateDir))
|
||||
|
||||
tmpMount := mount.Mount{
|
||||
Type: "overlay",
|
||||
Source: stateDir,
|
||||
|
||||
Options: []string{
|
||||
"defaults",
|
||||
"bind",
|
||||
},
|
||||
}
|
||||
err := mount.All([]mount.Mount{tmpMount}, rootMount)
|
||||
if err != nil {
|
||||
return fstab.Mount{}, err
|
||||
}
|
||||
|
||||
fstab := mountToStab(tmpMount)
|
||||
fstab.File = fmt.Sprintf("/%s", mountpoint)
|
||||
fstab.Spec = strings.ReplaceAll(fstab.Spec, root, "")
|
||||
|
||||
}
|
||||
return fstab.Mount{}, fmt.Errorf("already mounted")
|
||||
}
|
||||
|
||||
func syncState(src, dst string) error {
|
||||
return exec.Command("rsync", "-aqAX", src, dst).Run()
|
||||
}
|
||||
|
||||
// https://github.com/kairos-io/packages/blob/94aa3bef3d1330cb6c6905ae164f5004b6a58b8c/packages/system/dracut/immutable-rootfs/30cos-immutable-rootfs/cos-mount-layout.sh#L145
|
||||
func mountWithBaseOverlay(mountpoint, root, base string) (fstab.Mount, error) {
|
||||
mountpoint = strings.TrimLeft(mountpoint, "/") // normalize, remove / upfront as we are going to re-use it in subdirs
|
||||
rootMount := filepath.Join(root, mountpoint)
|
||||
bindMountPath := strings.ReplaceAll(mountpoint, "/", "-")
|
||||
|
||||
createIfNotExists(rootMount)
|
||||
if mounted, _ := mountinfo.Mounted(rootMount); !mounted {
|
||||
upperdir := filepath.Join(base, bindMountPath, ".overlay", "upper")
|
||||
workdir := filepath.Join(base, bindMountPath, ".overlay", "work")
|
||||
// Make sure workdir and/or upper exists
|
||||
os.MkdirAll(upperdir, os.ModePerm)
|
||||
os.MkdirAll(workdir, os.ModePerm)
|
||||
|
||||
tmpMount := mount.Mount{
|
||||
Type: "overlay",
|
||||
Source: "overlay",
|
||||
Options: []string{
|
||||
"defaults",
|
||||
fmt.Sprintf("lowerdir=%s", rootMount),
|
||||
fmt.Sprintf("upperdir=%s", upperdir),
|
||||
fmt.Sprintf("workdir=%s", workdir),
|
||||
},
|
||||
}
|
||||
err := mount.All([]mount.Mount{tmpMount}, rootMount)
|
||||
|
||||
fstab := mountToStab(tmpMount)
|
||||
fstab.File = rootMount
|
||||
|
||||
// TODO: update fstab with x-systemd info
|
||||
// https://github.com/kairos-io/packages/blob/94aa3bef3d1330cb6c6905ae164f5004b6a58b8c/packages/system/dracut/immutable-rootfs/30cos-immutable-rootfs/cos-mount-layout.sh#L170
|
||||
|
||||
return *fstab, err
|
||||
}
|
||||
|
||||
return fstab.Mount{}, fmt.Errorf("already mounted")
|
||||
}
|
32
pkg/prepare/overlay.go
Normal file
32
pkg/prepare/overlay.go
Normal file
@ -0,0 +1,32 @@
|
||||
package prepare
|
||||
|
||||
/*
|
||||
func hasMountpoint(path string, mounts []string) bool {
|
||||
for _, mount := range mounts {
|
||||
if strings.HasSuffix(mount, path) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func getStateMountpoints(statePaths []string, mountpoints []string) string {
|
||||
var stateMounts string
|
||||
for _, path := range statePaths {
|
||||
if !hasMountpoint(path, mountpoints) {
|
||||
stateMounts += path + " "
|
||||
}
|
||||
}
|
||||
return stateMounts
|
||||
}
|
||||
func getOverlayMountpoints(rwPaths []string, mounts []string) string {
|
||||
var mountpoints string
|
||||
|
||||
for _, path := range rwPaths {
|
||||
if !hasMountpoint(path, mounts) {
|
||||
mountpoints += path + ":overlay "
|
||||
}
|
||||
}
|
||||
return mountpoints
|
||||
}
|
||||
*/
|
7
pkg/profile/loader.go
Normal file
7
pkg/profile/loader.go
Normal file
@ -0,0 +1,7 @@
|
||||
package profile
|
||||
|
||||
func Apply() {
|
||||
// Load all profiles
|
||||
// Apply mounts
|
||||
// Apply configurations to sysroot (/) or (/sysroot)
|
||||
}
|
4
pkg/profile/mount.go
Normal file
4
pkg/profile/mount.go
Normal file
@ -0,0 +1,4 @@
|
||||
package profile
|
||||
|
||||
// profile.Mount mounts a profile to the system.
|
||||
func Mount()
|
15
pkg/profile/profile.go
Normal file
15
pkg/profile/profile.go
Normal file
@ -0,0 +1,15 @@
|
||||
package profile
|
||||
|
||||
type Layout struct {
|
||||
Overlay Overlay
|
||||
OEMLabel string
|
||||
//https://github.com/kairos-io/packages/blob/94aa3bef3d1330cb6c6905ae164f5004b6a58b8c/packages/system/dracut/immutable-rootfs/30cos-immutable-rootfs/cos-generator.sh#L71
|
||||
Mounts []string
|
||||
}
|
||||
|
||||
type Overlay struct {
|
||||
// /run/overlay
|
||||
Base string
|
||||
// https://github.com/kairos-io/packages/blob/94aa3bef3d1330cb6c6905ae164f5004b6a58b8c/packages/system/dracut/immutable-rootfs/30cos-immutable-rootfs/cos-generator.sh#L22
|
||||
BackingBase string
|
||||
}
|
Loading…
Reference in New Issue
Block a user