Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

snap: add support for snap advise-snap --from-apt #5122

Merged
merged 8 commits into from
Jul 23, 2018
Merged

Conversation

mvo5
Copy link
Contributor

@mvo5 mvo5 commented May 1, 2018

This adds support for interacting with the new apt 1.6+ hooks.

It implements the org.debian.apt.hooks.install.fail hook and
will suggest a snap if there is one available with the given
name.

E.g.:

Reading package lists... Done
Building dependency tree
Reading state information... Done

No apt package "aws-cli", but there is a snap with that name.
Try "snap install aws-cli"

E: Unable to locate package aws-cli

This will also need a spread test for the end-to-end integration test.

This adds support for interacting with the new apt 1.6+ hooks.

It implements the `org.debian.apt.hooks.install.fail` hook and
will suggest a snap if there is one available with the given
name.

E.g.:
```
Reading package lists... Done
Building dependency tree
Reading state information... Done

No apt package "aws-cli", but there is a snap with that name.
Try "snap install aws-cli"

E: Unable to locate package aws-cli
```
@Conan-Kudo
Copy link
Contributor

Hmm, that'd be interesting to have as a DNF hook too...

@mvo5
Copy link
Contributor Author

mvo5 commented May 3, 2018

@Conan-Kudo I would love to add one to dnf as well, do you have a pointer how to interact with dnf?

@Conan-Kudo
Copy link
Contributor

@mvo5: Here's the DNF plugin API: http://dnf.readthedocs.io/en/latest/api_plugins.html

@Conan-Kudo
Copy link
Contributor

@zyga
Copy link
Contributor

zyga commented May 4, 2018

It looks like the hook fails when snapd is being removed (or has been removed):

+ quiet apt-get remove -y --purge -y snapd
quiet: apt-get remove -y --purge -y snapd
quiet: exit status 100. Output follows:
Reading package lists...
Building dependency tree...
Reading state information...
The following package was automatically installed and is no longer required:
  grub-pc-bin
Use 'sudo apt autoremove' to remove it.
error: json: cannot unmarshal object into Go struct field .packages of type string
The following packages will be REMOVED:
  snapd*
0 upgraded, 0 newly installed, 1 to remove and 6 not upgraded.
After this operation, 57.6 MB disk space will be freed.
(Reading database ... 
(Reading database ... 5%
(Reading database ... 10%
(Reading database ... 15%
(Reading database ... 20%
(Reading database ... 25%
(Reading database ... 30%
(Reading database ... 35%
(Reading database ... 40%
(Reading database ... 45%
(Reading database ... 50%
(Reading database ... 55%
(Reading database ... 60%
(Reading database ... 65%
(Reading database ... 70%
(Reading database ... 75%
(Reading database ... 80%
(Reading database ... 85%
(Reading database ... 90%
(Reading database ... 95%
(Reading database ... 100%
(Reading database ... 101755 files and directories currently installed.)

Removing snapd (1337.2.32.6) ...

Processing triggers for man-db (2.8.3-2) ...

(Reading database ... 
(Reading database ... 5%
(Reading database ... 10%
(Reading database ... 15%
(Reading database ... 20%
(Reading database ... 25%
(Reading database ... 30%
(Reading database ... 35%
(Reading database ... 40%
(Reading database ... 45%
(Reading database ... 50%
(Reading database ... 55%
(Reading database ... 60%
(Reading database ... 65%
(Reading database ... 70%
(Reading database ... 75%
(Reading database ... 80%
(Reading database ... 85%
(Reading database ... 90%
(Reading database ... 95%
(Reading database ... 100%
(Reading database ... 101676 files and directories currently installed.)

Purging configuration files for snapd (1337.2.32.6) ...

Stopping snap-core-4588.mount

Stopping unit snap-core-4588.mount

Waiting until unit snap-core-4588.mount is stopped [attempt 1]

snap-core-4588.mount is stopped.

Removing snap core and revision 4588

Removing snap-core-4588.mount

Final directory cleanup

Discarding preserved snap namespaces

umount: /run/snapd/ns/: not mounted.

Removing extra snap-confine apparmor rules

Removing snapd cache

Removing snapd state

E: Could not read response to hello message from hook [ ! -f /usr/bin/snap ] || /usr/bin/snap advise-snap --from-apt || true: Connection reset by peer
E: Could not read message separator line after handshake from [ ! -f /usr/bin/snap ] || /usr/bin/snap advise-snap --from-apt || true: Connection reset by peer

Copy link
Contributor

@zyga zyga left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, I added a few comments but that's all nitpicks I think.

}

func readRpc(r *bufio.Reader) (*jsonRPC, error) {
line, _, err := r.ReadLine()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it guaranteed to be on a single line?

}
fd, err := strconv.Atoi(sockFd)
if err != nil {
return err
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nitpick, errors from atoi were a bit horrible last time I looked and it would be even less clear what went wrong if this were to happen. How about:

return fmt.Errorf("expected APT_HOOK_SOCKET to be a decimal integer, found %q", sockFd)


conn, err := net.FileConn(f)
if err != nil {
return fmt.Errorf("cannot connect to %q: %v", sockFd, err)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nitpick: I'd probably use fd rather than sockFd here since we're "done" handling that layer (string vs int).

func adviceViaAptHook() error {
sockFd := os.Getenv("APT_HOOK_SOCKET")
if sockFd == "" {
return fmt.Errorf("cannot find APT_HOOK_SOCKET env")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we just return nil here? Will this be the case when older apt is used and there's just no socket RPC to do.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apt added support for the new kind of hooks at the same time as the json rpc was added. So if there is no APT_HOOK_SOCKET env but the hook is called something is wrong (on the apt side).

@@ -18,6 +18,8 @@ data/udev/rules.d/66-snapd-autoimport.rules /lib/udev/rules.d
data/info /usr/lib/snapd/
# polkit actions
data/polkit/io.snapcraft.snapd.policy /usr/share/polkit-1/actions/
# apt hook
data/apt/20snapd.conf /etc/apt/apt.conf.d/
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wish apt would pick hooks from /lib as this is yet another thing that needs to be in /etc

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah :/

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this is a new feature, can we influence apt to do the reasonable thing?

@mvo5
Copy link
Contributor Author

mvo5 commented May 7, 2018

As for the remove failure - I think we need a fix in apt for this or we need to make the shell code talk to the socket but that would be pretty hard because we cannot really depend on much when apt is in a minimal chroot.

Copy link
Contributor

@bboozzoo bboozzoo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some nitpicks, overall LGTM.

Format string `long:"format" default:"pretty" choice:"pretty" choice:"json"`
Command bool `long:"command"`
Format string `long:"format" default:"pretty" choice:"pretty" choice:"json"`
// Command makes advice try to find snaps that provide this command
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/advice/advise/

// Command makes advice try to find snaps that provide this command
Command bool `long:"command"`

// FromApt tells advice that it got started from an apt hook
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/advice/advise/

@bboozzoo
Copy link
Contributor

bboozzoo commented May 8, 2018

@Conan-Kudo I looked a bit at dnf plugins, but it's not clear how the functionality proposed in this patch could be utilized. i hoped we could use dnf.Plugin.resolved but as far as I understand after going through the documentation (haven't looked at dnf source code yet), the method is called when transaction is successfully resolved. At least, there does not appear to be a way to access the packages that could not be resolved. I'm open to any advice. Do you think we will need to have the dnf plugin API extended a bit?

@Conan-Kudo
Copy link
Contributor

@bboozzoo I think it's possible if you file an RFE for it.

@Conan-Kudo
Copy link
Contributor

@bboozzoo So I've had a chat with @dmach, and he might be able to help figure out what's needed to extend DNF to make this possible.

@zyga
Copy link
Contributor

zyga commented May 14, 2018

@mvo5 this branch is failing and I don't see a clear way to undo that. Can you please comment about what you plan to do with it?

@mvo5
Copy link
Contributor Author

mvo5 commented May 15, 2018

@zyga We need a fix in apt for this. Once that has landed we can go forward with the PR.

@mvo5
Copy link
Contributor Author

mvo5 commented May 15, 2018

Setting to blocked because we need a fix in apt for this to work.

@mvo5
Copy link
Contributor Author

mvo5 commented Jun 11, 2018

@codecov-io
Copy link

codecov-io commented Jul 19, 2018

Codecov Report

Merging #5122 into master will decrease coverage by 0.04%.
The diff coverage is 46.55%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #5122      +/-   ##
==========================================
- Coverage   79.05%   79.01%   -0.05%     
==========================================
  Files         514      514              
  Lines       38943    39001      +58     
==========================================
+ Hits        30787    30816      +29     
- Misses       5678     5692      +14     
- Partials     2478     2493      +15
Impacted Files Coverage Δ
cmd/snap/cmd_advise.go 57.14% <46.55%> (-9.04%) ⬇️
overlord/hookstate/hookmgr.go 74.39% <0%> (+0.96%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update dd8d998...f79d7b9. Read the comment docs.

@mvo5 mvo5 removed the ⛔ Blocked label Jul 20, 2018
@mvo5
Copy link
Contributor Author

mvo5 commented Jul 20, 2018

This is no longer blocked, the apt in the distro is fixed now.

@mvo5 mvo5 added this to the 2.35 milestone Jul 23, 2018
@mvo5 mvo5 merged commit 2b3d77e into canonical:master Jul 23, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants