Create a simple custom plugin for Snapcraft

Source: Internet
Author: User
Tags glob git clone pprint

We know that the plugin framework of Snapcraft can be extended. We can define a new custom plugin for our snapcraft based on the new requirements to build our project. In today's article, we'll show you how to create a new plugin for our snapcraft. For more knowledge about Snapcraft's plugin, please refer to our documentation. For more information on Snapcraft, you can refer to our website Snapcraft.io. We can also find a number of plugin routines at the address for our reference.


1) Create one of the most basic custom plugin

At present, we can find the most similar documents on the Internet in:
Http://snapcraft.io/docs/build-snaps/plugins

As required, we create a template of the most basic custom plugin. We can download our code in the following way:

$ git clone https://github.com/liu-xiao-guo/plugin_template

The file structure of our project:
liuxg@liuxg:~/release/plugin_template$ tree-l 3
.
├──parts
│└──plugins
│     └──myplugin.py
└──snapcraft.yaml

In the file schema above, we can see that we have created a directory called parts under the root of our project. Underneath it, we also created a subdirectory called plugins. Inside we created a most basic file myplugin.py. Its content is as follows:
myplugin.py
#-*-Mode:python; Indent-tabs-mode:nil; Tab-width:4-*-Import Logging import OS import glob from pprint import pprint import Snapcraft logger = Logging.getlog Ger (__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 ' [' Mypro P '] = {' type ': ' String ', ' Default ': '} # Inform Snapcraft of the properties as Sociated with building.
        If These # change in the YAML Snapcraft would consider the build step dirty. schema[' build-properties '].append (' MyProp ') return schema def __init__ (self, name, O Ptions, ProjecT): Super (). __init__ (name, Options, Project) logger.warning ("__init__ Begins name:%s", name) Logg Er.warning ("Options.source:%s", Options.source) logger.warning ("Options.myprop:%s", Options.myprop) log Ger.warning ("Self.builddir:%s", Self.builddir) logger.warning ("Self.installdir:%s", Self.installdir) # l Ogger.warning ("Self.project.parallel_build_count:%d", Self.project.parallel_build_count) # logger.warning ("SELF.P Roject.arch_triplet:%s ", Self.project.arch_triplet) # logger.warning (" Self.project.stage_dir:%s ", Self.project.s Tage_dir) logger.warning ("going to add the needed build packages ...") # Self.build_packages.append (' Golang-go ') # _dump ("Options", Options) # _dump ("project", Project) logger.warning ("Bui Ld-packages: ") for Pkg in options.build_packages:logger.warning (" Build Package:%s ", pkg) def BU ILD (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 pul L begins ...      
 ")

Here, we can see a most basic of the simplest of a plugin template. Our Myplugin is inherited from Snapcraft. Baseplugin. In fact, there is no material to do anything. It is worth pointing out that we used the logger.warning (...) To help us output debugging information. At the time of the real release, we need to delete these outputs. We know that when you build a project in Snapcraft, it goes through the following process:



A plugin in the above 5 processes, it has experienced PullAnd Build. We can also refer to many examples of plugin in the Snapcraft project to implement the method above. In the code above:
        Schema[' Properties ' [' myprop '] = {
            ' type ': ' String ',
            ' default ': '
        }

We also define one of our own is called MyProp's property. To demonstrate our call to this custom Snapcraft plugin, we have designed the following Snapcraft.yaml files:
Snapcraft.yaml
Name:plugin # 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 # All char Long summary
Description: |
  This is a plugin example

grade:stable # must being ' stable ' to release into candidate/stable channels
confinement:s  Trict # use ' strict ' once you has the right plugs and slots

parts:
  my-part:
    # This is a custom plugin defined In "Parts" dir plugin:myplugin # This is the property of defined in the
    plugin. It is a file name # to being used for the
    congfigure Hook
    myprop:configure
    Source:.    

Here we apply the Myplugin, and we also use the MyProp attribute defined in our plugin as configure. Source is usually an essential attribute of a plugin. In our routines, we define it as ". ", which is the current directory.
At this point, our most basic plugin framework has been set up, so let's build our project. In the root directory of the project, enter:
$ snapcraft



From the above we can see that it has successfully used our own design of the plugin to build our project, and we can see that " Pull begins ...and Build begins ...Words These are the logger.warning (...) in the myplugin.py above us. The output of the. At the same time, we also print out some of the object properties we may need, such as Self.builddir. We can also see that the value of our options.myprop is "configure". Similarly, we can also clean our project:
$ Snapcraft Clean



As can be seen from the above, the "Clean_pull (self)" defined in myplugin.py is also called. We can use this method to delete anything we download in pull.
So far, our most basic template plugin has not done anything substantial, it just shows the inheritance from Snapcraft. A call to the most basic method in the Baseplugin class, such as build (self). In the following chapters, we will show you how to use these methods to do what we need to do.

2) Create a simple application that uses Snapcraft plugin

In this chapter, we show how to use the plugin above to do something meaningful. In today's routine, we want to put the following configure files into the final snap package of our project:
liuxg@liuxg:~/snappy/desktop/plugin/prime$ tree-l 3
.
├──bin
│└──config
├──command-config.wrapper
└──meta
    ├──hooks
    │└──configure
    └──snap.ya ml

Once we produce this configure (executable) file in the Meta/hooks directory, the contents are as follows:
Configure
#!/bin/sh

if! username=$ (Snapctl get username), then
    echo "username is required"
    exit 1
fi

if! password=$ (Snapctl get password); Then
    Echo ' Password is required '
    exit 1
fi

# Handle username and Password, perhaps write to a credenti Al file of some sort.
echo "user= $username" > $SNAP _data/credentials
echo "password= $password" >> $SNAP _data/credentials
chmod $SNAP _data/credentials

Once we have the above configure file in our snap installation, we can use the following command in our Ubuntu core system:
$ sudo snap set plugin Username=foo Password=bar

To produce the credentials file in the $snap_data directory. The contents are as follows:


For some reason, it is currently only possible to test on Ubuntu core systems (such as Raspberry Pi, Dragon Board, KVM, etc.). There is still a problem in the desktop environment of Ubuntu desktop. Based on this idea, we re-rewrite our myplugin.py file:
myplugin.py
#-*-Mode:python; Indent-tabs-mode:nil; Tab-width:4-*-Import Logging import OS import glob from pprint import pprint import Snapcraft logger = Logging.getlog Ger (__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 ' [' Mypro P '] = {' type ': ' String ', ' Default ': '} # Inform Snapcraft of the properties as Sociated with building.
        If These # change in the YAML Snapcraft would 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 Logge  R.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, NA  Me, 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.M Yprop) logger.warning ("Self.builddir:%s", Self.builddir) logger.warning ("Self.installdir:%s", Self.inst Alldir) # logger.warning ("Self.project.parallel_build_count:%d", Self.project.parallel_build_count) # Log Ger.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_p
        Ackages: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 pul L Begins ...
 ")

Here, we take our configure file into our corresponding part's build and install directory. So our task is done. We mainly modify the section in "Build (self)". In the same way, we have made the following changes to our Snapcraft.yaml:
Snapcraft.yaml
Name:plugin # 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 # All char Long summary
Description: |
  This is a plugin example

grade:stable # must being ' stable ' to release into candidate/stable channels
confinement:s Trict # use ' strict ' once you has the right plugs and slots

apps:
  config:
   command:bin/config

parts:
  
   my-part:
    # This was a custom plugin defined in ' Parts ' dir
    plugin:myplugin # This was the property
    defined In the plugin. It is a file name # to being used for the
    congfigure Hook
    myprop:configure
    Source:.
    
  Config:
    plugin:dump
    Source:./bin
    Organize:
      "*": bin/
  

Here, we add an app called Config. It can be used to show the results of our settings:
Config
#!/bin/bash

echo "Reading config file at: $SNAP _data"

config_file= "$SNAP _data/credentials"

if [-F "$ Config_file "]
then
	cat $config _file
else
	echo" $config _file not found. "
	echo "Please run the following commmand to generate the file:"
	echo "sudo snap set plugin Username=foo Password=bar" 
  fi

Re-build our project:


From the above can be seen in our intermediate output of some debugging information. Of course we can do whatever we need to do, such as installing the Debian package separately according to the definition of build-packages.
We can also test our application:

In fact we can do this directly using the dump plugin provided by our snapcraft. Interested developers can refer to my article "How to set up for our Ubuntu core app". We show from this example how to create a custom plugin of our own snapcraft. All the source code in: Https://github.com/liu-xiao-guo/plugin
More about how to design your own custom plugin:-Snappy ubuntu Core Clinic (YouTube)-Snappy Ubuntu core Clinic (Youku)


Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.