mirror of
https://github.com/clearlinux/rkt.git
synced 2026-09-04 04:41:30 +00:00
Merge pull request #214 from vcaputo/socketactivation
stage1: generate socket unit for socket-activated ports
This commit is contained in:
+50
-11
@@ -63,7 +63,7 @@ func LoadContainer(root string) (*Container, error) {
|
||||
return c, nil
|
||||
}
|
||||
|
||||
// appToSystemd transforms the provided app manifest into a systemd service unit
|
||||
// appToSystemd transforms the provided app manifest into systemd units
|
||||
func (c *Container) appToSystemd(am *schema.AppManifest, id types.Hash) error {
|
||||
name := am.Name.String()
|
||||
execStart := strings.Join(am.Exec, " ")
|
||||
@@ -101,17 +101,62 @@ func (c *Container) appToSystemd(am *schema.AppManifest, id types.Hash) error {
|
||||
opts = append(opts, &unit.UnitOption{"Service", "Environment", ee})
|
||||
}
|
||||
|
||||
file, err := os.OpenFile(ServiceFilePath(c.Root, id), os.O_WRONLY|os.O_CREATE, 0644)
|
||||
saPorts := []types.Port{}
|
||||
for _, p := range am.Ports {
|
||||
if p.SocketActivated {
|
||||
saPorts = append(saPorts, p)
|
||||
}
|
||||
}
|
||||
|
||||
if len(saPorts) > 0 {
|
||||
sockopts := []*unit.UnitOption{
|
||||
&unit.UnitOption{"Unit", "Description", name + " socket-activated ports"},
|
||||
&unit.UnitOption{"Unit", "DefaultDependencies", "false"},
|
||||
&unit.UnitOption{"Socket", "BindIPv6Only", "both"},
|
||||
&unit.UnitOption{"Socket", "Service", ServiceUnitName(id)},
|
||||
}
|
||||
|
||||
for _, sap := range saPorts {
|
||||
var proto string
|
||||
switch sap.Protocol {
|
||||
case "tcp":
|
||||
proto = "ListenStream"
|
||||
case "udp":
|
||||
proto = "ListenDatagram"
|
||||
default:
|
||||
return fmt.Errorf("unrecognized protocol: %v", sap.Protocol)
|
||||
}
|
||||
sockopts = append(sockopts, &unit.UnitOption{"Socket", proto, fmt.Sprintf("%v", sap.Port)})
|
||||
}
|
||||
|
||||
file, err := os.OpenFile(SocketUnitPath(c.Root, id), os.O_WRONLY|os.O_CREATE, 0644)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create socket file: %v", err)
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
if _, err = io.Copy(file, unit.Serialize(sockopts)); err != nil {
|
||||
return fmt.Errorf("failed to write socket unit file: %v", err)
|
||||
}
|
||||
|
||||
if err = os.Symlink(path.Join("..", SocketUnitName(id)), SocketWantPath(c.Root, id)); err != nil {
|
||||
return fmt.Errorf("failed to link socket want: %v", err)
|
||||
}
|
||||
|
||||
opts = append(opts, &unit.UnitOption{"Unit", "Requires", SocketUnitName(id)})
|
||||
}
|
||||
|
||||
file, err := os.OpenFile(ServiceUnitPath(c.Root, id), os.O_WRONLY|os.O_CREATE, 0644)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create service file: %v", err)
|
||||
return fmt.Errorf("failed to create service unit file: %v", err)
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
if _, err = io.Copy(file, unit.Serialize(opts)); err != nil {
|
||||
return fmt.Errorf("failed to write service file: %v", err)
|
||||
return fmt.Errorf("failed to write service unit file: %v", err)
|
||||
}
|
||||
|
||||
if err = os.Symlink(path.Join("..", ServiceName(id)), WantLinkPath(c.Root, id)); err != nil {
|
||||
if err = os.Symlink(path.Join("..", ServiceUnitName(id)), ServiceWantPath(c.Root, id)); err != nil {
|
||||
return fmt.Errorf("failed to link service want: %v", err)
|
||||
}
|
||||
|
||||
@@ -121,12 +166,6 @@ func (c *Container) appToSystemd(am *schema.AppManifest, id types.Hash) error {
|
||||
// ContainerToSystemd creates the appropriate systemd service unit files for
|
||||
// all the constituent apps of the Container
|
||||
func (c *Container) ContainerToSystemd() error {
|
||||
if err := os.MkdirAll(ServicesPath(c.Root), 0640); err != nil {
|
||||
return fmt.Errorf("failed to create services directory: %v", err)
|
||||
}
|
||||
if err := os.MkdirAll(WantsPath(c.Root), 0640); err != nil {
|
||||
return fmt.Errorf("failed to create wants directory: %v", err)
|
||||
}
|
||||
for _, am := range c.Apps {
|
||||
a := c.Manifest.Apps.Get(am.Name)
|
||||
if a == nil {
|
||||
|
||||
+28
-22
@@ -8,34 +8,40 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
servicesDir = path.Stage1Dir + "/usr/lib/systemd/system"
|
||||
wantsDir = servicesDir + "/default.target.wants"
|
||||
unitsDir = path.Stage1Dir + "/usr/lib/systemd/system"
|
||||
defaultWantsDir = unitsDir + "/default.target.wants"
|
||||
socketsWantsDir = unitsDir + "/sockets.target.wants"
|
||||
)
|
||||
|
||||
// ServiceName returns a sanitized (escaped) systemd service name
|
||||
// for the given imageID
|
||||
func ServiceName(imageID types.Hash) string {
|
||||
// ServiceUnitName returns a systemd service unit name for the given imageID
|
||||
func ServiceUnitName(imageID types.Hash) string {
|
||||
return imageID.String() + ".service"
|
||||
}
|
||||
|
||||
// WantsPath returns the systemd "wants" directory in root
|
||||
func WantsPath(root string) string {
|
||||
return filepath.Join(root, wantsDir)
|
||||
// ServiceUnitPath returns the path to the systemd service file for the given
|
||||
// imageID
|
||||
func ServiceUnitPath(root string, imageID types.Hash) string {
|
||||
return filepath.Join(root, unitsDir, ServiceUnitName(imageID))
|
||||
}
|
||||
|
||||
// ServicesPath returns the systemd "services" directory in root
|
||||
func ServicesPath(root string) string {
|
||||
return filepath.Join(root, servicesDir)
|
||||
}
|
||||
|
||||
// ServiceFilePath returns the path to the systemd service file
|
||||
// path for the given imageID
|
||||
func ServiceFilePath(root string, imageID types.Hash) string {
|
||||
return filepath.Join(root, servicesDir, ServiceName(imageID))
|
||||
}
|
||||
|
||||
// WantLinkPath returns the systemd "want" symlink path for the
|
||||
// ServiceWantPath returns the systemd default.target want symlink path for the
|
||||
// given imageID
|
||||
func WantLinkPath(root string, imageID types.Hash) string {
|
||||
return filepath.Join(root, wantsDir, ServiceName(imageID))
|
||||
func ServiceWantPath(root string, imageID types.Hash) string {
|
||||
return filepath.Join(filepath.Join(root, defaultWantsDir), ServiceUnitName(imageID))
|
||||
}
|
||||
|
||||
// SocketUnitName returns a systemd socket unit name for the given imageID
|
||||
func SocketUnitName(imageID types.Hash) string {
|
||||
return imageID.String() + ".socket"
|
||||
}
|
||||
|
||||
// SocketUnitPath returns the path to the systemd socket file for the given imageID
|
||||
func SocketUnitPath(root string, imageID types.Hash) string {
|
||||
return filepath.Join(root, unitsDir, SocketUnitName(imageID))
|
||||
}
|
||||
|
||||
// SocketWantPath returns the systemd sockets.target.wants symlink path for the
|
||||
// given imageID
|
||||
func SocketWantPath(root string, imageID types.Hash) string {
|
||||
return filepath.Join(filepath.Join(root, socketsWantsDir), SocketUnitName(imageID))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user