如何在Ubuntu18.04上打包和发布Snap应用程序
作为 Write for DOnations 计划的一部分,作者选择了 Electronic Frontier Foundation 来接受捐赠。
介绍
应用程序开发中最大的挑战之一是将成品分发给您的用户或客户的最后一步。 许多现有的应用程序部署方法缺乏用户友好性和安全性,或者不提供在应用程序安装后自动更新应用程序的方法。
Snap 是一种现代应用程序打包格式,具有强大的沙盒和安全功能,包括文件系统隔离、自动更新和集成依赖管理。 Snap 应用程序(称为 Snaps)可以使用命令行程序下载和安装,类似于 apt
或 yum
。 Ubuntu 预装了 Snap,这意味着 Snap 应用程序有广泛的受众。
在本教程中,您将创建一个 Snap 应用程序并将其发布到 Snap Store。
先决条件
要完成本教程,您需要:
- 按照 Initial Server Setup 和 Ubuntu 18.04 设置一台 Ubuntu 18.04 服务器,包括 sudo 非 root 用户。
- 您希望打包并发布为 Snap 的应用程序。 这可能是您创建的复杂应用程序、常见的开源项目或简单的“Hello, world!”。 程序。 如果您还没有应用程序,本教程的 Step 1 将介绍如何在 Go 中创建 Hello World 程序。
- Snapcraft Developer Dashboard 上的一个帐户。
准备好这些后,以非 root 用户身份登录到您的服务器即可开始。
第 1 步 — 准备好您的应用程序以进行打包
首先,通过确保所需的所有内容都存在于单个目录中,您将准备将应用程序打包为 Snap 应用程序。
首先为您的 Snap 创建一个新目录并进入其中:
mkdir ~/your-snap cd ~/your-snap
接下来,如果您已经有一个应用程序,请将您的应用程序源代码的完整副本放入您刚刚创建的目录中。 此处的过程将根据您要打包的确切应用程序而有很大差异,但是如果源代码存储在 Git 存储库中,您可以 git init
目录中的存储库并下拉所有相关代码。
如果您还没有想要打包的应用程序,您可以创建一个“Hello World”程序来代替使用。 如果您想了解有关使用 Go 编写此程序的更多背景信息,请查看 如何在 Go 中编写您的第一个程序教程。
您可以通过首先创建一个新的 Go 文件并使用您喜欢的文本编辑器打开它来做到这一点:
nano helloworld.go
接下来,将以下代码添加到文件中:
helloworld.go
package main import "fmt" func main() { fmt.Println("Hello, world!") }
然后保存并退出文件。
如果你没有安装 Go,你可以使用以下命令安装它:
sudo apt install golang-go
安装 Go 后,您可以运行新程序以检查它是否正常工作:
go run helloworld.go
您将看到以下输出:
OutputHello, world!
您已准备好将应用程序打包为 Snap。 接下来,您将安装开始打包过程所需的软件。
第 2 步 — 安装 Snapcraft
在此步骤中,您将下载并安装 Snapcraft,它是官方 Snap 应用程序打包工具的名称。 Snapcraft 可从 Snap Store 获得,该商店默认内置于 Ubuntu。 这意味着您可以使用 snap
命令从命令行安装 Snapcraft。
snap
命令等效于 apt
命令,但您可以使用它从 Snap Store 安装软件,而不是从 Apt 存储库安装软件包。
为了安装 Snapcraft,运行以下命令:
sudo snap install snapcraft --classic
您使用 --classic
命令参数,这样 Snapcraft 就可以在没有 Snaps 通常使用的严格沙盒功能的情况下安装。 Snapcraft 需要此参数,因为它需要对您的系统进行更多特权访问才能可靠地打包应用程序。
安装 Snapcraft 后,您将看到以下内容:
Outputsnapcraft 3.9.8 from Canonical✓ installed
最后,您可以通过运行以下命令仔细检查 Snapcraft 安装:
snapcraft --version
这将显示类似于:
Outputsnapcraft, version 3.9.8
现在您已经安装了 Snapcraft,您可以开始为您的 Snap 应用程序定义配置和元数据。
第 3 步 — 为您的 Snap 定义配置和元数据
在此步骤中,您将开始为 Snap 应用程序定义配置、结构和元数据。
首先确保您仍在 Snap 应用程序目录中工作:
cd ~/your-snap
接下来,使用您喜欢的文本编辑器创建和编辑 snapcraft.yaml
文件:
nano snapcraft.yaml
您将使用 snapcraft.yaml
文件来存储 Snap 应用程序的所有配置,包括名称、描述和版本,以及与依赖管理和沙盒相关的设置。
首先为您的应用程序定义名称、摘要、描述和版本号:
snapcraft.yaml
name: your-snap summary: A summary of your application in 78 characters or less. description: | A detailed description of your application. The description can have multiple lines. version: '1.0'
如果您希望在 Snap Store 上发布 Snap,则您的 Snap 的名称必须是唯一的——搜索具有相同名称的其他应用程序以确保它尚未被使用。
接下来,您可以定义希望与应用程序关联的命令。 这将允许您的 Snap 直接从 Bash 命令行作为普通命令使用。
将以下内容添加到您的 snapcraft.yaml
文件中:
snapcraft.yaml
. . . apps: your-snap-command: command: your-snap
your-snap-command
是您要定义的命令的名称。 例如,您可能希望使用命令 helloworld
来运行您的 Hello World 程序。
您使用 command: your-snap
告诉 Snapcraft 在运行应用程序命令时要做什么。 对于 Hello World 程序,您将使用值 helloworld
来引用 helloworld.go
文件,这将允许 Snapcraft 成功运行您的程序。
这导致以下示例配置:
snapcraft.yaml
apps: helloworld: command: helloworld
如果命令名称与 Snap 名称完全匹配,您将能够直接从命令行运行它。 如果命令与 Snap 名称不匹配,该命令将自动以 Snap 名称作为前缀。 例如,helloworld.command1
。
最后,您可以定义构成 Snap 应用程序的 parts。 Snap 应用程序由多个部分组成,这些部分是构成您的应用程序的所有组件。 在许多情况下,只有一个部分,即应用程序本身。
每个部分都有一个关联的插件。 例如,对于用 Ruby 编写的应用程序的组件,使用 ruby
插件,而对于用 Go 编写的组件,则使用 go
插件。
您可以使用 Snapcraft list-plugins
命令为您的应用程序识别正确的插件:
snapcraft list-plugins
这将输出类似于以下内容的列表:
Outputant catkin-tools conda dump gradle make nil python rust autotools cmake crystal go kbuild maven nodejs qmake scons catkin colcon dotnet godeps kernel meson plainbox-provider ruby waf
最常见的插件是用于常见编程语言的插件,例如 Go、Rust、Ruby 或 Python。
一旦您为您的应用程序确定了正确的插件,您就可以开始将 parts
配置添加到您的 snapcraft.yaml
文件中:
snapcraft.yaml
. . . parts: your-snap: plugin: plugin-name source: .
您使用 source
配置参数来指定应用程序源代码的相对路径。 通常这将是与 snapcraft.yaml
文件本身相同的目录,因此 source
值是单个点 (.
)。
注意: 如果您的应用程序组件具有构建或运行它所需的任何依赖项,您可以使用 build-packages
和 stage-packages
属性指定这些。 然后将自动从系统的默认包管理器中获取指定的依赖项名称。
例如:
snapcraft.yaml
parts: your-snap: plugin: plugin-name source: . build-packages: - gcc - make stage-packages: - libcurl4
一些 Snapcraft 插件有自己的特定选项,您的应用程序可能需要这些选项,因此值得查看插件的相关手册页:
snapcraft help plugin-name
对于 Go 应用程序,您还可以指定 go-importpath
。 对于 Hello World 配置,这会产生以下示例配置:
snapcraft.yaml
parts: helloworld: plugin: go source: . go-importpath: helloworld
您可以将 snapcraft.yaml
文件保持打开状态,以便在下一步中添加进一步的配置。
您已经为 Snap 应用程序定义了基本配置。 接下来,您将配置应用程序的安全和沙盒方面。
第 4 步 — 保护您的 Snap 应用程序
Snap 应用程序设计为在沙盒环境中运行,因此在此步骤中,您将为 Snap 配置沙盒。 首先,您需要为您的应用程序启用沙盒,在 Snapcraft 中称为 confinement
。
将以下内容添加到您的 snapcraft.yaml
文件中:
snapcraft.yaml
. . . confinement: strict
这将为您的应用程序启用沙盒,防止它访问互联网、其他正在运行的 Snap 或主机系统本身。 但是,在大多数情况下,应用程序确实需要能够在其沙盒之外进行通信,例如当它们需要访问 Internet 或读取/写入文件系统时。
这些权限在 Snapcraft 中称为 interfaces,可以使用 Plugs 授予您的 Snap 应用程序。 使用 Plugs,您可以对应用程序的沙盒进行细粒度控制,为其提供所需的访问权限,仅此而已( 最小权限原则)。
所需的确切接口将根据您的应用程序而有所不同。 一些最常见的接口是:
audio-playback
- 允许音频输出/播放声音。audio-record
- 允许音频输入/录音。camera
- 允许访问连接的网络摄像头。home
- 允许访问主目录中的非隐藏文件。network
- 允许访问网络/互联网。network-bind
- 允许绑定到端口以作为网络服务运行。system-files
- 允许访问主机的整个文件系统。
可用接口的完整列表可以在 Supported Interfaces 下的 Snapcraft 文档中找到。
一旦确定了应用程序所需的所有接口,就可以开始将这些分配给 snapcraft.yaml
文件中的 plugs
。
以下示例配置将允许应用程序访问网络和用户的家庭区域:
snapcraft.yaml
. . . plugs: your-snap-home: interface: home your-snap-network: interface: network
保存并退出您的文件。
插件的名称应该是一个描述性的名称,以帮助用户识别插件的用途。
您已为 Snap 启用沙盒并配置了一些插件以授予对系统资源的有限访问权限。 接下来,您将完成构建 Snap 应用程序。
第 5 步 — 构建和测试您的 Snap 应用程序
现在您已经为 Snap 编写了所有必需的配置,您可以继续构建它并在本地测试 Snap 包。
如果您一直使用 Hello World 程序作为您的应用程序,那么您的完整 snapcraft.yaml
文件现在将类似于以下内容:
snapcraft.yaml
name: helloworld summary: A simple Hello World program. description: | A simple Hello World program written in Go. Packaged as a Snap application using Snapcraft. version: '1.0' confinement: strict apps: helloworld: command: helloworld parts: helloworld: plugin: go source: . go-importpath: helloworld plugs: helloworld-home: interface: home helloworld-network: interface: network
为了构建您的 Snap 应用程序,请从您的 Snap 目录中运行 snapcraft
命令:
snapcraft
然后 Snapcraft 将自动启动虚拟机 (VM) 并开始构建您的 Snap。 完成后,Snapcraft 将退出,您将看到类似于以下内容的内容:
OutputSnapped your-snap_1.0_amd64.snap
您现在可以在本地安装 Snap 以检查它是否正常工作:
sudo snap install your-snap.snap --dangerous
当您安装未签名的本地 Snap 时,需要 --dangerous
命令参数。
Outputyour-snap 1.0 installed
安装过程完成后,您可以使用关联的命令运行 Snap。 例如:
helloworld
在示例 Hello World 程序的情况下,以下输出将是:
OutputHello, world!
您还可以查看 Snap 的沙盒策略,以确保已正确授予分配的权限:
snap connections your-snap
这将输出一个插头和接口列表,类似于以下内容:
Outputsnap connections your-snap Interface Plug Slot Notes home your-snap:your-snap-home :home - network your-snap:your-snap-network :network -
在此步骤中,您构建了 Snap 并将其安装在本地以测试其是否正常工作。 接下来,您将在 Snap Store 上发布您的 Snap。
第 6 步 — 发布您的快照
现在您已经构建并测试了 Snap 应用程序,是时候在 Snap Store 上发布它了。
首先使用 Snapcraft 命令行应用程序登录您的 Snap Developer 帐户:
snapcraft login
按照提示输入您的电子邮件地址和密码。
接下来,您需要在 Snap Store 上注册应用程序的名称:
snapcraft register your-snap
注册 Snap 名称后,您可以将构建的 Snap 包推送到商店:
snapcraft push your-snap.snap
您将看到类似于以下内容的输出:
OutputPreparing to push 'your-snap_1.0_amd64.snap'. Install the review-tools from the Snap Store for enhanced checks before uploading this snap. Pushing 'your-snap_1.0_amd64.snap' [===================================================================================================] 100% Processing...| Ready to release! Revision 1 of 'your-snap' created.
每次推送到 Snap 存储时,修订号都会递增,从 1 开始。 这有助于识别 Snap 的各种不同版本。
最后,您可以向公众发布 Snap:
snapcraft release your-snap revision-number channel
如果这是您第一次推送到 Snap Store,修订号将为 1
。 如果您有多个版本的您的应用程序处于不同的开发阶段。
例如,以下命令会将 Hello World Snap 的修订版 1
发布到 stable
通道:
snapcraft release helloworld 1 stable
您将看到类似于以下内容的输出:
OutputTrack Arch Channel Version Revision latest amd64 stable 1.0 1 candidate ^ ^ beta ^ ^ edge ^ ^ The 'stable' channel is now open.
您现在可以在 Snap Store 上搜索您的应用程序并将其安装在您的任何设备上。
在这最后一步中,您将构建的 Snap 包上传到 Snap Store 并将其发布给公众。
结论
在本文中,您配置并构建了一个 Snap 应用程序,然后通过 Snap Store 将其发布给公众。 您现在拥有维护应用程序和构建新应用程序所需的基础知识。
如果您想进一步探索 Snap,不妨浏览完整的 Snap Store。 您可能还希望查看 Snapcraft YAML 参考 以了解更多信息并确定 Snap 配置的其他属性。
最后,如果您想进一步研究 Snap 开发,您可能会喜欢阅读和 implementing Snap Hooks,它允许 Snaps 动态响应系统更改,例如升级或安全策略调整。