mirror of
https://github.com/Ascend/ascend-docker-runtime.git
synced 2025-10-11 18:20:08 +08:00
Match-id-0354e63b9bb8c86b7d8b9f14eba3884b6a7da21c
This commit is contained in:
@@ -21,6 +21,7 @@
|
||||
#define BUF_SIZE 1024
|
||||
#define MAX_DEVICE_NR 1024
|
||||
#define MAX_MOUNT_NR 512
|
||||
#define WHITE_LIST_NUM 4
|
||||
|
||||
#define ROOT_UID 0
|
||||
|
||||
|
116
cli/src/main.c
116
cli/src/main.c
@@ -12,6 +12,7 @@
|
||||
#include <sched.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <ctype.h>
|
||||
#include "securec.h"
|
||||
|
||||
#include "basic.h"
|
||||
@@ -51,6 +52,12 @@ static bool DevicesCmdArgParser(struct CmdArgs *args, const char *arg)
|
||||
Logger("args, arg pointer is null!", LEVEL_ERROR, SCREEN_YES);
|
||||
return false;
|
||||
}
|
||||
for (size_t iLoop = 0; iLoop < strlen(arg); iLoop++) {
|
||||
if ((isdigit(arg[iLoop]) == 0) && (arg[iLoop] != ',')) {
|
||||
Logger("failed to check devices.", LEVEL_ERROR, SCREEN_YES);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
errno_t err = strcpy_s(args->devices, BUF_SIZE, arg);
|
||||
if (err != EOK) {
|
||||
@@ -63,27 +70,71 @@ static bool DevicesCmdArgParser(struct CmdArgs *args, const char *arg)
|
||||
|
||||
static bool PidCmdArgParser(struct CmdArgs *args, const char *arg)
|
||||
{
|
||||
char buff[PATH_MAX] = {0};
|
||||
|
||||
if (args == NULL || arg == NULL) {
|
||||
Logger("args, arg pointer is null!", LEVEL_ERROR, SCREEN_YES);
|
||||
return false;
|
||||
}
|
||||
|
||||
errno = 0;
|
||||
args->pid = strtol(optarg, NULL, DECIMAL);
|
||||
const char* pidMax = "/proc/sys/kernel/pid_max";
|
||||
const size_t maxFileSzieMb = 10; // max 10MB
|
||||
if (!CheckExternalFile(pidMax, strlen(pidMax), maxFileSzieMb, true)) {
|
||||
Logger("failed to check pid_max path.", LEVEL_ERROR, SCREEN_YES);
|
||||
return false;
|
||||
}
|
||||
FILE* pFile = NULL;
|
||||
pFile = fopen(pidMax, "r");
|
||||
if ((pFile == NULL) || (fgets(buff, PATH_MAX, pFile) == NULL)) {
|
||||
Logger("failed to get pid_max buff.", LEVEL_ERROR, SCREEN_YES);
|
||||
return false;
|
||||
}
|
||||
(void)fclose(pFile);
|
||||
if ((strlen(buff) > 0) && (buff[strlen(buff) -1] == '\n')) {
|
||||
buff[strlen(buff) -1] = '\0';
|
||||
}
|
||||
for (size_t iLoop = 0; iLoop < strlen(buff); iLoop++) {
|
||||
if (isdigit(buff[iLoop]) == 0) {
|
||||
Logger("failed to get pid_max value.", LEVEL_ERROR, SCREEN_YES);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if ((args->pid < 0) || (args->pid >= strtol(buff, NULL, DECIMAL))) {
|
||||
Logger("The PID out of bounds.", LEVEL_ERROR, SCREEN_YES);
|
||||
return false;
|
||||
}
|
||||
if (errno != 0) {
|
||||
char* str = FormatLogMessage("failed to convert pid string from cmd args, pid string: %s.", arg);
|
||||
Logger(str, LEVEL_ERROR, SCREEN_YES);
|
||||
free(str);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (args->pid <= 0) {
|
||||
char* str = FormatLogMessage("invalid pid %d.", args->pid);
|
||||
Logger(str, LEVEL_ERROR, SCREEN_YES);
|
||||
free(str);
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool CheckFileLegality(const char* filePath, const size_t filePathLen,
|
||||
const size_t maxFileSzieMb)
|
||||
{
|
||||
if ((filePathLen > PATH_MAX) || (filePathLen <= 0)) { // 长度越界
|
||||
Logger("filePathLen out of bounds!", LEVEL_ERROR, SCREEN_YES);
|
||||
return false;
|
||||
}
|
||||
for (size_t iLoop = 0; iLoop < filePathLen; iLoop++) {
|
||||
if (!IsValidChar(filePath[iLoop])) { // 非法字符
|
||||
Logger("filePath has an illegal character!", LEVEL_ERROR, SCREEN_YES);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
char resolvedPath[PATH_MAX] = {0};
|
||||
if (realpath(filePath, resolvedPath) == NULL && errno != ENOENT) {
|
||||
Logger("realpath failed!", LEVEL_ERROR, SCREEN_YES);
|
||||
return false;
|
||||
}
|
||||
if (strstr(resolvedPath, filePath) == NULL) { // 存在软链接
|
||||
Logger("filePath has a soft link!", LEVEL_ERROR, SCREEN_YES);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -99,6 +150,11 @@ static bool RootfsCmdArgParser(struct CmdArgs *args, const char *arg)
|
||||
Logger("failed to get rootfs path from cmd args", LEVEL_ERROR, SCREEN_YES);
|
||||
return false;
|
||||
}
|
||||
const size_t maxFileSzieMb = 50; // max 50MB
|
||||
if (!CheckFileLegality(args->rootfs, strlen(args->rootfs), maxFileSzieMb)) {
|
||||
Logger("failed to check rootf.", LEVEL_ERROR, SCREEN_YES);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -116,6 +172,35 @@ static bool OptionsCmdArgParser(struct CmdArgs *args, const char *arg)
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((strcmp(args->options, "NODRV,VIRTUAL") != 0) &&
|
||||
(strcmp(args->options, "NODRV") != 0) &&
|
||||
(strcmp(args->options, "VIRTUAL") != 0)) {
|
||||
Logger("Whitelist check failed.", LEVEL_ERROR, SCREEN_YES);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool CheckWhiteList(const char* fileName)
|
||||
{
|
||||
bool fileExists = false;
|
||||
const char mountWhiteList[WHITE_LIST_NUM][PATH_MAX] = {{"/usr/local/Ascend/driver/lib64"},
|
||||
{"/usr/local/Ascend/driver/include"},
|
||||
{"/usr/local/dcmi"},
|
||||
{"/usr/local/bin/npu-smi"}};
|
||||
|
||||
for (size_t iLoop = 0; iLoop < WHITE_LIST_NUM; iLoop++) {
|
||||
if (strcmp(mountWhiteList[iLoop], fileName) == 0) {
|
||||
fileExists = true;
|
||||
}
|
||||
}
|
||||
if (!fileExists) {
|
||||
char* str = FormatLogMessage("failed to check whiteList value: %s.", fileName);
|
||||
Logger(str, LEVEL_ERROR, SCREEN_YES);
|
||||
free(str);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -142,7 +227,15 @@ static bool MountFileCmdArgParser(struct CmdArgs *args, const char *arg)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
const size_t maxFileSzieMb = 50; // max 50MB
|
||||
if (!CheckFileLegality(dst, strlen(dst), maxFileSzieMb)) {
|
||||
char* str = FormatLogMessage("failed to check files: %s", dst);
|
||||
Logger(str, LEVEL_ERROR, SCREEN_YES);
|
||||
free(str);
|
||||
return false;
|
||||
}
|
||||
|
||||
return CheckWhiteList(dst) ? true : false;
|
||||
}
|
||||
|
||||
static bool MountDirCmdArgParser(struct CmdArgs *args, const char *arg)
|
||||
@@ -167,8 +260,13 @@ static bool MountDirCmdArgParser(struct CmdArgs *args, const char *arg)
|
||||
free(str);
|
||||
return false;
|
||||
}
|
||||
const size_t maxFileSzieMb = 50; // max 50MB
|
||||
if (!CheckFileLegality(dst, strlen(dst), maxFileSzieMb)) {
|
||||
Logger("failed to check dir.", LEVEL_ERROR, SCREEN_YES);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return CheckWhiteList(dst) ? true : false;
|
||||
}
|
||||
|
||||
#define NUM_OF_CMD_ARGS 6
|
||||
|
@@ -31,10 +31,9 @@ int Mount(const char *src, const char *dst)
|
||||
((S_ISREG(fileStat.st_mode) != 0) || (S_ISDIR(fileStat.st_mode) != 0))) { // 只校验文件和目录
|
||||
const size_t maxFileSzieMb = 10 * 1024; // max 10 G
|
||||
if (!CheckExternalFile(src, strlen(src), maxFileSzieMb, false)) {
|
||||
char* str = FormatLogMessage("failed to mount src hehe:%s.", src);
|
||||
char* str = FormatLogMessage("failed to Check src: %s.", src);
|
||||
Logger(str, LEVEL_ERROR, SCREEN_YES);
|
||||
free(str);
|
||||
Logger("failed to Check src.", LEVEL_ERROR, SCREEN_YES);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
@@ -223,19 +223,30 @@ static bool CheckLegality(const char* resolvedPath, const size_t resolvedPathLen
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IsValidChar(const char c)
|
||||
{
|
||||
if (isalnum(c) != 0) {
|
||||
return true;
|
||||
}
|
||||
// ._-/~为合法字符
|
||||
if ((c == '.') || (c == '_') ||
|
||||
(c == '-') || (c == '/') || (c == '~')) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CheckExternalFile(const char* filePath, const size_t filePathLen,
|
||||
const size_t maxFileSzieMb, const bool checkOwner)
|
||||
{
|
||||
int iLoop;
|
||||
if ((filePathLen > PATH_MAX) || (filePathLen <= 0)) { // 长度越界
|
||||
return ShowExceptionInfo("filePathLen out of bounds!");
|
||||
}
|
||||
if (strstr(filePath, "..") != NULL) { // 存在".."
|
||||
return ShowExceptionInfo("filePath has an illegal character!");
|
||||
}
|
||||
for (iLoop = 0; iLoop < filePathLen; iLoop++) {
|
||||
if ((isalnum(filePath[iLoop]) == 0) && (filePath[iLoop] != '.') && (filePath[iLoop] != '_') &&
|
||||
(filePath[iLoop] != '-') && (filePath[iLoop] != '/') && (filePath[iLoop] != '~')) { // 非法字符
|
||||
for (size_t iLoop = 0; iLoop < filePathLen; iLoop++) {
|
||||
if (!IsValidChar(filePath[iLoop])) { // 非法字符
|
||||
return ShowExceptionInfo("filePath has an illegal character!");
|
||||
}
|
||||
}
|
||||
|
@@ -22,6 +22,7 @@ int CheckDirExists(const char *dir);
|
||||
int GetParentPathStr(const char *path, char *parent, size_t bufSize);
|
||||
int MakeDirWithParent(const char *path, mode_t mode);
|
||||
int MakeMountPoints(const char *path, mode_t mode);
|
||||
bool IsValidChar(const char c);
|
||||
bool CheckExternalFile(const char* filePath, const size_t filePathLen,
|
||||
const size_t maxFileSzieMb, const bool checkOwner);
|
||||
|
||||
|
@@ -841,21 +841,6 @@ TEST(SetupCgroup, StatusThree)
|
||||
EXPECT_EQ(-1, ret);
|
||||
}
|
||||
|
||||
TEST(SetupCgroup, StatusFour)
|
||||
{
|
||||
MOCKER(SetupDriverCgroup).stubs().will(invoke(Stub_SetupDriverCgroup_Success));
|
||||
MOCKER(SetupDeviceCgroup).stubs().will(invoke(Stub_SetupDeviceCgroup_Success));
|
||||
struct ParsedConfig config;
|
||||
(void)strcpy_s(config.rootfs, sizeof(config.rootfs), "/home");
|
||||
config.devices[0] = 1;
|
||||
config.devices[1] = 2;
|
||||
config.devicesNr = 2;
|
||||
(void)strcpy_s(config.cgroupPath, sizeof(config.cgroupPath), "devices.allow");
|
||||
int ret = SetupCgroup(&config);
|
||||
GlobalMockObject::verify();
|
||||
EXPECT_EQ(0, ret);
|
||||
}
|
||||
|
||||
TEST(SetupContainer, StatusOne)
|
||||
{
|
||||
struct CmdArgs args;
|
||||
|
@@ -193,7 +193,7 @@ var getContainerConfig = func() (*containerConfig, error) {
|
||||
}
|
||||
|
||||
configPath := path.Join(state.Bundle, "config.json")
|
||||
if _, err := mindxcheckutils.FileChecker(configPath, false, false, 0); err != nil {
|
||||
if _, err := mindxcheckutils.FileChecker(configPath, false, false, true, 0); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -239,7 +239,7 @@ func readMountConfig(dir string, name string) ([]string, []string, error) {
|
||||
}
|
||||
|
||||
fileInfo, err := os.Stat(baseConfigFilePath)
|
||||
if _, err := mindxcheckutils.FileChecker(baseConfigFilePath, false, true, 0); err != nil {
|
||||
if _, err := mindxcheckutils.FileChecker(baseConfigFilePath, false, true, false, 0); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
if err != nil {
|
||||
@@ -346,7 +346,7 @@ func doPrestartHook() error {
|
||||
if _, err = os.Stat(cliPath); err != nil {
|
||||
return fmt.Errorf("cannot find ascend-docker-cli executable file at %s: %v", cliPath, err)
|
||||
}
|
||||
if _, err := mindxcheckutils.FileChecker(cliPath, false, true, 0); err != nil {
|
||||
if _, err := mindxcheckutils.FileChecker(cliPath, false, true, false, 0); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
@@ -326,19 +326,30 @@ static bool CheckLegality(const char* resolvedPath, const size_t resolvedPathLen
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool IsValidChar(const char c)
|
||||
{
|
||||
if (isalnum(c) != 0) {
|
||||
return true;
|
||||
}
|
||||
// ._-/~为合法字符
|
||||
if ((c == '.') || (c == '_') ||
|
||||
(c == '-') || (c == '/') || (c == '~')) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool CheckExternalFile(const char* filePath, const size_t filePathLen,
|
||||
const size_t maxFileSzieMb, const bool checkOwner)
|
||||
{
|
||||
int iLoop;
|
||||
if ((filePathLen > PATH_MAX) || (filePathLen <= 0)) { // 长度越界
|
||||
return ShowExceptionInfo("filePathLen out of bounds!");
|
||||
}
|
||||
if (strstr(filePath, "..") != NULL) { // 存在".."
|
||||
return ShowExceptionInfo("filePath has an illegal character!");
|
||||
}
|
||||
for (iLoop = 0; iLoop < filePathLen; iLoop++) {
|
||||
if ((isalnum(filePath[iLoop]) == 0) && (filePath[iLoop] != '.') && (filePath[iLoop] != '_') &&
|
||||
(filePath[iLoop] != '-') && (filePath[iLoop] != '/') && (filePath[iLoop] != '~')) { // 非法字符
|
||||
for (size_t iLoop = 0; iLoop < filePathLen; iLoop++) {
|
||||
if (!IsValidChar(filePath[iLoop])) { // 非法字符
|
||||
return ShowExceptionInfo("filePath has an illegal character!");
|
||||
}
|
||||
}
|
||||
|
@@ -1,8 +1,7 @@
|
||||
// Package mindxcheckutils is a check utils package
|
||||
/**
|
||||
* Copyright (c) Huawei Technologies Co., Ltd. 2020-2022. All rights reserved.
|
||||
*/
|
||||
|
||||
// Package mindxcheckutils is a check utils package
|
||||
package mindxcheckutils
|
||||
|
||||
import (
|
||||
@@ -14,7 +13,7 @@ import (
|
||||
)
|
||||
|
||||
// FileChecker check if a file/dir is safe to use
|
||||
func FileChecker(path string, allowDir, checkParent bool, deep int) (bool, error) {
|
||||
func FileChecker(path string, allowDir, checkParent, allowLink bool, deep int) (bool, error) {
|
||||
const maxDepth, groupWriteIndex, otherWriteIndex, permLength int = 99, 5, 8, 10
|
||||
if deep > maxDepth {
|
||||
return false, fmt.Errorf("over maxDepth %v", maxDepth)
|
||||
@@ -26,7 +25,7 @@ func FileChecker(path string, allowDir, checkParent bool, deep int) (bool, error
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("get abs path failed %v", err)
|
||||
}
|
||||
fileInfo, ok, err := normalFileCheck(filePath, allowDir)
|
||||
fileInfo, ok, err := normalFileCheck(filePath, allowDir, allowLink)
|
||||
if err != nil {
|
||||
return ok, err
|
||||
}
|
||||
@@ -52,14 +51,14 @@ func FileChecker(path string, allowDir, checkParent bool, deep int) (bool, error
|
||||
return false, fmt.Errorf("owner not right %v %v", filePath, uid)
|
||||
}
|
||||
if filePath != "/" && checkParent {
|
||||
return FileChecker(filepath.Dir(filePath), true, true, deep+1)
|
||||
return FileChecker(filepath.Dir(filePath), true, true, allowLink, deep+1)
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func normalFileCheck(filePath string, allowDir bool) (os.FileInfo, bool, error) {
|
||||
func normalFileCheck(filePath string, allowDir bool, allowLink bool) (os.FileInfo, bool, error) {
|
||||
realPath, err := filepath.EvalSymlinks(filePath)
|
||||
if err != nil || realPath != filePath {
|
||||
if err != nil || (realPath != filePath && !allowLink) {
|
||||
return nil, false, fmt.Errorf("symlinks or not existed, failed %v, %v", filePath, err)
|
||||
}
|
||||
fileInfo, err := os.Stat(filePath)
|
||||
|
@@ -1,8 +1,7 @@
|
||||
/*
|
||||
// Package mindxcheckutils is a check utils package
|
||||
/**
|
||||
* Copyright (c) Huawei Technologies Co., Ltd. 2020-2022. All rights reserved.
|
||||
*/
|
||||
|
||||
// Package mindxcheckutils is a check utils package
|
||||
package mindxcheckutils
|
||||
|
||||
import (
|
||||
@@ -19,27 +18,27 @@ func TestNormalFileCheckRegularFile(t *testing.T) {
|
||||
t.Fatalf("create symlink failed %q: %s", filePath, err)
|
||||
}
|
||||
|
||||
if _, _, err = normalFileCheck(tmpDir, true); err != nil {
|
||||
if _, _, err = normalFileCheck(tmpDir, true, false); err != nil {
|
||||
t.Fatalf("check allow dir failed %q: %s", tmpDir+"/__test__", err)
|
||||
}
|
||||
|
||||
if _, _, err = normalFileCheck(tmpDir, false); !strings.Contains(err.Error(), "not regular file") {
|
||||
if _, _, err = normalFileCheck(tmpDir, false, false); !strings.Contains(err.Error(), "not regular file") {
|
||||
t.Fatalf("check not allow dir failed %q: %s", tmpDir+"/__test__", err)
|
||||
}
|
||||
|
||||
if _, _, err = normalFileCheck("/dev/zero", true); !strings.Contains(err.Error(), "not regular file/dir") {
|
||||
if _, _, err = normalFileCheck("/dev/zero", true, false); !strings.Contains(err.Error(), "not regular file/dir") {
|
||||
t.Fatalf("check /dev/zero failed %q: %s", tmpDir+"/__test__", err)
|
||||
}
|
||||
|
||||
if _, _, err = normalFileCheck(tmpDir+"/syslink", false); !strings.Contains(err.Error(), "symlinks") {
|
||||
if _, _, err = normalFileCheck(tmpDir+"/syslink", false, false); !strings.Contains(err.Error(), "symlinks") {
|
||||
t.Fatalf("check symlinks failed %q: %s", tmpDir+"/syslink", err)
|
||||
}
|
||||
|
||||
if _, _, err = normalFileCheck(filePath, false); err != nil {
|
||||
if _, _, err = normalFileCheck(filePath, false, false); err != nil {
|
||||
t.Fatalf("check failed %q: %s", filePath, err)
|
||||
}
|
||||
|
||||
if _, _, err = normalFileCheck(tmpDir+"/notexisted", false); !strings.Contains(err.Error(), "not existed") {
|
||||
if _, _, err = normalFileCheck(tmpDir+"/notexisted", false, false); !strings.Contains(err.Error(), "not existed") {
|
||||
t.Fatalf("check symlinks failed %q: %s", tmpDir+"/syslink", err)
|
||||
}
|
||||
}
|
||||
@@ -52,15 +51,16 @@ func TestFileCheckRegularFile(t *testing.T) {
|
||||
t.Fatalf("create symlink failed %q: %s", filePath, err)
|
||||
}
|
||||
|
||||
if _, err = FileChecker(tmpDir, true, false, 0); err != nil {
|
||||
if _, err = FileChecker(tmpDir, true, false, false, 0); err != nil {
|
||||
t.Fatalf("check allow dir failed %q: %s", tmpDir+"/__test__", err)
|
||||
}
|
||||
|
||||
if _, err = FileChecker(tmpDir, false, false, 0); err != nil && !strings.Contains(err.Error(), "not regular file") {
|
||||
if _, err = FileChecker(tmpDir, false, false, false, 0); err != nil &&
|
||||
!strings.Contains(err.Error(), "not regular file") {
|
||||
t.Fatalf("check not allow dir failed %q: %s", tmpDir+"/__test__", err)
|
||||
}
|
||||
|
||||
if _, err = FileChecker("/dev/zero", true, false, 0); err != nil &&
|
||||
if _, err = FileChecker("/dev/zero", true, false, false, 0); err != nil &&
|
||||
!strings.Contains(err.Error(), "not regular file/dir") {
|
||||
t.Fatalf("check /dev/zero failed %q: %s", tmpDir+"/__test__", err)
|
||||
}
|
||||
|
@@ -65,7 +65,7 @@ var execRunc = func() error {
|
||||
return fmt.Errorf("failed to find the path of runc: %v", err)
|
||||
}
|
||||
}
|
||||
if _, err := mindxcheckutils.FileChecker(runcPath, false, true, 0); err != nil {
|
||||
if _, err := mindxcheckutils.FileChecker(runcPath, false, true, false, 0); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -83,7 +83,7 @@ func addHook(spec *specs.Spec) error {
|
||||
}
|
||||
|
||||
hookCliPath = path.Join(path.Dir(currentExecPath), hookCli)
|
||||
if _, err := mindxcheckutils.FileChecker(hookCliPath, false, true, 0); err != nil {
|
||||
if _, err := mindxcheckutils.FileChecker(hookCliPath, false, true, false, 0); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err = os.Stat(hookCliPath); err != nil {
|
||||
@@ -114,7 +114,7 @@ func modifySpecFile(path string) error {
|
||||
if err != nil {
|
||||
return fmt.Errorf("spec file doesnt exist %s: %v", path, err)
|
||||
}
|
||||
if _, err := mindxcheckutils.FileChecker(path, false, true, 0); err != nil {
|
||||
if _, err := mindxcheckutils.FileChecker(path, false, true, true, 0); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user