为snapcraft创建一个简单的定制的plugin
来源:互联网 发布:光纤星型网络结构 编辑:程序博客网 时间:2024/05/24 03:20
我们知道snapcraft的plugin框架是可以扩展的.我们可以为我们的snapcraft根据新的需求定义一个新的custom plugin来build我们的项目.在今天的这篇文章中,我们将介绍如何为我们的snapcraft创建一个新的plugin.关于snapcraft的plugin的更多的知识,请参阅我们的文档.更多关于snapcraft的知识,可以参阅我们的网站snapcraft.io.我们也可以在地址找到许多的plugin的例程供我们参考.
1)创建一个最基本的custom plugin
目前,我们能够在网上找到的最相近的文档在:
http://snapcraft.io/docs/build-snaps/plugins
按照要求,我们创建一个最基本的custom plugin的模版.我们可以通过如下的方法把我们的代码下载下来:
$ git clone https://github.com/liu-xiao-guo/plugin_template
我们的项目的文件架构:
liuxg@liuxg:~/release/plugin_template$ tree -L 3.├── parts│ └── plugins│ └── myplugin.py└── snapcraft.yaml
在上面的文件架构中,我们可以看出来,我们在我们的项目的根目录下创建了一个叫做parts的目录.在它的下面,我们也创建了一个叫做plugins的子目录.里面我们创建了一个最基本的文件myplugin.py.它的内容如下:
myplugin.py
# -*- Mode:Python; indent-tabs-mode:nil; tab-width:4 -*-import loggingimport osimport globfrom pprint import pprintimport snapcraftlogger = logging.getLogger(__name__)def _dump(name, obj): for attr in dir(obj): # logger.warning("obj.%s = %s", attr, getattr(obj, attr)) func = getattr(obj, attr, None) if func: logger.warning("%s.%s = %s",name, attr, func) logger.warning("===================================")class MyPlugin(snapcraft.BasePlugin): @classmethod def schema(cls): schema = super().schema() schema['properties']['myprop'] = { 'type': 'string', 'default': '' } # Inform Snapcraft of the properties associated with building. If these # change in the YAML Snapcraft will consider the build step dirty. schema['build-properties'].append('myprop') return schema def __init__(self, name, options, project): super().__init__(name, options, project) logger.warning("__init__ begins name: %s", name) logger.warning("options.source: %s", options.source) logger.warning("options.myprop: %s", options.myprop) logger.warning("self.builddir: %s", self.builddir) logger.warning("self.installdir: %s", self.installdir) # logger.warning("self.project.parallel_build_count: %d", self.project.parallel_build_count) # logger.warning("self.project.arch_triplet: %s", self.project.arch_triplet) # logger.warning("self.project.stage_dir: %s", self.project.stage_dir) logger.warning("Going to add the needed build packages...") # self.build_packages.append('golang-go') # _dump("options", options) # _dump("project", project) logger.warning("build-packages:") for pkg in options.build_packages: logger.warning("build package: %s", pkg) def build(self): # setup build directory super().build() logger.warning("build begins ... ") def pull(self): super().pull() logger.warning("pull begins ... ") def clean_pull(self): super().clean_pull() logger.warning("clean pull begins ... ")
一个plugin在上面的5个过程中,它有经历pull及build.我们也可以参考在snapcraft项目中的许多plugin的实例来如何实现上面的method.
在上面的代码中:
schema['properties']['myprop'] = { 'type': 'string', 'default': '' }
snapcraft.yaml
name: plugin # you probably want to 'snapcraft register <name>'version: '0.1' # just for humans, typically '1.2+git' or '1.3.2'summary: This is a sample plugin for snapcraft # 79 char long summarydescription: | This is a plugin examplegrade: stable # must be 'stable' to release into candidate/stable channelsconfinement: strict # use 'strict' once you have the right plugs and slotsparts: my-part: # This is a custom plugin defined in "parts" dir plugin: myplugin # This is the property defined in the plugin. It is a file name # to be used for the congfigure hook myprop: configure source: .
在这里,我们运用了myplugin,同时我们也使用了在我们plugin中所定义的myprop属性为configure.source通常是一个plugin必不可少的一个属性.在我们的例程中,我们定义它为".",也即当前的目录.
至此,我们最基本的一个plugin的框架已经搭好了,那么我们来对我们的项目进行build.在项目的根目录中打入:
$ snapcraft
从上面我们可以看出来它已经成功利用我们自己设计的plugin来build我们的项目,并且我们可以看出来"pull begins ..."及"build begins ..."字样.这些都是在我们的上面的myplugin.py中的logger.warning(...)所输出的.同时,我们也打印出来一些我们可能需要的Object属性,比如self.builddir等.我们也可以看出我们的options.myprop的值为"configure".同样,我们也可以来clean我们的项目:
$ snapcraft clean
从上面可以看出来,在myplugin.py中所定义的"clean_pull(self)"也被调用.我们可以通过这个method来删除我们在pull中下载的任何东西.
到目前为止,我们的最基本的template plugin没有做任何实质性的东西,它只是展示了继承于snapcraft.BasePlugin类里最基本的method(比如build(self))的调用.在下面的章节中,我们将展示如何利用这些方法来做我们需要做的事.
2)创建一个简单的运用snapcraft plugin的应用
在这一章节中,我们来展示如何使用我们上面的plugin来做一些有意义的事.在今天的例程中,我们想把在我们项目最终的snap包中打入如下的configure文件:
liuxg@liuxg:~/snappy/desktop/plugin/prime$ tree -L 3.├── bin│ └── config├── command-config.wrapper└── meta ├── hooks │ └── configure └── snap.yaml
configure
#!/bin/shif ! username=$(snapctl get username); then echo "Username is required" exit 1fiif ! password=$(snapctl get password); then echo "Password is required" exit 1fi# Handle username and password, perhaps write to a credential file of some sort.echo "user=$username" > $SNAP_DATA/credentialsecho "password=$password" >> $SNAP_DATA/credentialschmod 600 $SNAP_DATA/credentials
一旦在我们的snap安装中有上面的configure文件,那么我们可以在我们的Ubuntu Core系统中,使用如下的命令:
$ sudo snap set plugin username=foo password=bar
来生产在$SNAP_DATA目录下的credentials文件.其内容如下:
由于一些原因,目前只能在Ubuntu Core的系统中进行测试(比如树莓派,dragon board, KVM等上进行测试).在Ubuntu Desktop的桌面环境中还是有一点问题.
基于这样的思路,我们重新改写我们的myplugin.py文件:
myplugin.py
# -*- Mode:Python; indent-tabs-mode:nil; tab-width:4 -*-import loggingimport osimport globfrom pprint import pprintimport snapcraftlogger = logging.getLogger(__name__)def _dump(name, obj): for attr in dir(obj): # logger.warning("obj.%s = %s", attr, getattr(obj, attr)) func = getattr(obj, attr, None) if func: logger.warning("%s.%s = %s",name, attr, func) logger.warning("===================================")class MyPlugin(snapcraft.BasePlugin): @classmethod def schema(cls): schema = super().schema() schema['properties']['myprop'] = { 'type': 'string', 'default': '' } # Inform Snapcraft of the properties associated with building. If these # change in the YAML Snapcraft will consider the build step dirty. schema['build-properties'].append('myprop') return schema def _copy(self, path_copyto): path = os.path.join(path_copyto, "meta/hooks/") logger.warning("path: %s", path); os.makedirs(os.path.dirname(path), exist_ok=True) source = self.builddir + "/" + self.options.myprop logger.warning("source: %s", source) destination = path + self.options.myprop logger.warning("destination: %s", destination) snapcraft.common.link_or_copy(source, destination, False) def __init__(self, name, options, project): super().__init__(name, options, project) logger.warning("__init__ begins name: %s", name) logger.warning("options.source: %s", options.source) logger.warning("options.myprop: %s", options.myprop) logger.warning("self.builddir: %s", self.builddir) logger.warning("self.installdir: %s", self.installdir) # logger.warning("self.project.parallel_build_count: %d", self.project.parallel_build_count) # logger.warning("self.project.arch_triplet: %s", self.project.arch_triplet) # logger.warning("self.project.stage_dir: %s", self.project.stage_dir) logger.warning("Going to add the needed build packages...") # self.build_packages.append('golang-go') #_dump("options", options) #_dump("project", project) logger.warning("build-packages:") for pkg in options.build_packages: logger.warning("build package: %s", pkg) def build(self): # setup build directory super().build() logger.warning("build begins ... ") # copy congfigure file to parts/<part>/build/meta/hooks self._copy(self.builddir) # copy configure file to parts/<part>/install/meta/hooks self._copy(self.installdir) def pull(self): super().pull() logger.warning("pull begins ... ") def clean_pull(self): super().clean_pull() logger.warning("clean pull begins ... ")
snapcraft.yaml
name: plugin # you probably want to 'snapcraft register <name>'version: '0.1' # just for humans, typically '1.2+git' or '1.3.2'summary: This is a sample plugin for snapcraft # 79 char long summarydescription: | This is a plugin examplegrade: stable # must be 'stable' to release into candidate/stable channelsconfinement: strict # use 'strict' once you have the right plugs and slotsapps: config: command: bin/configparts: my-part: # This is a custom plugin defined in "parts" dir plugin: myplugin # This is the property defined in the plugin. It is a file name # to be used for the congfigure hook myprop: configure source: . config: plugin: dump source: ./bin organize: "*": bin/
在这里,我们加入了一个叫做config的app.它可以被用来展示我们的设置的结果:
config
#!/bin/bashecho "Reading config file at: $SNAP_DATA"config_file="$SNAP_DATA/credentials"if [ -f "$config_file" ]thencat $config_fileelseecho "$config_file not found."echo "Please run the following commmand to generate the file:"echo "sudo snap set plugin username=foo password=bar"fi
重新build我们的项目:
从上面可以看出来我们中间输出的一些调试的信息.当然我们可以做任何我们需要做的事情,比如根据build-packages的定义来分别安装对应的debian包等.
我们也可以来测试我们的应用:
事实上我们也可以直接使用由我们的snapcraft所提供的dump plugin来完成这个.有兴趣的开发者可以参阅我的文章"如何为我们的Ubuntu Core应用进行设置".我们从这个例子中展示如何创建一个我们自己的snapcraft的custom plugin.
所有的源码在:https://github.com/liu-xiao-guo/plugin
更多关于如何设计自己的custom plugin:
- Snappy Ubuntu Core Clinic (youtube)
- Snappy Ubuntu Core Clinic (youku)
0 0
- 为snapcraft创建一个简单的定制的plugin
- 利用snapcraft为我们的Snappy Ubuntu应用打包
- 在snapcraft.yaml中如何使用dump plugin来拷贝我们的文件
- 为一个系统写plugin的感想
- 一个简单的时间类的定制
- 用PickerView定制一个简单的datepicker
- Python 简单的定制一个计时器
- 自定制vs插件--LearnVSXNow!-#3 创建一个带有简单命令的Package
- 为Orchard CMS创建一个简单的HelloWorld模块
- 使用 Fabrik 组件为 Joomla 创建一个简单的留言板
- 使用 Fabrik 组件为 Joomla 创建一个简单的留言板
- pppd拨号创建新的plugin定制自己的拨号软件
- 创建定制的组件
- 创建定制的ViewGroup
- 一个简单的Jquery Plugin: 跨浏览器的Word Breaker
- 专为GTD定制的emacs简单版
- 关于一个简单的复选框的定制
- 一个在程序中实现plugin机制的简单例子
- iOS 上传到AppStore上的icon尺寸和预览图片大小
- zookeeper安装
- Maven新建、更新……遇到“Could not calculate build plan”这一类问题怎么办
- 欢迎使用CSDN-markdown编辑器
- spark sql
- 为snapcraft创建一个简单的定制的plugin
- java 数组 math.max 方法取最大值
- Centos7 VMware 挂载SD卡
- mtd-utils交叉编译
- c++11标准下的随机数发生器
- 关于C++调用C#语言DLL(类库)
- TCP 回射程序(处理子进程的SIGCHLD信号)
- EventBus的使用
- 寻找sql注入的网站的方法