Devoperator classic confinement request

Hello,

I am creating a snap to bundle up several tools which our devops team uses internally. We also share this tool with a small number of customers.

https://snapcraft.io/devoperator/listing

Among other tools, devoperator includes

  • terraform which we use to write YAML files for consumption by other tools
  • eksctl which writes $HOME/.kube/config
  • kubectl which reads and writes files in $HOME/.kube
  • AVH git flow which reads and writes anywhere/.git/config

I am not married to using classic confinement but I cannot think of any other way to handle the pretty much arbitrary read/write requirements of these tools. If you have another idea, please let me know.

– Art Z.

Folks,

I just noticed this step in the process:

the advocacy team, reviewers team and/or architects participate in vetting the snap/publisher

To vette me, see my LinkedIn profile and my personal blog

– Art Z.

@reviewers It has been almost a full business week. How long does the vetting and review process take?

Apologies for the delay - this week there has been a company-wide event so most reviewers have been focussing on that. As per Process for reviewing classic confinement snaps any vetting etc is only done once it is clear that classic confinement is actually required for the snap in question.

In this case, it is not clear to me that classic confinement is a required for devoperator - for access to dot files in the users home directory, the personal-files interface exists which would appear to provide the required access - can you please investigate using this instead?

@alexmurray Thank you. I must have misread the description for personal-files back when I was doing my initial research. I remember it as specifically not allowing access to dot-files. I think that it will do nicely for what I need to accomplish.

Let’s just put this request on hold for now. Over the next few days, I ought to have time to try personal-files and I will either cancel this request or ask you to continue with your review.

@alexmurray I spent several hours working with my snap and have come to the conclusion that, while I could make it work with strict confinement, that is really not what I had hoped to achieve. I end up trapped inside the snap’s container, unable to access programs outside the container (like emacs and vim). Although I can access config files, like $HOME/.aws/config, none of those files are where they should be because $HOME has been rewritten to /home/whatever/snap/devoperator/...

All I really want from the snap is the convenient bundling of several tools and libraries. I explicitly do not want to be constrained inside a container, isolated from the rest of my development environment. I have a working version of DevOperator that is a Docker container and had hoped to reduce the amount of code necessary to make “devoperator” work, not simply transition to a different container jail. :slight_smile:

Classic confinement gives me exactly what I want. If you can approve that, great. If not, I will move along having learned a lot about snaps and realizing that it is not the right tool for this particular job.

@alexmurray To give you a couple of specific of what I am wrestling with, I ended up writing this:

plugs:
  ansible:
    interface: personal-files
    read:
      - $HOME/.ansible
      - $HOME/.ansible.prod.password
  ansible-ssh:
    interface: ssh-keys
  aws:
    interface: personal-files
    write:
      - $HOME/.aws
      - $HOME/.kube
  home:
    interface: home
  devoperator-network:
    interface: network

and then had to add the appropriate plugs to each command

  aws:
    command: bin/aws
    plugs:
      - aws
      - devoperator-network
  mfa:
    command: mfa
    plugs:
      - home

and then I had to start writing stuff like this (taken from mfa)

# $HOME is rewritten by snap to something like /home/art/snap/devoperator/x1 so change it back to /home/art
export HOME=$( echo $HOME | awk -F / '{printf("/%s/%s", $2, $3)}' )

I have 21 commands, each of which has to be dealt with.

So if you snap needs to or expects to execute commands from the host system (such as vim/emacs etc) or to manage non-root development workspace environments, then this is an identified use-case for classic requirement as per Process for reviewing classic confinement snaps

However in that case you would need to more clearly describe these use-cases specifically for devoperator so that it is clear that this is definitely required.

In regards to your snapcraft.yaml above, there are a couple redundant sections which can be removed - ie all of the following

  home:
    interface: home
  devoperator-network:
    interface: network
  ansible-ssh:
    interface: ssh-keys

As this can be replaced with just:

  plugs:
    - home
    - network
    - ssh-keys

where required.

Also if all commands need the same set of interfaces connected, then you can just specify a top-level plugs to list them all (in the same manner as the top-level slots) - then you don’t have to repeat it for each separate app entry.

Finally, it would probably be more reliable to lookup HOME as:

getent passwd $(id -u) | cut -d ':' -f 6

@alexmurray

Our typical use-case is to start the day by running mfa. This script logs into the AWS CLI with multi-factor authentication, sets the authentication info in environment variables, and spawns a subshell. From within the subshell, the user runs arbitrary commands anywhere on their workstation, typically within $HOME and /images.

The most commonly used commands include are the 20-ish commands within devoperator (the Ansible suite, the AWS CLI, eksctl, kubectl, and the git-flow plugins for git). People also use many commands outside the snap, including editors, ssh, rsync, docker, grep, find, etc etc etc.

Within the snap, the ansible-vault command directly spawns $EDITOR which is outside the snap.

Thanks for the tips on snapcraft.yaml syntax. I tried to give each command just the plugs that it required. Perhaps I went too far in crafting the fine grained access controls. :slight_smile:

Worth thinking about is whether a future (not right now) version could include changes that allow you to become strict: don’t spawn a subshell, instead return the environment variables in STDOUT, or write them to a file, for the user to apply to their current system shell. This would prevent the need for classic to be able to execute external commands.

@lucyllewy We did consider that mechanism and prefer the subshell. One key reason is that it makes logging out really easy: exit the subshell and the env variables vanish. The alternative is deactivate for a venv and something else for mfa and then a third command for exiting from assume-role (which acts like mfa but assumes an AWS IAM role).

1 Like

This makes it clear that classic confinement is appropriate in this case. The requirements are understood - @advocacy can you please perform vetting of the publisher?

I have verified the publisher, +1 from me.

Thank you, gentlemen.

I just uploaded our release candidate. Do I need to do anything else?

Classic confinement granted for devoperator, this is now live.

Thank you very much @alexmurray It’s working perfectly.

It will be no surprise to know that all of my peers will find snap install much more convenient than rsyncing the .snap files around. :slight_smile:

Cheers, – Art Z.