diff --git a/Makefile b/Makefile index 603449c..1f63e7d 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ try: - snapcraft try + snapcraft try --use-lxd snap try prime sync: @@ -12,4 +12,4 @@ test: ./log \ ./snapctl \ ./env \ - ./options \ No newline at end of file + ./options diff --git a/README.md b/README.md index 3925184..2589471 100644 --- a/README.md +++ b/README.md @@ -88,7 +88,7 @@ sudo edgex-snap-hooks.test ./snapctl -run TestGet #### Development ``` -SNAPCRAFT_BUILD_ENVIRONMENT=lxd make try +make try ``` You can now edit the files locally, copy them to prime directory, and re-run the diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml index 50e898b..ec54379 100644 --- a/snap/snapcraft.yaml +++ b/snap/snapcraft.yaml @@ -7,6 +7,11 @@ description: This snap is used to run tests on this package grade: devel confinement: strict +plugs: + # Plug for testing snapctl commands + test-plug: + interface: content + target: $SNAP_DATA apps: # App for running the tests @@ -21,13 +26,12 @@ apps: install-mode: disable mock-service-2: *ms - parts: go: - ## Using stage go snap doesn't work, + ## Using stage go snap doesn't work, ## resulting in core dump when running go: # plugin: nil - # stage-snaps: + # stage-snaps: # - go/1.17 # organize: # '*': go/ diff --git a/snapctl/README.md b/snapctl/README.md index 24f57a7..029b015 100644 --- a/snapctl/README.md +++ b/snapctl/README.md @@ -1,12 +1,12 @@ # snapctl Go wrapper library for the [snapctl](https://snapcraft.io/docs/using-snapctl) tool. -Wrappers for following subcommands are implemented: +Wrappers for following subcommands are partially implemented for EdgeX use cases: - [ ] `fde-setup-request`: Obtain full disk encryption setup request - [ ] `fde-setup-result`: Set result for full disk encryption - [x] `get`: The get command prints configuration and interface connection settings. -- [ ] `is-connected`: Return success if the given plug or slot is connected, and failure otherwise +- [x] `is-connected`: Return success if the given plug or slot is connected, and failure otherwise - [ ] `reboot`: Control the reboot behavior of the system - [x] `restart`: Restart services - [x] `services`: Query the status of services @@ -96,4 +96,4 @@ func main() { panic(err) } } -``` \ No newline at end of file +``` diff --git a/snapctl/is-connected.go b/snapctl/is-connected.go new file mode 100644 index 0000000..fd88b89 --- /dev/null +++ b/snapctl/is-connected.go @@ -0,0 +1,85 @@ +/* +Usage: +snapctl [OPTIONS] is-connected [is-connected-OPTIONS] + + The is-connected command returns success if the given plug or slot of the + calling snap is connected, and failure otherwise. + + $ snapctl is-connected plug + $ echo $? + 1 + + Snaps can only query their own plugs and slots - snap name is implicit and + implied by the snapctl execution context. + + The --pid and --aparmor-label options can be used to determine whether + a plug or slot is connected to the snap identified by the given + process ID or AppArmor label. In this mode, additional failure exit + codes may be returned: 10 if the other snap is not connected but uses + classic confinement, or 11 if the other process is not snap confined. + + The --pid and --apparmor-label options may only be used with slots of + interface type "pulseaudio", "audio-record", or "cups-control". + + + Help Options: + -h, --help Show this help message + + [is-connected command options] + --pid= Process ID for a plausibly connected process + --apparmor-label= AppArmor label for a plausibly connected process + +*/ + +package snapctl + +import ( + "fmt" + "strings" +) + +type isConnected struct { + plug string + validators []func() error +} + +// IsConnected checks the connection status of a plug or slot +// It returns an object for setting the CLI arguments before running the command +func IsConnected(plug string) (cmd isConnected) { + cmd.plug = plug + + cmd.validators = append(cmd.validators, func() error { + if strings.Contains(plug, " ") { + return fmt.Errorf("plug must not contain spaces. Got: '%s'", plug) + } + + return nil + }) + + return cmd +} + +// Run executes the get command +func (cmd isConnected) Run() (bool, error) { + // validate all input + for _, validate := range cmd.validators { + if err := validate(); err != nil { + return false, err + } + } + + // construct the command args + // snapctl [OPTIONS] is-connected [is-connected-OPTIONS] + var args []string + + // plug + args = append(args, cmd.plug) + + out, err := run("is-connected", args...) + if err != nil && out == "" { + return false, nil + } else if err != nil { + return false, err + } + return true, nil +} diff --git a/snapctl/is-connected_test.go b/snapctl/is-connected_test.go new file mode 100644 index 0000000..21f9dbe --- /dev/null +++ b/snapctl/is-connected_test.go @@ -0,0 +1,19 @@ +package snapctl_test + +import ( + "testing" + + "github.com/canonical/edgex-snap-hooks/v3/snapctl" + "github.com/stretchr/testify/require" +) + +func TestIsConnected(t *testing.T) { + t.Run("snapctl is-connected", func(t *testing.T) { + + connected, err := snapctl.IsConnected("test-plug").Run() + require.NoError(t, err, "Error checking plug status.") + require.False(t, connected) + + }) + +}