Is it possible to make snapcraft always mount the current directory into the VM?


#1

Hi all,

Currently we are building snap packages on bare metal in our build system. A script creates a temporary directory and copies all the necessary files into there before running snapcraft.

I am trying to migrate to base and multipass solution. I notice that snapcraft doesn’t update the project folder mounting in its multipass VM unless we clean the VM with snapcraft clean.

Is it possible to have an option in snapcraft to mount the project directory again automatically? Also, it would be nice to have a better error message for missing project files. It took me quite some time to realize that the project files are missing because the VM mounted an old temporary directory.


#2

Probably you’ve already experimented with it, but is the LXD option any better? I.e. snapcraft --use-lxd? I think it’s in beta stage, now, but I use it all the time.


#3

Mounting of the project folder should happen on every run.

How is the interplay with this copy script? How would it work with bases?

If you have a consolidated build-system for which the host is compatible with the target base (core -> Ubuntu 16.04, core18 -> Ubuntu 18.04), then you could just use --destructive-mode


#4

I haven’t check the LXD solution yet since I thought multipass is better supported now. But I will give it a try to see if we can run snapcraft from different directory. Thanks.


#5

From what I can tell, the VM always keep the original mounted project directory unless I clean the whole VM with snapcraft clean.

We snap our software with a GN action that calls a python script.
In short, this python script creates a temporary directory, copies the compiled binaries and other resources like snapcraft.yaml to there and run snapcraft. A very short version of this script will look like this:

class SnapArchiver(linux_archiver.LinuxArchiver):
  def __init__(self, ...):
    self.workspace_ = tempfile.mkdtemp()
    self.snap_dir_ = os.path.join(self.workspace_, 'build')
  def __exit__(self, ...):
    shutil.rmtree(self.workspace_)
  def create(self):
    # Prepare the self.snap_dir_
    build_command = ['snapcraft']
    subprocess.check_output(build_command, cwd=self.snap_dir_)
    # Move the .snap file to the place we want
def main():
   # Parse arguments
   with SnapArchiver(...) as archiver:
     archiver.create()
   return 0
if __name__ == '__main__':
  sys.exit(main())

As you can see, the temporary directory is created in __init()__ and removed in __exit__(). If I don’t remove the temporary directory and don’t run snapcraft clean between builds, snapcraft will keep using the first temporary directory to snap the software. Therefore, no mounting of new project directory.


#6

I understand now… If there is a horrible error, we can certainly fix that.

That said, you are cleaning up the entire project assets dynamically, so why not run snapcraft clean as part of that?


#7

Since we are only building one software with very stable dependencies, we’d like to save the time and the bandwidth by not cleaning the VM.

After talking to our build system team, we will use a constant path for running snapcraft, which should solve this issue for us. Also we are using LXD since it’s a lot faster for us. But I think this post is still valid since the error can be very confusing to others too. If it’s not possible to mount the current directory when running snapcraft, it’s better to check and tell user the expected project path.