...

Source file src/github.com/chaos-mesh/chaos-mesh/pkg/bpm/build_linux.go

Documentation: github.com/chaos-mesh/chaos-mesh/pkg/bpm

     1  // Copyright 2021 Chaos Mesh Authors.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  // http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  //
    15  
    16  package bpm
    17  
    18  import (
    19  	"context"
    20  	"os/exec"
    21  	"strconv"
    22  	"strings"
    23  	"syscall"
    24  
    25  	"github.com/chaos-mesh/chaos-mesh/pkg/mock"
    26  )
    27  
    28  // Build builds the command
    29  // the ctx argument passes the context information to this function
    30  // e.g. the corresponding resource name.
    31  func (b *CommandBuilder) Build(ctx context.Context) *ManagedCommand {
    32  	log := b.getLoggerFromContext(ctx)
    33  	args := b.args
    34  	cmd := b.cmd
    35  
    36  	if len(b.nsOptions) > 0 {
    37  		args = append([]string{"--", cmd}, args...)
    38  		for _, option := range b.nsOptions {
    39  			args = append([]string{"-" + nsArgMap[option.Typ], option.Path}, args...)
    40  		}
    41  
    42  		if b.localMnt {
    43  			args = append([]string{"-l"}, args...)
    44  		}
    45  		cmd = nsexecPath
    46  	}
    47  
    48  	if b.oomScoreAdj != 0 {
    49  		args = append([]string{"-n", strconv.Itoa(b.oomScoreAdj), "--", cmd}, args...)
    50  		cmd = "choom"
    51  	}
    52  
    53  	// pause should always be the first command to execute because the
    54  	// `stress_server` will check whether the /proc/PID/comm is `pause` to
    55  	// determine whether it should continue to send `SIGCONT`. If the first
    56  	// command is not `pause`, the real `pause` program may not receive the
    57  	// command successfully.
    58  	if b.pause {
    59  		args = append([]string{cmd}, args...)
    60  		cmd = pausePath
    61  	}
    62  
    63  	if c := mock.On("MockProcessBuild"); c != nil {
    64  		f := c.(func(context.Context, string, ...string) *exec.Cmd)
    65  		return &ManagedCommand{
    66  			Cmd:        f(b.ctx, cmd, args...),
    67  			Identifier: b.identifier,
    68  		}
    69  	}
    70  
    71  	log.Info("build command", "command", cmd+" "+strings.Join(args, " "))
    72  
    73  	command := exec.CommandContext(b.ctx, cmd, args...)
    74  	command.Env = b.env
    75  	command.SysProcAttr = &syscall.SysProcAttr{}
    76  	command.SysProcAttr.Pdeathsig = syscall.SIGTERM
    77  
    78  	if b.stdin != nil {
    79  		command.Stdin = b.stdin
    80  	}
    81  
    82  	if b.stdout != nil {
    83  		command.Stdout = b.stdout
    84  	}
    85  
    86  	if b.stderr != nil {
    87  		command.Stderr = b.stderr
    88  	}
    89  
    90  	return &ManagedCommand{
    91  		Cmd:        command,
    92  		Identifier: b.identifier,
    93  	}
    94  }
    95