/
githubmirror
/
ignition
Обзор
Документация
Войти
/
githubmirror
/
ignition
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
internal/exec/util/unit.go
201 строка
5 KB
Steven Presti
*: update to v3_7_experimental spec
11 фев 2026, 23:55
11 фев 2026, 23:55
3252aa5
Код
Авторство
О чём код?
// Copyright 2015 CoreOS, Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package util import ( "fmt" "net/url" "os" "os/exec" "path/filepath" "syscall" "github.com/coreos/ignition/v2/config/v3_7_experimental/types" "github.com/coreos/ignition/v2/internal/distro" "github.com/vincent-petithory/dataurl" ) const ( PresetPath string = "/etc/systemd/system-preset/20-ignition.preset" DefaultPresetPermissions os.FileMode = 0644 ) func (ut Util) FileFromSystemdUnit(unit types.Unit) (FetchOp, error) { if unit.Contents == nil { empty := "" unit.Contents = &empty } u, err := url.Parse(dataurl.EncodeBytes([]byte(*unit.Contents))) if err != nil { return FetchOp{}, err } path, err := ut.JoinPath(SystemdUnitsPath(), unit.Name) if err != nil { return FetchOp{}, err } return FetchOp{ Node: types.Node{ Path: path, }, Url: *u, }, nil } func (ut Util) FileFromSystemdUnitDropin(unit types.Unit, dropin types.Dropin) (FetchOp, error) { if dropin.Contents == nil { empty := "" dropin.Contents = &empty } u, err := url.Parse(dataurl.EncodeBytes([]byte(*dropin.Contents))) if err != nil { return FetchOp{}, err } path, err := ut.JoinPath(SystemdDropinsPath(string(unit.Name)), dropin.Name) if err != nil { return FetchOp{}, err } return FetchOp{ Node: types.Node{ Path: path, }, Url: *u, }, nil } // MaskUnit writes a symlink to /dev/null to mask the specified unit and returns the path of that unit // without the sysroot prefix func (ut Util) MaskUnit(unit types.Unit) (string, error) { path, err := ut.JoinPath(SystemdUnitsPath(), unit.Name) if err != nil { return "", err } if err := MkdirForFile(path); err != nil { return "", err } if err := os.RemoveAll(path); err != nil { return "", err } if err := os.Symlink("/dev/null", path); err != nil { return "", err } // not the same as the path above, since this lacks the sysroot prefix return filepath.Join("/", SystemdUnitsPath(), unit.Name), nil } // UnmaskUnit deletes the symlink to /dev/null for a masked unit func (ut Util) UnmaskUnit(unit types.Unit) error { path, err := ut.JoinPath(SystemdUnitsPath(), unit.Name) if err != nil { return err } // Make a final check to make sure the unit is masked masked, err := ut.IsUnitMasked(unit) if err != nil { return err } // If masked, remove the symlink if masked { if err = os.Remove(path); err != nil { return err } } return nil } // IsUnitMasked returns true/false if a systemd unit is masked func (ut Util) IsUnitMasked(unit types.Unit) (bool, error) { path, err := ut.JoinPath(SystemdUnitsPath(), unit.Name) if err != nil { return false, err } target, err := os.Readlink(path) if err != nil { if os.IsNotExist(err) { // The path doesn't exist, hence the unit isn't masked return false, nil } else if e, ok := err.(*os.PathError); ok && e.Err == syscall.EINVAL { // The path isn't a symlink, hence the unit isn't masked return false, nil } else { return false, err } } if target != "/dev/null" { // The symlink doesn't point to /dev/null, hence the unit isn't masked return false, nil } return true, nil } func (ut Util) EnableUnit(enabledUnit string) error { return ut.appendLineToPreset(fmt.Sprintf("enable %s", enabledUnit)) } func (ut Util) DisableUnit(disabledUnit string) error { // check if the unit is currently enabled to see if we need to disable it // if it's not enabled or does not exist, we don't need to do anything args := []string{"--root", ut.DestDir, "is-enabled", disabledUnit} if err := exec.Command(distro.SystemctlCmd(), args...).Run(); err != nil { return nil } // We need to delete any enablement symlinks for a unit before sending it to a // preset directive. This will help to disable that unit completely. // For more information: https://github.com/coreos/fedora-coreos-tracker/issues/392 // This is a short-term solution until the upstream systemd PR // (https://github.com/systemd/systemd/pull/15205) gets accepted. if err := ut.LogOp( func() error { args := []string{"--root", ut.DestDir, "disable", disabledUnit} if output, err := exec.Command(distro.SystemctlCmd(), args...).CombinedOutput(); err != nil { return fmt.Errorf("cannot remove symlink(s) for %s: %v: %q", disabledUnit, err, string(output)) } return nil }, "removing enablement symlink(s) for %q", disabledUnit, ); err != nil { return err } return ut.appendLineToPreset(fmt.Sprintf("disable %s", disabledUnit)) } func (ut Util) appendLineToPreset(data string) error { path, err := ut.JoinPath(PresetPath) if err != nil { return err } if err := MkdirForFile(path); err != nil { return err } file, err := os.OpenFile(path, os.O_RDWR|os.O_APPEND|os.O_CREATE, DefaultPresetPermissions) if err != nil { return err } defer func() { _ = file.Close() }() _, err = file.WriteString(data + "\n") return err }