mirror of
https://github.com/containers/podman.git
synced 2025-06-20 00:51:16 +08:00
Use parser.UnitFile
Uses the systemd unit file parser to build unit files instead of having them be just blocks of hard-coded strings. Signed-off-by: Jake Correnti <jakecorrenti+github@proton.me>
This commit is contained in:
@ -26,6 +26,7 @@ import (
|
|||||||
"github.com/containers/podman/v4/pkg/machine/vmconfigs"
|
"github.com/containers/podman/v4/pkg/machine/vmconfigs"
|
||||||
"github.com/containers/podman/v4/pkg/machine/ignition"
|
"github.com/containers/podman/v4/pkg/machine/ignition"
|
||||||
"github.com/containers/podman/v4/pkg/strongunits"
|
"github.com/containers/podman/v4/pkg/strongunits"
|
||||||
|
"github.com/containers/podman/v4/pkg/systemd/parser"
|
||||||
"github.com/containers/podman/v4/pkg/util"
|
"github.com/containers/podman/v4/pkg/util"
|
||||||
"github.com/containers/podman/v4/utils"
|
"github.com/containers/podman/v4/utils"
|
||||||
"github.com/containers/storage/pkg/lockfile"
|
"github.com/containers/storage/pkg/lockfile"
|
||||||
@ -46,21 +47,13 @@ const (
|
|||||||
apiUpTimeout = 20 * time.Second
|
apiUpTimeout = 20 * time.Second
|
||||||
)
|
)
|
||||||
|
|
||||||
// appleHVReadyUnit is a unit file that sets up the virtual serial device
|
// VfkitHelper describes the use of vfkit: cmdline and endpoint
|
||||||
// where when the VM is done configuring, it will send an ack
|
type VfkitHelper struct {
|
||||||
// so a listening host knows it can begin interacting with it
|
LogLevel logrus.Level
|
||||||
const appleHVReadyUnit = `[Unit]
|
Endpoint string
|
||||||
Requires=dev-virtio\\x2dports-%s.device
|
VfkitBinaryPath *define.VMFile
|
||||||
After=remove-moby.service sshd.socket sshd.service
|
VirtualMachine *vfConfig.VirtualMachine
|
||||||
OnFailure=emergency.target
|
}
|
||||||
OnFailureJobMode=isolate
|
|
||||||
[Service]
|
|
||||||
Type=oneshot
|
|
||||||
RemainAfterExit=yes
|
|
||||||
ExecStart=/bin/sh -c '/usr/bin/echo Ready | socat - VSOCK-CONNECT:2:1025'
|
|
||||||
[Install]
|
|
||||||
RequiredBy=default.target
|
|
||||||
`
|
|
||||||
|
|
||||||
type MacMachine struct {
|
type MacMachine struct {
|
||||||
// ConfigPath is the fully qualified path to the configuration file
|
// ConfigPath is the fully qualified path to the configuration file
|
||||||
@ -274,10 +267,15 @@ func (m *MacMachine) Init(opts machine.InitOptions) (bool, error) {
|
|||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
readyUnitFile, err := createReadyUnitFile()
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
builder.WithUnit(ignition.Unit{
|
builder.WithUnit(ignition.Unit{
|
||||||
Enabled: ignition.BoolToPtr(true),
|
Enabled: ignition.BoolToPtr(true),
|
||||||
Name: "ready.service",
|
Name: "ready.service",
|
||||||
Contents: ignition.StrToPtr(fmt.Sprintf(appleHVReadyUnit, "vsock")),
|
Contents: ignition.StrToPtr(readyUnitFile),
|
||||||
})
|
})
|
||||||
builder.WithUnit(generateSystemDFilesForVirtiofsMounts(virtiofsMnts)...)
|
builder.WithUnit(generateSystemDFilesForVirtiofsMounts(virtiofsMnts)...)
|
||||||
|
|
||||||
@ -288,6 +286,13 @@ func (m *MacMachine) Init(opts machine.InitOptions) (bool, error) {
|
|||||||
return err == nil, err
|
return err == nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func createReadyUnitFile() (string, error) {
|
||||||
|
readyUnit := ignition.DefaultReadyUnitFile()
|
||||||
|
readyUnit.Add("Unit", "Requires", "dev-virtio\\x2dports-vsock.device")
|
||||||
|
readyUnit.Add("Service", "ExecStart", "/bin/sh -c '/usr/bin/echo Ready | socat - VSOCK-CONNECT:2:1025'")
|
||||||
|
return readyUnit.ToString()
|
||||||
|
}
|
||||||
|
|
||||||
func (m *MacMachine) removeSSHKeys() error {
|
func (m *MacMachine) removeSSHKeys() error {
|
||||||
if err := os.Remove(fmt.Sprintf("%s.pub", m.IdentityPath)); err != nil {
|
if err := os.Remove(fmt.Sprintf("%s.pub", m.IdentityPath)); err != nil {
|
||||||
logrus.Error(err)
|
logrus.Error(err)
|
||||||
@ -1111,31 +1116,34 @@ func generateSystemDFilesForVirtiofsMounts(mounts []machine.VirtIoFs) []ignition
|
|||||||
// Here we are looping the mounts and for each mount, we are adding two unit files
|
// Here we are looping the mounts and for each mount, we are adding two unit files
|
||||||
// for virtiofs. One unit file is the mount itself and the second is to automount it
|
// for virtiofs. One unit file is the mount itself and the second is to automount it
|
||||||
// on boot.
|
// on boot.
|
||||||
autoMountUnit := `[Automount]
|
autoMountUnit := parser.NewUnitFile()
|
||||||
Where=%s
|
autoMountUnit.Add("Automount", "Where", "%s")
|
||||||
[Install]
|
autoMountUnit.Add("Install", "WantedBy", "multi-user.target")
|
||||||
WantedBy=multi-user.target
|
autoMountUnit.Add("Unit", "Description", "Mount virtiofs volume %s")
|
||||||
|
autoMountUnitFile, err := autoMountUnit.ToString()
|
||||||
|
if err != nil {
|
||||||
|
logrus.Warnf(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
[Unit]
|
mountUnit := parser.NewUnitFile()
|
||||||
Description=Mount virtiofs volume %s
|
mountUnit.Add("Mount", "What", "%s")
|
||||||
`
|
mountUnit.Add("Mount", "Where", "%s")
|
||||||
mountUnit := `[Mount]
|
mountUnit.Add("Mount", "Type", "virtiofs")
|
||||||
What=%s
|
mountUnit.Add("Install", "WantedBy", "multi-user.target")
|
||||||
Where=%s
|
mountUnitFile, err := mountUnit.ToString()
|
||||||
Type=virtiofs
|
if err != nil {
|
||||||
|
logrus.Warnf(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
[Install]
|
|
||||||
WantedBy=multi-user.target
|
|
||||||
`
|
|
||||||
virtiofsAutomount := ignition.Unit{
|
virtiofsAutomount := ignition.Unit{
|
||||||
Enabled: ignition.BoolToPtr(true),
|
Enabled: ignition.BoolToPtr(true),
|
||||||
Name: fmt.Sprintf("%s.automount", mnt.Tag),
|
Name: fmt.Sprintf("%s.automount", mnt.Tag),
|
||||||
Contents: ignition.StrToPtr(fmt.Sprintf(autoMountUnit, mnt.Target, mnt.Target)),
|
Contents: ignition.StrToPtr(fmt.Sprintf(autoMountUnitFile, mnt.Target, mnt.Target)),
|
||||||
}
|
}
|
||||||
virtiofsMount := ignition.Unit{
|
virtiofsMount := ignition.Unit{
|
||||||
Enabled: ignition.BoolToPtr(true),
|
Enabled: ignition.BoolToPtr(true),
|
||||||
Name: fmt.Sprintf("%s.mount", mnt.Tag),
|
Name: fmt.Sprintf("%s.mount", mnt.Tag),
|
||||||
Contents: ignition.StrToPtr(fmt.Sprintf(mountUnit, mnt.Tag, mnt.Target)),
|
Contents: ignition.StrToPtr(fmt.Sprintf(mountUnitFile, mnt.Tag, mnt.Target)),
|
||||||
}
|
}
|
||||||
|
|
||||||
// This "unit" simulates something like systemctl enable virtiofs-mount-prepare@
|
// This "unit" simulates something like systemctl enable virtiofs-mount-prepare@
|
||||||
@ -1149,23 +1157,24 @@ WantedBy=multi-user.target
|
|||||||
|
|
||||||
// mount prep is a way to workaround the FCOS limitation of creating directories
|
// mount prep is a way to workaround the FCOS limitation of creating directories
|
||||||
// at the rootfs / and then mounting to them.
|
// at the rootfs / and then mounting to them.
|
||||||
mountPrep := `
|
mountPrep := parser.NewUnitFile()
|
||||||
[Unit]
|
mountPrep.Add("Unit", "Description", "Allow virtios to mount to /")
|
||||||
Description=Allow virtios to mount to /
|
mountPrep.Add("Unit", "DefaultDependencies", "no")
|
||||||
DefaultDependencies=no
|
mountPrep.Add("Unit", "ConditionPathExists", "!%f")
|
||||||
ConditionPathExists=!%f
|
|
||||||
|
|
||||||
[Service]
|
mountPrep.Add("Service", "Type", "oneshot")
|
||||||
Type=oneshot
|
mountPrep.Add("Service", "ExecStartPre", "chattr -i /")
|
||||||
ExecStartPre=chattr -i /
|
mountPrep.Add("Service", "ExecStart", "mkdir -p '%f'")
|
||||||
ExecStart=mkdir -p '%f'
|
mountPrep.Add("Service", "ExecStopPost", "chattr +i /")
|
||||||
ExecStopPost=chattr +i /
|
|
||||||
|
mountPrep.Add("Install", "WantedBy", "remote-fs.target")
|
||||||
|
mountPrepFile, err := mountPrep.ToString()
|
||||||
|
if err != nil {
|
||||||
|
logrus.Warnf(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
[Install]
|
|
||||||
WantedBy=remote-fs.target
|
|
||||||
`
|
|
||||||
virtioFSChattr := ignition.Unit{
|
virtioFSChattr := ignition.Unit{
|
||||||
Contents: ignition.StrToPtr(mountPrep),
|
Contents: ignition.StrToPtr(mountPrepFile),
|
||||||
Name: "virtiofs-mount-prepare@.service",
|
Name: "virtiofs-mount-prepare@.service",
|
||||||
}
|
}
|
||||||
unitFiles = append(unitFiles, virtioFSChattr)
|
unitFiles = append(unitFiles, virtioFSChattr)
|
||||||
|
@ -24,6 +24,7 @@ import (
|
|||||||
"github.com/containers/podman/v4/pkg/machine/vmconfigs"
|
"github.com/containers/podman/v4/pkg/machine/vmconfigs"
|
||||||
"github.com/containers/podman/v4/pkg/machine/ignition"
|
"github.com/containers/podman/v4/pkg/machine/ignition"
|
||||||
"github.com/containers/podman/v4/pkg/strongunits"
|
"github.com/containers/podman/v4/pkg/strongunits"
|
||||||
|
"github.com/containers/podman/v4/pkg/systemd/parser"
|
||||||
"github.com/containers/podman/v4/pkg/util"
|
"github.com/containers/podman/v4/pkg/util"
|
||||||
"github.com/containers/podman/v4/utils"
|
"github.com/containers/podman/v4/utils"
|
||||||
"github.com/containers/storage/pkg/lockfile"
|
"github.com/containers/storage/pkg/lockfile"
|
||||||
@ -46,40 +47,6 @@ const (
|
|||||||
apiUpTimeout = 20 * time.Second
|
apiUpTimeout = 20 * time.Second
|
||||||
)
|
)
|
||||||
|
|
||||||
// hyperVReadyUnit is a unit file that sets up the virtual serial device
|
|
||||||
// where when the VM is done configuring, it will send an ack
|
|
||||||
// so a listening host knows it can begin interacting with it
|
|
||||||
//
|
|
||||||
// VSOCK-CONNECT:2 <- shortcut to connect to the hostvm
|
|
||||||
const hyperVReadyUnit = `[Unit]
|
|
||||||
After=remove-moby.service sshd.socket sshd.service
|
|
||||||
After=systemd-user-sessions.service
|
|
||||||
OnFailure=emergency.target
|
|
||||||
OnFailureJobMode=isolate
|
|
||||||
[Service]
|
|
||||||
Type=oneshot
|
|
||||||
RemainAfterExit=yes
|
|
||||||
ExecStart=/bin/sh -c '/usr/bin/echo Ready | socat - VSOCK-CONNECT:2:%d'
|
|
||||||
[Install]
|
|
||||||
RequiredBy=default.target
|
|
||||||
`
|
|
||||||
|
|
||||||
// hyperVVsockNetUnit is a systemd unit file that calls the vm helper utility
|
|
||||||
// needed to take traffic from a network vsock0 device to the actual vsock
|
|
||||||
// and onto the host
|
|
||||||
const hyperVVsockNetUnit = `
|
|
||||||
[Unit]
|
|
||||||
Description=vsock_network
|
|
||||||
After=NetworkManager.service
|
|
||||||
|
|
||||||
[Service]
|
|
||||||
ExecStart=/usr/libexec/podman/gvforwarder -preexisting -iface vsock0 -url vsock://2:%d/connect
|
|
||||||
ExecStartPost=/usr/bin/nmcli c up vsock0
|
|
||||||
|
|
||||||
[Install]
|
|
||||||
WantedBy=multi-user.target
|
|
||||||
`
|
|
||||||
|
|
||||||
const hyperVVsockNMConnection = `
|
const hyperVVsockNMConnection = `
|
||||||
[connection]
|
[connection]
|
||||||
id=vsock0
|
id=vsock0
|
||||||
@ -278,14 +245,24 @@ func (m *HyperVMachine) Init(opts machine.InitOptions) (bool, error) {
|
|||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
readyUnitFile, err := createReadyUnit(m.ReadyHVSock.Port)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
builder.WithUnit(ignition.Unit{
|
builder.WithUnit(ignition.Unit{
|
||||||
Enabled: ignition.BoolToPtr(true),
|
Enabled: ignition.BoolToPtr(true),
|
||||||
Name: "ready.service",
|
Name: "ready.service",
|
||||||
Contents: ignition.StrToPtr(fmt.Sprintf(hyperVReadyUnit, m.ReadyHVSock.Port)),
|
Contents: ignition.StrToPtr(readyUnitFile),
|
||||||
})
|
})
|
||||||
|
|
||||||
|
netUnitFile, err := createNetworkUnit(m.NetworkHVSock.Port)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
builder.WithUnit(ignition.Unit{
|
builder.WithUnit(ignition.Unit{
|
||||||
Contents: ignition.StrToPtr(fmt.Sprintf(hyperVVsockNetUnit, m.NetworkHVSock.Port)),
|
Contents: ignition.StrToPtr(netUnitFile),
|
||||||
Enabled: ignition.BoolToPtr(true),
|
Enabled: ignition.BoolToPtr(true),
|
||||||
Name: "vsock-network.service",
|
Name: "vsock-network.service",
|
||||||
})
|
})
|
||||||
@ -316,6 +293,23 @@ func (m *HyperVMachine) Init(opts machine.InitOptions) (bool, error) {
|
|||||||
return err == nil, err
|
return err == nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func createReadyUnit(readyPort uint64) (string, error) {
|
||||||
|
readyUnit := ignition.DefaultReadyUnitFile()
|
||||||
|
readyUnit.Add("Unit", "After", "systemd-user-sessions.service")
|
||||||
|
readyUnit.Add("Service", "ExecStart", fmt.Sprintf("/bin/sh -c '/usr/bin/echo Ready | socat - VSOCK-CONNECT:2:%d'", readyPort))
|
||||||
|
return readyUnit.ToString()
|
||||||
|
}
|
||||||
|
|
||||||
|
func createNetworkUnit(netPort uint64) (string, error) {
|
||||||
|
netUnit := parser.NewUnitFile()
|
||||||
|
netUnit.Add("Unit", "Description", "vsock_network")
|
||||||
|
netUnit.Add("Unit", "After", "NetworkManager.service")
|
||||||
|
netUnit.Add("Service", "ExecStart", fmt.Sprintf("/usr/libexec/podman/gvforwarder -preexisting -iface vsock0 -url vsock://2:%d/connect", netPort))
|
||||||
|
netUnit.Add("Service", "ExecStartPost", "/usr/bin/nmcli c up vsock0")
|
||||||
|
netUnit.Add("Install", "WantedBy", "multi-user.target")
|
||||||
|
return netUnit.ToString()
|
||||||
|
}
|
||||||
|
|
||||||
func (m *HyperVMachine) unregisterMachine() error {
|
func (m *HyperVMachine) unregisterMachine() error {
|
||||||
vmm := hypervctl.NewVirtualMachineManager()
|
vmm := hypervctl.NewVirtualMachineManager()
|
||||||
vm, err := vmm.GetMachine(m.Name)
|
vm, err := vmm.GetMachine(m.Name)
|
||||||
|
@ -11,6 +11,7 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
"github.com/containers/podman/v4/pkg/machine/define"
|
"github.com/containers/podman/v4/pkg/machine/define"
|
||||||
|
"github.com/containers/podman/v4/pkg/systemd/parser"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -134,23 +135,24 @@ func (ign *DynamicIgnition) GenerateIgnitionConfig() error {
|
|||||||
ignStorage.Links = append(ignStorage.Links, tzLink)
|
ignStorage.Links = append(ignStorage.Links, tzLink)
|
||||||
}
|
}
|
||||||
|
|
||||||
deMoby := `[Unit]
|
deMoby := parser.NewUnitFile()
|
||||||
Description=Remove moby-engine
|
deMoby.Add("Unit", "Description", "Remove moby-engine")
|
||||||
# Run once for the machine
|
deMoby.Add("Unit", "After", "systemd-machine-id-commit.service")
|
||||||
After=systemd-machine-id-commit.service
|
deMoby.Add("Unit", "Before", "zincati.service")
|
||||||
Before=zincati.service
|
deMoby.Add("Unit", "ConditionPathExists", "!/var/lib/%N.stamp")
|
||||||
ConditionPathExists=!/var/lib/%N.stamp
|
|
||||||
|
|
||||||
[Service]
|
deMoby.Add("Service", "Type", "oneshot")
|
||||||
Type=oneshot
|
deMoby.Add("Service", "RemainAfterExit", "yes")
|
||||||
RemainAfterExit=yes
|
deMoby.Add("Service", "ExecStart", "/usr/bin/rpm-ostree override remove moby-engine")
|
||||||
ExecStart=/usr/bin/rpm-ostree override remove moby-engine
|
deMoby.Add("Service", "ExecStart", "/usr/bin/rpm-ostree ex apply-live --allow-replacement")
|
||||||
ExecStart=/usr/bin/rpm-ostree ex apply-live --allow-replacement
|
deMoby.Add("Service", "ExecStartPost", "/bin/touch /var/lib/%N.stamp")
|
||||||
ExecStartPost=/bin/touch /var/lib/%N.stamp
|
|
||||||
|
deMoby.Add("Install", "WantedBy", "default.target")
|
||||||
|
deMobyFile, err := deMoby.ToString()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
[Install]
|
|
||||||
WantedBy=default.target
|
|
||||||
`
|
|
||||||
// This service gets environment variables that are provided
|
// This service gets environment variables that are provided
|
||||||
// through qemu fw_cfg and then sets them into systemd/system.conf.d,
|
// through qemu fw_cfg and then sets them into systemd/system.conf.d,
|
||||||
// profile.d and environment.d files
|
// profile.d and environment.d files
|
||||||
@ -158,34 +160,39 @@ WantedBy=default.target
|
|||||||
// Currently, it is used for propagating
|
// Currently, it is used for propagating
|
||||||
// proxy settings e.g. HTTP_PROXY and others, on a start avoiding
|
// proxy settings e.g. HTTP_PROXY and others, on a start avoiding
|
||||||
// a need of re-creating/re-initiating a VM
|
// a need of re-creating/re-initiating a VM
|
||||||
envset := `[Unit]
|
|
||||||
Description=Environment setter from QEMU FW_CFG
|
envset := parser.NewUnitFile()
|
||||||
[Service]
|
envset.Add("Unit", "Description", "Environment setter from QEMU FW_CFG")
|
||||||
Type=oneshot
|
|
||||||
RemainAfterExit=yes
|
envset.Add("Service", "Type", "oneshot")
|
||||||
Environment=FWCFGRAW=/sys/firmware/qemu_fw_cfg/by_name/opt/com.coreos/environment/raw
|
envset.Add("Service", "RemainAfterExit", "yes")
|
||||||
Environment=SYSTEMD_CONF=/etc/systemd/system.conf.d/default-env.conf
|
envset.Add("Service", "Environment", "FWCFGRAW=/sys/firmware/qemu_fw_cfg/by_name/opt/com.coreos/environment/raw")
|
||||||
Environment=ENVD_CONF=/etc/environment.d/default-env.conf
|
envset.Add("Service", "Environment", "SYSTEMD_CONF=/etc/systemd/system.conf.d/default-env.conf")
|
||||||
Environment=PROFILE_CONF=/etc/profile.d/default-env.sh
|
envset.Add("Service", "Environment", "ENVD_CONF=/etc/environment.d/default-env.conf")
|
||||||
ExecStart=/usr/bin/bash -c '/usr/bin/test -f ${FWCFGRAW} &&\
|
envset.Add("Service", "Environment", "PROFILE_CONF=/etc/profile.d/default-env.sh")
|
||||||
echo "[Manager]\n#Got from QEMU FW_CFG\nDefaultEnvironment=$(/usr/bin/base64 -d ${FWCFGRAW} | sed -e "s+|+ +g")\n" > ${SYSTEMD_CONF} ||\
|
envset.Add("Service", "ExecStart", `/usr/bin/bash -c '/usr/bin/test -f ${FWCFGRAW} &&\
|
||||||
echo "[Manager]\n#Got nothing from QEMU FW_CFG\n#DefaultEnvironment=\n" > ${SYSTEMD_CONF}'
|
echo "[Manager]\n#Got from QEMU FW_CFG\nDefaultEnvironment=$(/usr/bin/base64 -d ${FWCFGRAW} | sed -e "s+|+ +g")\n" > ${SYSTEMD_CONF} ||\
|
||||||
ExecStart=/usr/bin/bash -c '/usr/bin/test -f ${FWCFGRAW} && (\
|
echo "[Manager]\n#Got nothing from QEMU FW_CFG\n#DefaultEnvironment=\n" > ${SYSTEMD_CONF}'`)
|
||||||
echo "#Got from QEMU FW_CFG"> ${ENVD_CONF};\
|
envset.Add("Service", "ExecStart", `/usr/bin/bash -c '/usr/bin/test -f ${FWCFGRAW} && (\
|
||||||
IFS="|";\
|
echo "#Got from QEMU FW_CFG"> ${ENVD_CONF};\
|
||||||
for iprxy in $(/usr/bin/base64 -d ${FWCFGRAW}); do\
|
IFS="|";\
|
||||||
echo "$iprxy" >> ${ENVD_CONF}; done ) || \
|
for iprxy in $(/usr/bin/base64 -d ${FWCFGRAW}); do\
|
||||||
echo "#Got nothing from QEMU FW_CFG"> ${ENVD_CONF}'
|
echo "$iprxy" >> ${ENVD_CONF}; done ) || \
|
||||||
ExecStart=/usr/bin/bash -c '/usr/bin/test -f ${FWCFGRAW} && (\
|
echo "#Got nothing from QEMU FW_CFG"> ${ENVD_CONF}'`)
|
||||||
echo "#Got from QEMU FW_CFG"> ${PROFILE_CONF};\
|
envset.Add("Service", "ExecStart", `/usr/bin/bash -c '/usr/bin/test -f ${FWCFGRAW} && (\
|
||||||
IFS="|";\
|
echo "#Got from QEMU FW_CFG"> ${PROFILE_CONF};\
|
||||||
for iprxy in $(/usr/bin/base64 -d ${FWCFGRAW}); do\
|
IFS="|";\
|
||||||
echo "export $iprxy" >> ${PROFILE_CONF}; done ) || \
|
for iprxy in $(/usr/bin/base64 -d ${FWCFGRAW}); do\
|
||||||
echo "#Got nothing from QEMU FW_CFG"> ${PROFILE_CONF}'
|
echo "export $iprxy" >> ${PROFILE_CONF}; done ) || \
|
||||||
ExecStartPost=/usr/bin/systemctl daemon-reload
|
echo "#Got nothing from QEMU FW_CFG"> ${PROFILE_CONF}'`)
|
||||||
[Install]
|
envset.Add("Service", "ExecStartPost", "/usr/bin/systemctl daemon-reload")
|
||||||
WantedBy=sysinit.target
|
|
||||||
`
|
envset.Add("Install", "WantedBy", "sysinit.target")
|
||||||
|
envsetFile, err := envset.ToString()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
ignSystemd := Systemd{
|
ignSystemd := Systemd{
|
||||||
Units: []Unit{
|
Units: []Unit{
|
||||||
{
|
{
|
||||||
@ -205,7 +212,7 @@ WantedBy=sysinit.target
|
|||||||
{
|
{
|
||||||
Enabled: BoolToPtr(true),
|
Enabled: BoolToPtr(true),
|
||||||
Name: "remove-moby.service",
|
Name: "remove-moby.service",
|
||||||
Contents: &deMoby,
|
Contents: &deMobyFile,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// Disable auto-updating of fcos images
|
// Disable auto-updating of fcos images
|
||||||
@ -220,7 +227,7 @@ WantedBy=sysinit.target
|
|||||||
qemuUnit := Unit{
|
qemuUnit := Unit{
|
||||||
Enabled: BoolToPtr(true),
|
Enabled: BoolToPtr(true),
|
||||||
Name: "envset-fwcfg.service",
|
Name: "envset-fwcfg.service",
|
||||||
Contents: &envset,
|
Contents: &envsetFile,
|
||||||
}
|
}
|
||||||
ignSystemd.Units = append(ignSystemd.Units, qemuUnit)
|
ignSystemd.Units = append(ignSystemd.Units, qemuUnit)
|
||||||
}
|
}
|
||||||
@ -299,13 +306,16 @@ func getDirs(usrName string) []Directory {
|
|||||||
func getFiles(usrName string, uid int, rootful bool, vmtype define.VMType) []File {
|
func getFiles(usrName string, uid int, rootful bool, vmtype define.VMType) []File {
|
||||||
files := make([]File, 0)
|
files := make([]File, 0)
|
||||||
|
|
||||||
lingerExample := `[Unit]
|
lingerExample := parser.NewUnitFile()
|
||||||
Description=A systemd user unit demo
|
lingerExample.Add("Unit", "Description", "A systemd user unit demo")
|
||||||
After=network-online.target
|
lingerExample.Add("Unit", "After", "network-online.target")
|
||||||
Wants=network-online.target podman.socket
|
lingerExample.Add("Unit", "Wants", "network-online.target podman.socket")
|
||||||
[Service]
|
lingerExample.Add("Service", "ExecStart", "/usr/bin/sleep infinity")
|
||||||
ExecStart=/usr/bin/sleep infinity
|
lingerExampleFile, err := lingerExample.ToString()
|
||||||
`
|
if err != nil {
|
||||||
|
logrus.Warnf(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
containers := `[containers]
|
containers := `[containers]
|
||||||
netns="bridge"
|
netns="bridge"
|
||||||
`
|
`
|
||||||
@ -336,7 +346,7 @@ Delegate=memory pids cpu io
|
|||||||
FileEmbedded1: FileEmbedded1{
|
FileEmbedded1: FileEmbedded1{
|
||||||
Append: nil,
|
Append: nil,
|
||||||
Contents: Resource{
|
Contents: Resource{
|
||||||
Source: EncodeDataURLPtr(lingerExample),
|
Source: EncodeDataURLPtr(lingerExampleFile),
|
||||||
},
|
},
|
||||||
Mode: IntToPtr(0744),
|
Mode: IntToPtr(0744),
|
||||||
},
|
},
|
||||||
@ -731,3 +741,14 @@ func (i *IgnitionBuilder) BuildWithIgnitionFile(ignPath string) error {
|
|||||||
func (i *IgnitionBuilder) Build() error {
|
func (i *IgnitionBuilder) Build() error {
|
||||||
return i.dynamicIgnition.Write()
|
return i.dynamicIgnition.Write()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func DefaultReadyUnitFile() parser.UnitFile {
|
||||||
|
u := parser.NewUnitFile()
|
||||||
|
u.Add("Unit", "After", "remove-moby.service sshd.socket sshd.service")
|
||||||
|
u.Add("Unit", "OnFailure", "emergency.target")
|
||||||
|
u.Add("Unit", "OnFailureJobMode", "isolate")
|
||||||
|
u.Add("Service", "Type", "oneshot")
|
||||||
|
u.Add("Service", "RemainAfterExit", "yes")
|
||||||
|
u.Add("Install", "RequiredBy", "default.target")
|
||||||
|
return *u
|
||||||
|
}
|
||||||
|
@ -47,23 +47,6 @@ const (
|
|||||||
dockerConnectTimeout = 5 * time.Second
|
dockerConnectTimeout = 5 * time.Second
|
||||||
)
|
)
|
||||||
|
|
||||||
// qemuReadyUnit is a unit file that sets up the virtual serial device
|
|
||||||
// where when the VM is done configuring, it will send an ack
|
|
||||||
// so a listening host tknows it can begin interacting with it
|
|
||||||
const qemuReadyUnit = `[Unit]
|
|
||||||
Requires=dev-virtio\\x2dports-%s.device
|
|
||||||
After=remove-moby.service sshd.socket sshd.service
|
|
||||||
After=systemd-user-sessions.service
|
|
||||||
OnFailure=emergency.target
|
|
||||||
OnFailureJobMode=isolate
|
|
||||||
[Service]
|
|
||||||
Type=oneshot
|
|
||||||
RemainAfterExit=yes
|
|
||||||
ExecStart=/bin/sh -c '/usr/bin/echo Ready >/dev/%s'
|
|
||||||
[Install]
|
|
||||||
RequiredBy=default.target
|
|
||||||
`
|
|
||||||
|
|
||||||
type MachineVM struct {
|
type MachineVM struct {
|
||||||
// ConfigPath is the path to the configuration file
|
// ConfigPath is the path to the configuration file
|
||||||
ConfigPath define.VMFile
|
ConfigPath define.VMFile
|
||||||
@ -230,10 +213,14 @@ func (v *MachineVM) Init(opts machine.InitOptions) (bool, error) {
|
|||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
readyUnitFile, err := createReadyUnitFile()
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
readyUnit := ignition.Unit{
|
readyUnit := ignition.Unit{
|
||||||
Enabled: ignition.BoolToPtr(true),
|
Enabled: ignition.BoolToPtr(true),
|
||||||
Name: "ready.service",
|
Name: "ready.service",
|
||||||
Contents: ignition.StrToPtr(fmt.Sprintf(qemuReadyUnit, "vport1p1", "vport1p1")),
|
Contents: ignition.StrToPtr(readyUnitFile),
|
||||||
}
|
}
|
||||||
builder.WithUnit(readyUnit)
|
builder.WithUnit(readyUnit)
|
||||||
|
|
||||||
@ -243,6 +230,14 @@ func (v *MachineVM) Init(opts machine.InitOptions) (bool, error) {
|
|||||||
return err == nil, err
|
return err == nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func createReadyUnitFile() (string, error) {
|
||||||
|
readyUnit := ignition.DefaultReadyUnitFile()
|
||||||
|
readyUnit.Add("Unit", "Requires", "dev-virtio\\x2dports-vport1p1.device")
|
||||||
|
readyUnit.Add("Unit", "After", "systemd-user-sessions.service")
|
||||||
|
readyUnit.Add("Service", "ExecStart", "/bin/sh -c '/usr/bin/echo Ready >/dev/vport1p1'")
|
||||||
|
return readyUnit.ToString()
|
||||||
|
}
|
||||||
|
|
||||||
func (v *MachineVM) removeSSHKeys() error {
|
func (v *MachineVM) removeSSHKeys() error {
|
||||||
if err := os.Remove(fmt.Sprintf("%s.pub", v.IdentityPath)); err != nil {
|
if err := os.Remove(fmt.Sprintf("%s.pub", v.IdentityPath)); err != nil {
|
||||||
logrus.Error(err)
|
logrus.Error(err)
|
||||||
|
Reference in New Issue
Block a user