1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163
|
// Copyright (c) 2018-2022, Sylabs Inc. All rights reserved.
// This software is licensed under a 3-clause BSD license. Please consult the
// LICENSE.md file distributed with the sources of this project regarding your
// rights to use or distribute this software.
// Includes code from https://github.com/containers/podman
// Released under the Apache License Version 2.0
package singularity
import (
"context"
"fmt"
lccgroups "github.com/opencontainers/runc/libcontainer/cgroups"
"github.com/sylabs/singularity/v4/internal/pkg/buildcfg"
"github.com/sylabs/singularity/v4/internal/pkg/runtime/launcher/oci"
ocibundle "github.com/sylabs/singularity/v4/pkg/ocibundle/sif"
"github.com/sylabs/singularity/v4/pkg/util/namespaces"
"github.com/sylabs/singularity/v4/pkg/util/singularityconf"
)
// OciArgs contains CLI arguments
type OciArgs struct {
BundlePath string
OverlayPaths []string
LogPath string
LogFormat string
PidFile string
FromFile string
KillSignal string
KillTimeout uint32
EmptyProcess bool
ForceKill bool
}
// OciRun runs a container (equivalent to create/start/delete)
func OciRun(ctx context.Context, containerID string, args *OciArgs) error {
systemdCgroups, err := systemdCgroups()
if err != nil {
return err
}
return oci.Run(ctx, containerID, args.BundlePath, args.PidFile, systemdCgroups)
}
// OciCreate creates a container from an OCI bundle
func OciCreate(containerID string, args *OciArgs) error {
systemdCgroups, err := systemdCgroups()
if err != nil {
return err
}
return oci.Create(containerID, args.BundlePath, systemdCgroups)
}
// OciStart starts a previously create container
func OciStart(containerID string) error {
systemdCgroups, err := systemdCgroups()
if err != nil {
return err
}
return oci.Start(containerID, systemdCgroups)
}
// OciDelete deletes container resources
func OciDelete(ctx context.Context, containerID string) error {
systemdCgroups, err := systemdCgroups()
if err != nil {
return err
}
return oci.Delete(ctx, containerID, systemdCgroups)
}
// OciExec executes a command in a container
func OciExec(containerID string, cmdArgs []string) error {
systemdCgroups, err := systemdCgroups()
if err != nil {
return err
}
return oci.Exec(containerID, cmdArgs, systemdCgroups)
}
// OciKill kills container process
func OciKill(containerID string, killSignal string) error {
return oci.Kill(containerID, killSignal)
}
// OciPause pauses processes in a container
func OciPause(containerID string) error {
systemdCgroups, err := systemdCgroups()
if err != nil {
return err
}
return oci.Pause(containerID, systemdCgroups)
}
// OciResume pauses processes in a container
func OciResume(containerID string) error {
systemdCgroups, err := systemdCgroups()
if err != nil {
return err
}
return oci.Resume(containerID, systemdCgroups)
}
// OciState queries container state
func OciState(containerID string, _ *OciArgs) error {
systemdCgroups, err := systemdCgroups()
if err != nil {
return err
}
return oci.State(containerID, systemdCgroups)
}
// OciUpdate updates container cgroups resources
func OciUpdate(containerID string, args *OciArgs) error {
systemdCgroups, err := systemdCgroups()
if err != nil {
return err
}
return oci.Update(containerID, args.FromFile, systemdCgroups)
}
// OciMount mount a SIF image to create an OCI bundle
func OciMount(ctx context.Context, image string, bundle string) error {
d, err := ocibundle.FromSif(image, bundle, true)
if err != nil {
return err
}
return d.Create(ctx, nil)
}
// OciUmount umount SIF and delete OCI bundle
func OciUmount(ctx context.Context, bundle string) error {
d, err := ocibundle.FromSif("", bundle, true)
if err != nil {
return err
}
return d.Delete(ctx)
}
func systemdCgroups() (use bool, err error) {
cfg := singularityconf.GetCurrentConfig()
if cfg == nil {
cfg, err = singularityconf.Parse(buildcfg.SINGULARITY_CONF_FILE)
if err != nil {
return false, fmt.Errorf("unable to parse singularity configuration file: %w", err)
}
}
useSystemd := cfg.SystemdCgroups
// As non-root, we need cgroups v2 unified mode for systemd support.
// Fall back to cgroupfs if this is not available.
hostUID, err := namespaces.HostUID()
if err != nil {
return false, fmt.Errorf("while finding host uid: %w", err)
}
if hostUID != 0 && !lccgroups.IsCgroup2UnifiedMode() {
useSystemd = false
}
return useSystemd, nil
}
|