github.com/google/osv-scalibr@v0.4.1/extractor/filesystem/containers/podman/podman_linux.go (about)

     1  // Copyright 2025 Google LLC
     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  //go:build linux
    16  
    17  package podman
    18  
    19  import (
    20  	"context"
    21  	"fmt"
    22  	"path/filepath"
    23  	"strings"
    24  
    25  	"github.com/google/osv-scalibr/extractor"
    26  	"github.com/google/osv-scalibr/extractor/filesystem"
    27  	"github.com/google/osv-scalibr/inventory"
    28  )
    29  
    30  // FileRequired returns true if the specified file matches podman db file pattern.
    31  func (e Extractor) FileRequired(api filesystem.FileAPI) bool {
    32  	path := filepath.ToSlash(api.Path())
    33  
    34  	if strings.HasSuffix(path, "/containers/storage/db.sql") {
    35  		return true
    36  	}
    37  
    38  	if strings.HasSuffix(path, "/containers/storage/libpod/bolt_state.db") {
    39  		return true
    40  	}
    41  
    42  	return false
    43  }
    44  
    45  // Extract container inventory through the podman db file passed as the scan input.
    46  func (e Extractor) Extract(ctx context.Context, input *filesystem.ScanInput) (inventory.Inventory, error) {
    47  	path := filepath.Join(input.Root, input.Path)
    48  
    49  	state, err := getDBState(path)
    50  	if err != nil {
    51  		return inventory.Inventory{}, fmt.Errorf("error opening file: %s with error: %w", path, err)
    52  	}
    53  	defer state.Close()
    54  
    55  	ctrs, err := state.AllContainers()
    56  	if err != nil {
    57  		return inventory.Inventory{}, fmt.Errorf("error listing containers in file: %s with error: %w", path, err)
    58  	}
    59  
    60  	pkgs := make([]*extractor.Package, 0, len(ctrs))
    61  	for _, ctr := range ctrs {
    62  		if !e.cfg.IncludeStopped && ctr.state.Exited {
    63  			continue
    64  		}
    65  
    66  		pkgs = append(pkgs, &extractor.Package{
    67  			Name:      ctr.config.RawImageName,
    68  			Version:   ctr.config.RootfsImageID,
    69  			Locations: []string{input.Path},
    70  			Metadata: &Metadata{
    71  				ExposedPorts: ctr.config.ExposedPorts,
    72  				PID:          ctr.state.PID,
    73  				NameSpace:    ctr.config.Namespace,
    74  				StartedTime:  ctr.state.StartedTime,
    75  				FinishedTime: ctr.state.FinishedTime,
    76  				Status:       ctr.state.State.String(),
    77  				ExitCode:     ctr.state.ExitCode,
    78  				Exited:       ctr.state.Exited,
    79  			},
    80  		})
    81  	}
    82  	return inventory.Inventory{Packages: pkgs}, nil
    83  }