...

Source file src/github.com/in-toto/in-toto-golang/cmd/run.go

Documentation: github.com/in-toto/in-toto-golang/cmd

     1  package cmd
     2  
     3  import (
     4  	"fmt"
     5  	"path/filepath"
     6  
     7  	intoto "github.com/in-toto/in-toto-golang/in_toto"
     8  	"github.com/spf13/cobra"
     9  )
    10  
    11  var (
    12  	stepName       string
    13  	runDir         string
    14  	materialsPaths []string
    15  	productsPaths  []string
    16  	noCommand      bool
    17  )
    18  
    19  var runCmd = &cobra.Command{
    20  	Use:   "run",
    21  	Short: "Executes the passed command and records paths and hashes of 'materials'",
    22  	Long: `Executes the passed command and records paths and hashes of 'materials' (i.e.
    23  files before command execution) and 'products' (i.e. files after command
    24  execution) and stores them together with other information (executed command,
    25  return value, stdout, stderr, ...) to a link metadata file, which is signed
    26  with the passed key.  Returns nonzero value on failure and zero otherwise.`,
    27  	Args:    cobra.MinimumNArgs(0),
    28  	PreRunE: getKeyCert,
    29  	RunE:    run,
    30  }
    31  
    32  func init() {
    33  	rootCmd.AddCommand(runCmd)
    34  
    35  	runCmd.Flags().StringVarP(
    36  		&stepName,
    37  		"name",
    38  		"n",
    39  		"",
    40  		`Name used to associate the resulting link metadata
    41  with the corresponding step defined in an in-toto layout.`,
    42  	)
    43  
    44  	runCmd.Flags().StringVarP(
    45  		&runDir,
    46  		"run-dir",
    47  		"r",
    48  		"",
    49  		`runDir specifies the working directory of the command.
    50  If runDir is the empty string, the command will run in the
    51  calling process's current directory. The runDir directory must
    52  exist, be writable, and not be a symlink.`,
    53  	)
    54  
    55  	runCmd.Flags().StringVarP(
    56  		&keyPath,
    57  		"key",
    58  		"k",
    59  		"",
    60  		`Path to a PEM formatted private key file used to sign
    61  the resulting link metadata.`,
    62  	)
    63  
    64  	runCmd.Flags().StringVarP(
    65  		&certPath,
    66  		"cert",
    67  		"c",
    68  		"",
    69  		`Path to a PEM formatted certificate that corresponds with
    70  the provided key.`,
    71  	)
    72  
    73  	runCmd.Flags().StringArrayVarP(
    74  		&materialsPaths,
    75  		"materials",
    76  		"m",
    77  		[]string{},
    78  		`Paths to files or directories, whose paths and hashes
    79  are stored in the resulting link metadata before the
    80  command is executed. Symlinks are followed.`,
    81  	)
    82  
    83  	runCmd.Flags().StringArrayVarP(
    84  		&productsPaths,
    85  		"products",
    86  		"p",
    87  		[]string{},
    88  		`Paths to files or directories, whose paths and hashes
    89  are stored in the resulting link metadata after the
    90  command is executed. Symlinks are followed.`,
    91  	)
    92  
    93  	runCmd.Flags().StringVarP(
    94  		&outDir,
    95  		"metadata-directory",
    96  		"d",
    97  		"./",
    98  		`Directory to store link metadata`,
    99  	)
   100  
   101  	runCmd.Flags().StringArrayVarP(
   102  		&lStripPaths,
   103  		"lstrip-paths",
   104  		"l",
   105  		[]string{},
   106  		`Path prefixes used to left-strip artifact paths before storing
   107  them to the resulting link metadata. If multiple prefixes
   108  are specified, only a single prefix can match the path of
   109  any artifact and that is then left-stripped. All prefixes
   110  are checked to ensure none of them are a left substring
   111  of another.`,
   112  	)
   113  
   114  	runCmd.Flags().StringArrayVarP(
   115  		&exclude,
   116  		"exclude",
   117  		"e",
   118  		[]string{},
   119  		`Path patterns to match paths that should not be recorded as 0
   120  ‘materials’ or ‘products’. Passed patterns override patterns defined
   121  in environment variables or config files. See Config docs for details.`,
   122  	)
   123  
   124  	runCmd.MarkFlagRequired("name")
   125  
   126  	runCmd.Flags().BoolVar(
   127  		&lineNormalization,
   128  		"normalize-line-endings",
   129  		false,
   130  		`Enable line normalization in order to support different
   131  operating systems. It is done by replacing all line separators
   132  with a new line character.`,
   133  	)
   134  
   135  	runCmd.Flags().BoolVarP(
   136  		&noCommand,
   137  		"no-command",
   138  		"x",
   139  		false,
   140  		`Indicate that there is no command to be executed for the step.`,
   141  	)
   142  
   143  	runCmd.PersistentFlags().BoolVar(
   144  		&followSymlinkDirs,
   145  		"follow-symlink-dirs",
   146  		false,
   147  		`Follow symlinked directories to their targets. Note: this parameter
   148  toggles following linked directories only, linked files are always
   149  recorded independently of this parameter.`,
   150  	)
   151  
   152  	runCmd.PersistentFlags().BoolVar(
   153  		&useDSSE,
   154  		"use-dsse",
   155  		false,
   156  		"Create metadata using DSSE instead of the legacy signature wrapper.",
   157  	)
   158  
   159  	runCmd.Flags().StringVar(
   160  		&spiffeUDS,
   161  		"spiffe-workload-api-path",
   162  		"",
   163  		"UDS path for SPIFFE workload API",
   164  	)
   165  
   166  }
   167  
   168  func run(cmd *cobra.Command, args []string) error {
   169  	if noCommand && len(args) > 0 {
   170  		return fmt.Errorf("command arguments passed with --no-command/-x flag")
   171  	}
   172  
   173  	if !noCommand && len(args) == 0 {
   174  		return fmt.Errorf("no command arguments passed, please specify or use --no-command option")
   175  	}
   176  
   177  	metadata, err := intoto.InTotoRun(stepName, runDir, materialsPaths, productsPaths, args, key, []string{"sha256"}, exclude, lStripPaths, lineNormalization, followSymlinkDirs, useDSSE)
   178  	if err != nil {
   179  		return fmt.Errorf("failed to create link metadata: %w", err)
   180  	}
   181  
   182  	linkName := fmt.Sprintf(intoto.LinkNameFormat, metadata.GetPayload().(intoto.Link).Name, key.KeyID)
   183  
   184  	linkPath := filepath.Join(outDir, linkName)
   185  	err = metadata.Dump(linkPath)
   186  	if err != nil {
   187  		return fmt.Errorf("failed to write link metadata to %s: %w", linkPath, err)
   188  	}
   189  
   190  	return nil
   191  }
   192  

View as plain text