File: main.go

package info (click to toggle)
singularity-container 4.1.5%2Bds4-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 43,876 kB
  • sloc: asm: 14,840; sh: 3,190; ansic: 1,751; awk: 414; makefile: 413; python: 99
file content (66 lines) | stat: -rw-r--r-- 1,977 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
// Copyright (c) 2020-2021, Sylabs Inc. All rights reserved.
// This software is licensed under a 3-clause BSD license. Please consult the
// LICENSE.md file distributed with the sources of this project regarding your
// rights to use or distribute this software.

package main

import (
	"fmt"
	"log/syslog"
	"os"

	"github.com/spf13/cobra"
	"github.com/sylabs/singularity/v4/pkg/cmdline"
	pluginapi "github.com/sylabs/singularity/v4/pkg/plugin"
	clicallback "github.com/sylabs/singularity/v4/pkg/plugin/callback/cli"
	"github.com/sylabs/singularity/v4/pkg/sylog"
)

// Plugin is the only variable which a plugin MUST export.
// This symbol is accessed by the plugin framework to initialize the plugin
var Plugin = pluginapi.Plugin{
	Manifest: pluginapi.Manifest{
		Name:        "github.com/sylabs/singularity/log-plugin",
		Author:      "Sylabs Team",
		Version:     "0.2.0",
		Description: "Log executed CLI commands to syslog",
	},
	Callbacks: []pluginapi.Callback{
		(clicallback.Command)(logCommand),
	},
}

func logCommand(manager *cmdline.CommandManager) {
	rootCmd := manager.GetRootCmd()

	// Keep track of an existing PreRunE so we can call it
	f := rootCmd.PersistentPreRunE

	// The log action is added as a PreRunE on the main `singularity` root command
	// so we can log anything a user does with `singularity`.
	rootCmd.PersistentPreRunE = func(c *cobra.Command, args []string) error {
		uid := os.Getuid()
		gid := os.Getgid()
		command := c.Name()
		msg := fmt.Sprintf("UID=%d GID=%d COMMAND=%s ARGS=%v", uid, gid, command, args)

		// This logger never errors, only warns, if it fails to write to syslog
		w, err := syslog.New(syslog.LOG_INFO, "singularity")
		if err != nil {
			sylog.Warningf("Could not create syslog: %v", err)
		} else {
			defer w.Close()
			if err := w.Info(msg); err != nil {
				sylog.Warningf("Could not write to syslog: %v", err)
			}
		}

		// Call any existing PreRunE
		if f != nil {
			return f(c, args)
		}

		return nil
	}
}