2019-09-30 10:53:51 -04:00

129 lines
3.1 KiB
Go

// Copyright (c) Huawei Technologies Co., Ltd. 2018-2019. All rights reserved.
// isulad-tools is licensed under the Mulan PSL v1.
// You can use this software according to the terms and conditions of the Mulan PSL v1.
// You may obtain a copy of Mulan PSL v1 at:
// http://license.coscl.org.cn/MulanPSL
// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
// PURPOSE.
// See the Mulan PSL v1 for more details.
// Description: udevd rules
// Author: zhangwei
// Create: 2018-01-18
package udevd
import (
"bufio"
"fmt"
"github.com/sirupsen/logrus"
"os"
"os/exec"
"path/filepath"
"strings"
)
func usingUdevd() (bool, error) {
return true, nil
}
func reloadConfig() error {
_, err := exec.Command("udevadm", "control", "--reload").CombinedOutput()
return err
}
func saveRules(path string, rules []*Rule) error {
f, err := os.Create(path)
if err != nil {
return err
}
defer f.Close()
if err := f.Chmod(0600); err != nil {
return err
}
f.WriteString("## This File is auto-generated by isulad-tools.\n")
f.WriteString("## DO NOT EDIT IT\n\n")
for _, r := range rules {
if _, err := f.WriteString(fmt.Sprintf("%s\n", r.ToUdevRuleString())); err != nil {
logrus.Errorf("f.WriteString err: %s", err)
}
}
if err := f.Sync(); err != nil {
logrus.Errorf("f.WriteString err: %s", err)
return err
}
return nil
}
func loadRules(path string) ([]*Rule, error) {
var rules []*Rule
f, err := os.Open(path)
if err != nil {
// if non-existing, just return empty rules array
if os.IsNotExist(err) {
return rules, nil
}
return nil, err
}
defer f.Close()
logrus.Infof("Start load rules from path: %s", path)
scanner := bufio.NewScanner(f)
for scanner.Scan() {
text := strings.TrimLeft(scanner.Text(), " ")
// ignore the comment line
if strings.HasPrefix(text, "#") {
continue
}
array := strings.Split(text, ",")
var (
name string
ctrDevName string
containerID string
)
for _, tag := range array {
tag = strings.TrimLeft(tag, " ")
tag = strings.TrimRight(tag, " ")
// Parse device name from 'KERNEL' segment
if strings.HasPrefix(tag, "KERNEL") {
ar := strings.Split(tag, "\"")
if len(ar) >= 2 { // Minimum value for get split tag
sub := ar[1]
name = sub[:len(sub)-1]
}
}
// Parse Container ID, major, minor number from 'RUN' command
if strings.HasPrefix(tag, "RUN") {
ar := strings.Split(tag, "\"")
if len(ar) >= 2 { // Minimum value for get split tag
sub := ar[1]
cmdArray := strings.Split(sub, " ")
if len(cmdArray) >= 6 { // Minimum value for get split sub
containerID = cmdArray[2]
ctrDevName = cmdArray[4]
}
}
}
}
// TODO: failed to parse some rules, ignore it??
if name == "" || containerID == "" || ctrDevName == "" {
continue
}
rules = append(rules, &Rule{
Name: filepath.Join("/dev", name),
CtrDevName: ctrDevName,
Container: containerID,
})
}
logrus.Infof("Finish load rules from path: %s", path)
return rules, nil
}