1ba991379Sopenharmony_ci#!/usr/bin/env python
2ba991379Sopenharmony_ci#coding=utf-8
3ba991379Sopenharmony_ci
4ba991379Sopenharmony_ci#
5ba991379Sopenharmony_ci# Copyright (c) 2023-2024 Huawei Device Co., Ltd.
6ba991379Sopenharmony_ci# Licensed under the Apache License, Version 2.0 (the "License");
7ba991379Sopenharmony_ci# you may not use this file except in compliance with the License.
8ba991379Sopenharmony_ci# You may obtain a copy of the License at
9ba991379Sopenharmony_ci#
10ba991379Sopenharmony_ci#     http://www.apache.org/licenses/LICENSE-2.0
11ba991379Sopenharmony_ci#
12ba991379Sopenharmony_ci# Unless required by applicable law or agreed to in writing, software
13ba991379Sopenharmony_ci# distributed under the License is distributed on an "AS IS" BASIS,
14ba991379Sopenharmony_ci# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15ba991379Sopenharmony_ci# See the License for the specific language governing permissions and
16ba991379Sopenharmony_ci# limitations under the License.
17ba991379Sopenharmony_ci#
18ba991379Sopenharmony_ci
19ba991379Sopenharmony_ciimport os
20ba991379Sopenharmony_ciimport json
21ba991379Sopenharmony_ci
22ba991379Sopenharmony_cifrom .base_rule import BaseRule
23ba991379Sopenharmony_ci
24ba991379Sopenharmony_ci
25ba991379Sopenharmony_ciclass CmdRule(BaseRule):
26ba991379Sopenharmony_ci    RULE_NAME = "NO-Config-Cmds-In-Init"
27ba991379Sopenharmony_ci
28ba991379Sopenharmony_ci    def __init__(self, mgr, args):
29ba991379Sopenharmony_ci        super().__init__(mgr, args)
30ba991379Sopenharmony_ci        self._cmds = {}
31ba991379Sopenharmony_ci        self._start_modes = {}
32ba991379Sopenharmony_ci        self._boot_list = {}
33ba991379Sopenharmony_ci        self._condition_list = {}
34ba991379Sopenharmony_ci        self._start_cmd_list = {}
35ba991379Sopenharmony_ci
36ba991379Sopenharmony_ci    def __check__(self):
37ba991379Sopenharmony_ci        return self.check_config_cmd()
38ba991379Sopenharmony_ci
39ba991379Sopenharmony_ci    def check_config_cmd(self):
40ba991379Sopenharmony_ci        passed = True
41ba991379Sopenharmony_ci        self._parse_while_list()
42ba991379Sopenharmony_ci        cfg_parser = self.get_mgr().get_parser_by_name('config_parser')
43ba991379Sopenharmony_ci        self._get_json_service()
44ba991379Sopenharmony_ci
45ba991379Sopenharmony_ci        start_passed = self._check_start_cmd(cfg_parser)
46ba991379Sopenharmony_ci        secon_passed = self._check_selinux(cfg_parser)
47ba991379Sopenharmony_ci        cmd_passed = self._check_cmdline_in_parser(cfg_parser)
48ba991379Sopenharmony_ci        start_mode_passed = self._check_service(cfg_parser)
49ba991379Sopenharmony_ci        passed = start_passed and secon_passed and cmd_passed and start_mode_passed
50ba991379Sopenharmony_ci        return passed
51ba991379Sopenharmony_ci
52ba991379Sopenharmony_ci    def _get_json_service(self):
53ba991379Sopenharmony_ci        for _, start_mode in enumerate(self._start_modes):
54ba991379Sopenharmony_ci            if start_mode.get("start-mode") == "boot":
55ba991379Sopenharmony_ci                self._boot_list = start_mode.get("service")
56ba991379Sopenharmony_ci            elif start_mode.get("start-mode") == "condition":
57ba991379Sopenharmony_ci                self._condition_list = start_mode.get("service")
58ba991379Sopenharmony_ci        pass
59ba991379Sopenharmony_ci
60ba991379Sopenharmony_ci    def _get_start_cmds(self, parser):
61ba991379Sopenharmony_ci        lists = {}
62ba991379Sopenharmony_ci        for cmd in parser._cmds:
63ba991379Sopenharmony_ci            if cmd["name"] == "start":
64ba991379Sopenharmony_ci                lists[cmd["content"]] = cmd["fileId"]
65ba991379Sopenharmony_ci                pass
66ba991379Sopenharmony_ci        return lists
67ba991379Sopenharmony_ci
68ba991379Sopenharmony_ci    def _parse_while_list(self):
69ba991379Sopenharmony_ci        white_lists = self.get_white_lists()[0]
70ba991379Sopenharmony_ci        for key, item in white_lists.items():
71ba991379Sopenharmony_ci            if key == "cmds":
72ba991379Sopenharmony_ci                self._cmds = item
73ba991379Sopenharmony_ci            if key == "start-modes":
74ba991379Sopenharmony_ci                self._start_modes = item
75ba991379Sopenharmony_ci            if key == "start-cmd":
76ba991379Sopenharmony_ci                self._start_cmd_list = item
77ba991379Sopenharmony_ci
78ba991379Sopenharmony_ci    def _check_condition_start_mode(self, cmd_list, service_name, passed):
79ba991379Sopenharmony_ci        if service_name in self._condition_list and service_name in cmd_list:
80ba991379Sopenharmony_ci            pass
81ba991379Sopenharmony_ci        else:
82ba991379Sopenharmony_ci            self.warn("\'%s\' cannot be started in conditional mode" % service_name)
83ba991379Sopenharmony_ci        return passed
84ba991379Sopenharmony_ci
85ba991379Sopenharmony_ci
86ba991379Sopenharmony_ci    def _check_service(self, parser):
87ba991379Sopenharmony_ci        boot_passed = True
88ba991379Sopenharmony_ci        condition_passed = True
89ba991379Sopenharmony_ci        start_cmd_list = self._get_start_cmds(parser).keys()
90ba991379Sopenharmony_ci        for key, item in parser._services.items():
91ba991379Sopenharmony_ci            if item.get("start_mode") == "boot":
92ba991379Sopenharmony_ci                if key not in self._boot_list:
93ba991379Sopenharmony_ci                    self.warn("\'%s\' cannot be started in boot mode" % key)
94ba991379Sopenharmony_ci            elif item.get("on_demand") is not True and item.get("start_mode") == "condition":
95ba991379Sopenharmony_ci                condition_passed = self._check_condition_start_mode(start_cmd_list, key, condition_passed)
96ba991379Sopenharmony_ci        return boot_passed and condition_passed
97ba991379Sopenharmony_ci
98ba991379Sopenharmony_ci    def _check_file_id_in_cmds(self, cmdlist, cmdline):
99ba991379Sopenharmony_ci        file_id_list = set()
100ba991379Sopenharmony_ci        for _, cmd in enumerate(cmdlist):
101ba991379Sopenharmony_ci            if cmdline == cmd["name"]:
102ba991379Sopenharmony_ci                file_id_list.add(cmd["fileId"])
103ba991379Sopenharmony_ci        return file_id_list
104ba991379Sopenharmony_ci
105ba991379Sopenharmony_ci    def _check_cmdline_in_parser(self, parser):
106ba991379Sopenharmony_ci        passed = True
107ba991379Sopenharmony_ci        cmdline = []
108ba991379Sopenharmony_ci        file_id_list = set()
109ba991379Sopenharmony_ci        parser_cmds = parser._cmds
110ba991379Sopenharmony_ci
111ba991379Sopenharmony_ci        for cmd in self._cmds:
112ba991379Sopenharmony_ci            cmdline = cmd["cmd"]
113ba991379Sopenharmony_ci            file_id_list = self._check_file_id_in_cmds(parser_cmds, cmdline)
114ba991379Sopenharmony_ci            file_lists = cmd["location"]
115ba991379Sopenharmony_ci            for key, item in parser._files.items():
116ba991379Sopenharmony_ci                if item["fileId"] in file_id_list and key not in file_lists:
117ba991379Sopenharmony_ci                    output = "\'{}\' is timeout command, in {}".format(cmd["cmd"], key)
118ba991379Sopenharmony_ci                    self.error("%s" % str(output))
119ba991379Sopenharmony_ci                    passed = False
120ba991379Sopenharmony_ci            file_id_list.clear()
121ba991379Sopenharmony_ci        return passed
122ba991379Sopenharmony_ci
123ba991379Sopenharmony_ci    def _check_selinux(self, parser):
124ba991379Sopenharmony_ci        if parser._selinux != 'enforcing':
125ba991379Sopenharmony_ci            self.warn("selinux status is %s" % parser._selinux)
126ba991379Sopenharmony_ci            return True
127ba991379Sopenharmony_ci
128ba991379Sopenharmony_ci        passed = True
129ba991379Sopenharmony_ci        for key, item in parser._services.items():
130ba991379Sopenharmony_ci            if item.get("secon") == "":
131ba991379Sopenharmony_ci                output_str = "%s \'secon\' is empty" % key
132ba991379Sopenharmony_ci                self.error("%s" % str(output_str))
133ba991379Sopenharmony_ci                passed = False
134ba991379Sopenharmony_ci        return passed
135ba991379Sopenharmony_ci
136ba991379Sopenharmony_ci    def _check_start_cmd(self, parser):
137ba991379Sopenharmony_ci        passed = True
138ba991379Sopenharmony_ci        start_cmd_list = self._get_start_cmds(parser)
139ba991379Sopenharmony_ci        for cmd, file_id in start_cmd_list.items():
140ba991379Sopenharmony_ci            if cmd in list(self._start_cmd_list):
141ba991379Sopenharmony_ci                pass
142ba991379Sopenharmony_ci            else:
143ba991379Sopenharmony_ci                for key, item in parser._files.items():
144ba991379Sopenharmony_ci                    if item["fileId"] == file_id:
145ba991379Sopenharmony_ci                        log_str = "{} is not in start cmd list. path:{}".format(cmd, item["file_name"])
146ba991379Sopenharmony_ci                        self.warn("%s" % log_str)
147ba991379Sopenharmony_ci                        passed = False
148ba991379Sopenharmony_ci                    pass
149ba991379Sopenharmony_ci        return passed
150