-
Notifications
You must be signed in to change notification settings - Fork 28
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(snap): Add snap packaging #30
Changes from 25 commits
fbae2df
862b54a
a30f13e
e81ae1c
f6542a3
bdfb580
b80c245
36ec5bb
13faad9
21b1265
81273f7
330d9cc
554a70a
c4eb13c
a19e9f5
cf5febe
dd2391e
bc793f9
e9b21ae
1f03470
97d9f59
4df80ee
4eccf07
1eaa599
91b64af
47482b0
ad82447
52d4126
4c4ab6a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
# EdgeX USB Camera Device Service Snap | ||
[![edgex-device-usb-camera](https://snapcraft.io/edgex-device-usb-camera/badge.svg)](https://snapcraft.io/edgex-device-usb-camera) | ||
|
||
This directory contains the snap packaging of the EdgeX USB Camera device service. | ||
|
||
The snap is built automatically and published on the Snap Store as [edgex-device-usb-camera]. | ||
|
||
For usage instructions, please refer to Device Camera section in [Getting Started using Snaps][docs]. | ||
|
||
## Build from source | ||
Execute the following command from the top-level directory of this repo: | ||
``` | ||
snapcraft -v | ||
``` | ||
|
||
This will create a snap package file with `.snap` extension. It can be installed locally by setting the `--dangerous` flag: | ||
```bash | ||
sudo snap install --dangerous <snap-file> | ||
``` | ||
|
||
The [snapcraft overview](https://snapcraft.io/docs/snapcraft-overview) provides additional details. | ||
|
||
### Obtain a Secret Store token | ||
The `edgex-secretstore-token` snap slot makes it possible to automatically receive a token from a locally installed platform snap. | ||
|
||
If the snap is built and installed locally, the interface will not auto-connect. You can check the status of the connections by running the `snap connections edgex-device-usb-camera` command. | ||
|
||
To manually connect and obtain a token: | ||
farshidtz marked this conversation as resolved.
Show resolved
Hide resolved
|
||
```bash | ||
sudo snap connect edgexfoundry:edgex-secretstore-token edgex-device-usb-camera:edgex-secretstore-token | ||
``` | ||
|
||
Please refer [here][secret-store-token] for further information. | ||
|
||
### Connect the camera interface | ||
The [`camera`](https://snapcraft.io/docs/camera-interface) interface is currently **NOT automatically connected** as it is pending auto-connection permissions from the store. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Have we requested these permissions yet? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not yet. We will do so once we have a stable source and build that can be reviewed by the store. |
||
|
||
To connect manually: | ||
``` | ||
snap connect edgex-device-usb-camera:camera :camera | ||
``` | ||
|
||
[edgex-device-usb-camera]: https://snapcraft.io/edgex-device-usb-camera | ||
[docs]: https://docs.edgexfoundry.org/2.2/getting-started/Ch-GettingStartedSnapUsers/#device-usb-camera | ||
[secret-store-token]: https://docs.edgexfoundry.org/2.2/getting-started/Ch-GettingStartedSnapUsers/#secret-store-token |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
#!/bin/bash | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is a workaround for snapcraft 7, correct? Did you ever get a response from the snapcraft team on this? At minimum, we should probably add a note to this script noting that it's a workaround. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As mentioned in this comment, I've reported the bug. We are no longer affected by it because we have refactored the hooks to have a single binary executable. This reduces the build complexity (code, time) and snap size. The same improvement is being rolled out to other snaps. |
||
exec $SNAP/bin/helper-go configure |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
#!/bin/bash -e | ||
|
||
exec $SNAP/bin/helper-go install | ||
farshidtz marked this conversation as resolved.
Show resolved
Hide resolved
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
#!/bin/bash -e | ||
|
||
# convert cmdline to string array | ||
ARGV=($@) | ||
|
||
# grab binary path | ||
BINPATH="${ARGV[0]}" | ||
|
||
# binary name == service name/key | ||
SERVICE=$(basename "$BINPATH") | ||
ENV_FILE="$SNAP_DATA/config/$SERVICE/res/$SERVICE.env" | ||
TAG="edgex-$SERVICE."$(basename "$0") | ||
|
||
if [ -f "$ENV_FILE" ]; then | ||
logger --tag=$TAG "sourcing $ENV_FILE" | ||
set -o allexport | ||
source "$ENV_FILE" set | ||
set +o allexport | ||
fi | ||
|
||
exec "$@" |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
build: | ||
go build -ldflags="-s -w" -o helper-go | ||
|
||
tidy: | ||
go mod tidy -compat=1.17 | ||
|
||
clean: | ||
rm -f helper-go |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
/* | ||
* Copyright (C) 2022 Canonical Ltd | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except | ||
* in compliance with the License. You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software distributed under the License | ||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express | ||
* or implied. See the License for the specific language governing permissions and limitations under | ||
* the License. | ||
* | ||
* SPDX-License-Identifier: Apache-2.0' | ||
*/ | ||
|
||
package main | ||
|
||
import ( | ||
"strings" | ||
|
||
"github.com/canonical/edgex-snap-hooks/v2/log" | ||
"github.com/canonical/edgex-snap-hooks/v2/options" | ||
"github.com/canonical/edgex-snap-hooks/v2/snapctl" | ||
) | ||
|
||
func configure() { | ||
log.SetComponentName("configure") | ||
|
||
// config options are always enabled for this service | ||
err := snapctl.Set("app-options", "true").Run() | ||
if err != nil { | ||
log.Fatalf("could not enable config options: %v", err) | ||
} | ||
|
||
err = options.ProcessAppConfig("device-usb-camera") | ||
if err != nil { | ||
log.Fatalf("could not process options: %v", err) | ||
} | ||
|
||
// If autostart is not explicitly set, default to "no" | ||
// as only example service configuration and profiles | ||
// are provided by default. | ||
autostart, err := snapctl.Get("autostart").Run() | ||
if err != nil { | ||
log.Fatalf("Reading config 'autostart' failed: %v", err) | ||
} | ||
if autostart == "" { | ||
log.Debug("autostart is NOT set, initializing to 'no'") | ||
autostart = "no" | ||
} | ||
autostart = strings.ToLower(autostart) | ||
log.Debugf("autostart=%s", autostart) | ||
|
||
// services are stopped/disabled by default in the install hook | ||
switch autostart { | ||
case "true", "yes": | ||
err = snapctl.Start("rtsp-simple-server", "device-usb-camera").Enable().Run() | ||
if err != nil { | ||
log.Fatalf("Can't start service: %s", err) | ||
} | ||
case "false", "no": | ||
// no action necessary | ||
default: | ||
log.Fatalf("Invalid value for 'autostart': %s", autostart) | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
module github.com/edgexfoundry/device-camera-go/hooks | ||
|
||
require github.com/canonical/edgex-snap-hooks/v2 v2.3.0 | ||
|
||
require ( | ||
github.com/davecgh/go-spew v1.1.1 // indirect | ||
github.com/stretchr/testify v1.7.1 // indirect | ||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect | ||
) | ||
|
||
go 1.17 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
github.com/canonical/edgex-snap-hooks/v2 v2.3.0 h1:ddXo8b5AsYjTiZ1APyeHWri0//KfU5qhDwPkyK0TUTc= | ||
github.com/canonical/edgex-snap-hooks/v2 v2.3.0/go.mod h1:rOxrwdYL7hJDhxFH3uV+nVgLPjWOhJWgM5PRD5YG1jI= | ||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | ||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= | ||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | ||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= | ||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= | ||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= | ||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= | ||
github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= | ||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= | ||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | ||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= | ||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= | ||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
/* | ||
* Copyright (C) 2022 Canonical Ltd | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except | ||
* in compliance with the License. You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software distributed under the License | ||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express | ||
* or implied. See the License for the specific language governing permissions and limitations under | ||
* the License. | ||
* | ||
* SPDX-License-Identifier: Apache-2.0' | ||
*/ | ||
|
||
package main | ||
|
||
import ( | ||
"os" | ||
|
||
hooks "github.com/canonical/edgex-snap-hooks/v2" | ||
"github.com/canonical/edgex-snap-hooks/v2/env" | ||
"github.com/canonical/edgex-snap-hooks/v2/log" | ||
) | ||
|
||
// installProfiles copies the profile configuration.toml files from $SNAP to $SNAP_DATA. | ||
func installConfig() error { | ||
resPath := "/config/device-usb-camera/res" | ||
err := os.MkdirAll(env.SnapData+resPath, 0755) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
path := resPath + "/configuration.toml" | ||
err = hooks.CopyFile( | ||
env.Snap+path, | ||
env.SnapData+path) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
path = "/config/rtsp-simple-server.yml" | ||
err = hooks.CopyFile( | ||
env.Snap+path, | ||
env.SnapData+path) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func installDevices() error { | ||
devicesDir := "/config/device-usb-camera/res/devices" | ||
|
||
err := os.MkdirAll(env.SnapData+devicesDir, 0755) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
err = hooks.CopyFile( | ||
hooks.Snap+devicesDir+"/general.usb.camera.toml.example", | ||
hooks.SnapData+devicesDir+"/general.usb.camera.toml.example") | ||
if err != nil { | ||
return err | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func installDevProfiles() error { | ||
profilesDir := "/config/device-usb-camera/res/profiles" | ||
|
||
err := os.MkdirAll(env.SnapData+profilesDir, 0755) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
err = hooks.CopyFile( | ||
hooks.Snap+profilesDir+"/general.usb.camera.yaml", | ||
hooks.SnapData+profilesDir+"/general.usb.camera.yaml") | ||
if err != nil { | ||
return err | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func install() { | ||
log.SetComponentName("install") | ||
|
||
err := installConfig() | ||
if err != nil { | ||
log.Fatalf("error installing config file: %s", err) | ||
} | ||
|
||
err = installDevices() | ||
if err != nil { | ||
log.Fatalf("error installing devices config: %s", err) | ||
} | ||
|
||
err = installDevProfiles() | ||
if err != nil { | ||
log.Fatalf("error installing device profiles config: %s", err) | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
/* | ||
* Copyright (C) 2022 Canonical Ltd | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except | ||
* in compliance with the License. You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software distributed under the License | ||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express | ||
* or implied. See the License for the specific language governing permissions and limitations under | ||
* the License. | ||
* SPDX-License-Identifier: Apache-2.0' | ||
*/ | ||
|
||
package main | ||
|
||
import ( | ||
"os" | ||
) | ||
|
||
func main() { | ||
subCommand := os.Args[1] | ||
switch subCommand { | ||
case "install": | ||
install() | ||
case "configure": | ||
configure() | ||
default: | ||
panic("Unknown subcommand: " + subCommand) | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should mention that building this snap remains "challenging" and at least offer some options. I don't think the given option "just works".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As explained in another comment, we have been able to build it without problems locally and on CI servers. If there are any OS-specific challenges related to using snapcraft to build core22-based snaps, it should be raised on snapcraft issue trackers.