github.com/apptainer/singularity@v3.1.1+incompatible/cmd/internal/cli/key_pull.go (about)

     1  // Copyright (c) 2017-2019, Sylabs Inc. All rights reserved.
     2  // This software is licensed under a 3-clause BSD license. Please consult the
     3  // LICENSE.md file distributed with the sources of this project regarding your
     4  // rights to use or distribute this software.
     5  
     6  package cli
     7  
     8  import (
     9  	"fmt"
    10  	"os"
    11  
    12  	"github.com/spf13/cobra"
    13  	"github.com/sylabs/singularity/docs"
    14  	"github.com/sylabs/singularity/internal/pkg/sylog"
    15  	"github.com/sylabs/singularity/pkg/sypgp"
    16  )
    17  
    18  func init() {
    19  	KeyPullCmd.Flags().SetInterspersed(false)
    20  
    21  	KeyPullCmd.Flags().StringVarP(&keyServerURL, "url", "u", defaultKeyServer, "specify the key server URL")
    22  	KeyPullCmd.Flags().SetAnnotation("url", "envkey", []string{"URL"})
    23  }
    24  
    25  // KeyPullCmd is `singularity key pull' and fetches public keys from a key server
    26  var KeyPullCmd = &cobra.Command{
    27  	Args:                  cobra.ExactArgs(1),
    28  	DisableFlagsInUseLine: true,
    29  	PreRun:                sylabsToken,
    30  	Run: func(cmd *cobra.Command, args []string) {
    31  		if err := doKeyPullCmd(args[0], keyServerURL); err != nil {
    32  			sylog.Errorf("pull failed: %s", err)
    33  			os.Exit(2)
    34  		}
    35  	},
    36  
    37  	Use:     docs.KeyPullUse,
    38  	Short:   docs.KeyPullShort,
    39  	Long:    docs.KeyPullLong,
    40  	Example: docs.KeyPullExample,
    41  }
    42  
    43  func doKeyPullCmd(fingerprint string, url string) error {
    44  	var count int
    45  
    46  	// get matching keyring
    47  	el, err := sypgp.FetchPubkey(fingerprint, url, authToken, false)
    48  	if err != nil {
    49  		return err
    50  	}
    51  
    52  	elstore, err := sypgp.LoadPubKeyring()
    53  	if err != nil {
    54  		return err
    55  	}
    56  
    57  	// store in local cache
    58  	fp, err := os.OpenFile(sypgp.PublicPath(), os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0600)
    59  	if err != nil {
    60  		return err
    61  	}
    62  	defer fp.Close()
    63  
    64  	for _, e := range el {
    65  		storeKey := true
    66  		for _, estore := range elstore {
    67  			if e.PrimaryKey.KeyId == estore.PrimaryKey.KeyId {
    68  				storeKey = false // Entity is already in key store
    69  				break
    70  			}
    71  		}
    72  		if storeKey {
    73  			if err = e.Serialize(fp); err != nil {
    74  				return err
    75  			}
    76  			count++
    77  		}
    78  	}
    79  
    80  	fmt.Printf("%v key(s) fetched and stored in local cache %s\n", count, sypgp.PublicPath())
    81  
    82  	return nil
    83  }