Join GitHub today
GitHub is home to over 20 million developers working together to host and review code, manage projects, and build software together.
snappy,dirs: add support to use desktop files from inside snaps #548
Conversation
|
This looks good; it just deviates from the |
zyga
reviewed
Feb 29, 2016
| + return err | ||
| + } | ||
| + | ||
| + // sub |
zyga
reviewed
Feb 29, 2016
| + app := &AppYaml{ | ||
| + DesktopFile: "foo.desktop", | ||
| + } | ||
| + c.Assert(generateDesktopFileName(m, app), Equals, filepath.Join(dirs.SnapDesktopFilesDir, "foo_foo.desktop")) |
|
Some misc comments. If you are happy about not having the version in the generated desktop file name then I'm +1 |
|
Can we have this by filename convention instead? E.g. if meta/<app-name>.desktop exists (or maybe meta/desktop/<app-name>.desktop), we use it as the desktop file. Would we need the yaml field for other reasons? |
niemeyer
added
the
Reviewed
label
Feb 29, 2016
|
@niemeyer can it be a template instead that uses |
|
@zyga I think its fine without the version, because there is only a single one active at any point in time. |
|
@niemeyer sure, happy to use the |
|
@sergiusens I'm not sure I understand? The recommendation should be that you have:
and the desktop file would have a matching
In this case the app can be launcher both via CLI and desktop UI. Or am I misreading your question/suggestion? |
|
I updated the branch to look for |
|
I am saying that maybe
|
|
Given that it has been changed to be done by convention though my suggestion just makes things fragile. |
niemeyer
reviewed
Feb 29, 2016
| @@ -63,6 +63,9 @@ type AppYaml struct { | ||
| Command string `yaml:"command"` | ||
| Daemon string `yaml:"daemon"` | ||
| + // for desktop-file integration | ||
| + DesktopFile string `yaml:"desktop"` |
niemeyer
reviewed
Feb 29, 2016
| + | ||
| + desktopFiles, err := filepath.Glob(filepath.Join(baseDir, "meta", "*.desktop")) | ||
| + if err != nil { | ||
| + return fmt.Errorf("can not get desktop files for %v: %s", baseDir, err) |
niemeyer
reviewed
Feb 29, 2016
| + glob := filepath.Join(dirs.SnapDesktopFilesDir, m.Name+"_*.desktop") | ||
| + activeDesktopFiles, err := filepath.Glob(glob) | ||
| + if err != nil { | ||
| + return fmt.Errorf("can not get desktop files for %v: %s", glob, err) |
|
LGTM |
|
One small change: we decided to put the desktop files under |
|
And one more small change: move the icon(s) under |
mvo5
added some commits
Feb 29, 2016
|
Thanks for the feedback. The branch is updated and I addressed the feedback. |
|
Hey, I've still to check the internals of this PR, but in the mean time, for here's what I and @mvo5 discussed in order to get proper unity/BAMF support:
So I guess we can continue here. |
ted-gould
reviewed
Feb 29, 2016
| + | ||
| + realBaseDir := stripGlobalRootDir(baseDir) | ||
| + content = bytes.Replace(content, []byte("${SNAP}"), []byte(realBaseDir), -1) | ||
| + |
ted-gould
Feb 29, 2016
I don't think it's a good idea to use a desktop file verbatim. It needs to be associated with a command and have the Exec line match that command. For instance my desktop Exec could read data at the permissions level of the shell before going into confinement. I think that a much better approach is to generate the desktop file from data in the YAML.
ted-gould
commented
Feb 29, 2016
|
Can we please have an interface for this? Here are a few reasons I think an interface is important:
All in all, if it is an interface, we can still have a desktop file for systems like Unity7 and BAMF to use, we just remove it from the things that snap packagers have to know about. |
mvo5
closed this
Mar 1, 2016
|
Closing for now, the concern about Exec and TryExec running without confinement is very valid and needs addressing. It sounds like feature/apps may need resurrecting which auto-generates desktop files. Which in itself has problems of course. |
mvo5
added some commits
Mar 2, 2016
|
Thanks everyone for the review and the comments. @ted-gould I talked about the generate vs filter/whitelist with @niemeyer yesterday and after going over the pros and cons he suggested to go with the approach implemented in this branch plus proper whitelist based filtering. So I reopen this pull-request again. An extra careful eye on the whitelist is appreciated |
mvo5
reopened this
Mar 2, 2016
mvo5
removed
the
Reviewed
label
Mar 2, 2016
ted-gould
commented
Mar 2, 2016
|
That's fine, can we then say that it is Snappy policy that for extension of snappy we expect files to be put in /meta/$(appname).* ? We have a lot more extensions of this manner that we want to land and so I'd like to know what that policy is. |
pedronis
changed the title from
add support to use desktop files from inside snaps
to
snappy,dirs: add support to use desktop files from inside snaps
Mar 2, 2016
|
@ted-gould You sent a mail to the list, so let's not cover this here any further. |
niemeyer
reviewed
Mar 2, 2016
| + validCmd := filepath.Base(generateBinaryName(m, app)) | ||
| + // just check the prefix to allow %flag style args | ||
| + // this is ok because desktop files are not run through sh | ||
| + if strings.HasPrefix(cmd, validCmd) { |
niemeyer
Mar 2, 2016
Contributor
Should we make this path absolute when copying it over?
Also, the test should likely be `cmd == validCmd || HasPrefix(cmd, validCmd+" ")
Not sure TryExec makes much sense in this context. Does it?
mvo5
Mar 3, 2016
Collaborator
Good catch! I Fixed the cmd == validCmd || HasPrefix() bit, that was indeed incorrect before. I also dropped TryExec as I agree that it does not make sense in the snap world.
I also added code to make the path absolute in f4357d1
niemeyer
reviewed
Mar 2, 2016
| +} | ||
| + | ||
| +func validExecLine(m *snapYaml, line string) bool { | ||
| + if !strings.HasPrefix(line, "Exec=") && !strings.HasPrefix(line, "TryExec=") { |
niemeyer
Mar 2, 2016
Contributor
That's a bit surprising, and may be the source of future bugs as these are not actually valid Exec lines. It's easy to fix that by inverting the logic: rename the function to badExecLine, and invert the false<=>true logic (and the call site test). Then, it's true that something not being an Exec line is also not a bad Exec line.
niemeyer
reviewed
Mar 2, 2016
| + if !isValidDesktopFilePrefix(line) { | ||
| + continue | ||
| + } | ||
| + if !validExecLine(m, line) { |
niemeyer
reviewed
Mar 3, 2016
| @@ -481,6 +483,129 @@ func removePackageBinaries(m *snapYaml, baseDir string) error { | ||
| return nil | ||
| } | ||
| +// this is a bit confusing, a localestring in xdg is: |
niemeyer
Mar 3, 2016
Contributor
Should this logic be in something like a desktop.go file? click.go seems to be used as a catch-all at the moment.
|
LGTM |
mvo5
added some commits
Mar 3, 2016
|
Thanks for the excellent review, I addressed the points, should be ready for a re-review. |
mvo5
referenced this pull request
Mar 3, 2016
Merged
snappy: cleanup click.go and move functionatlity into more meaningful places #569
zyga
reviewed
Mar 3, 2016
| +var validDesktopFileLines = []*regexp.Regexp{ | ||
| + // headers | ||
| + regexp.MustCompile(`^\[Desktop Entry\]$`), | ||
| + regexp.MustCompile(`^\[Desktop Action`), |
mvo5
Mar 3, 2016
Collaborator
Yes, this is for actions, but its confusing so I made this explicit now and added tests.
chipaca
reviewed
Mar 3, 2016
| +### Unsupported desktop keys | ||
| + | ||
| +The `DBusActivatable`, `TryExec` and `Implements` keys are currently | ||
| +not supported. |
chipaca
Mar 3, 2016
Member
...and will be removed / they will be ignored / snap installation will fail / the computer will be considered untrusted and all your cookies will be eaten.
ted-gould
Mar 3, 2016
I think that looking at the code we're stripping all other keys, for instance X-* keys, as well. We should note that in the documentation. (I do think it's a good idea, just saying we should tell people)
chipaca
reviewed
Mar 3, 2016
| +// lang_COUNTRY@MODFIER (or a subset of this) | ||
| +var desktopFileI18nPattern = `(|\[[a-zA-Z_@]+\])` | ||
| +var validDesktopFileLines = []*regexp.Regexp{ | ||
| + // headers |
niemeyer
Mar 3, 2016
Contributor
I was tempted to suggest the exact opposite when looking over the branch: why are we even using regexps when this pretty much just prefix checking? I doubt using goconfigparser would simplify the logic below, and it would definitely increase the complexity by adding a dependency into the picture.
mvo5
Mar 3, 2016
Collaborator
Thanks.
I started out with plain prefix checking. For the i18n strings like GenericName[de_DE@NL]= I switched to regexp. I'm of course open for alternative suggestions how we could check those without the need to hard-to-read regexp.
ted-gould
Mar 3, 2016
Sorry, this is confusing now, I commented on an out-of-date version and apparently it just gets appended. I think that using a proper ini parser is better. That way we can also ensure things like extra groups don't get copied over easily.
niemeyer
Mar 3, 2016
Contributor
The goal is having simple and correct logic only. A "proper" parser creates an invalid sense of safety if it's simply adding a third party dependency that requires significantly more logic both locally and in the third-party code itself.
mvo5
Mar 3, 2016
Collaborator
@niemeyer Thanks for the example. This will require some more tweaks, if you think that is worth the extra work to avoid the regexp, I will work on this now.
ted-gould
reviewed
Mar 3, 2016
| + return err | ||
| + } | ||
| + | ||
| + desktopFiles, err := filepath.Glob(filepath.Join(baseDir, "meta", "gui", "*.desktop")) |
ted-gould
Mar 3, 2016
It seems like instead of getting all desktop files, you only want ones that are the name of an application you know. Or put a check lower to ensure you have an application that matches the desktop file name.
mvo5
Mar 3, 2016
Collaborator
Thanks! So far I was not considering restricting the name of the desktop files. Should we do this in order to help unity/BAMF to match desktop-file to application? It feels a little heavy handed to restrict it so that application foo can only have meta/gui/foo.desktop but if it is actually important for unity/BAMF I can change that of course.
ted-gould
Mar 3, 2016
I don't think BAMF is a concern with that naming, as it won't be able to use the binary name matching anyway. As the Exec is going to point to a shell script in most cases. So the actual binary name will be different. But more I was thinking that you'd have a 1:1 ratio of apps to desktop files. I realize now that you weren't thinking of that restriction. I'm not sure there's a technical reason to prefer that, but it does feel weird to me that we'd have multiple GUI icons for each Snappy Application.
mvo5
added some commits
Mar 3, 2016
ted-gould
reviewed
Mar 3, 2016
| +var validDesktopFileLines = []*regexp.Regexp{ | ||
| + // headers | ||
| + regexp.MustCompile(`^\[Desktop Entry\]$`), | ||
| + regexp.MustCompile(`^\[Desktop Action [a-zA-Z0-9]+\]$`), |
ted-gould
Mar 3, 2016
I'm not sure how wide spread it is, but the spec does not limit the name of the action like this. It is just a string. I have seen action names that use spaces for sure, not sure of the usage of other characters.
mvo5
Mar 3, 2016
Collaborator
Interesting. The way I read https://specifications.freedesktop.org/desktop-entry-spec/latest/ar01s10.html#extra-actions-keys
Each action is identified by a string, following the same format as key names (see the section called “Entries”). Each identifier is associated with an action group that must be present in the .desktop file. The action group is a group named Desktop Action %s, where %s is the action identifier.
and in https://specifications.freedesktop.org/desktop-entry-spec/latest/ar01s02.html#entries: Only the characters A-Za-z0-9- may be used in key names.
However this may actually not reflect reality. I see for example [Desktop Action window-shot] from gnome-screenshot which clearly violates this :) So maybe this needs to be relaxed for the real world.
ted-gould
Mar 3, 2016
I missed that part of the spec, but whether we become less restrictive or not, we should at least add in "-" to the regex.
mvo5
Mar 3, 2016
Collaborator
Indeed, I wonder if this part of the spec is actually enforced anywhere :) I will add the "-" for now and we may need to relax it further.
ted-gould
reviewed
Mar 3, 2016
| +The `gui/` directory may contain .desktop files for the snap. Those | ||
| +desktop files may contain all valid desktop entries from the xdg | ||
| +Desktop Entry Specification version 1.1 with some exceptions listed | ||
| +below. |
ted-gould
Mar 3, 2016
Would be handy to put the link in the text: https://specifications.freedesktop.org/desktop-entry-spec/desktop-entry-spec-1.1.html
ted-gould
reviewed
Mar 3, 2016
| + | ||
| +func rewriteExecLine(m *snapYaml, line string) (string, error) { | ||
| + cmd := strings.SplitN(line, "=", 2)[1] | ||
| + for _, app := range m.Apps { |
ted-gould
Mar 3, 2016
Seems like, since different apps can have different permissions, we need to ensure that the exec line matches the application that it is associated with instead of any app in the package.
ted-gould
reviewed
Mar 3, 2016
| + validCmd := filepath.Base(generateBinaryName(m, app)) | ||
| + // check the prefix to allow %flag style args | ||
| + // this is ok because desktop files are not run through sh | ||
| + // so we don't have to worry about the arguments too much |
ted-gould
Mar 3, 2016
I'm not sure that's a valid assumption. I don't know that we can reasonably protect against it, but we should probably at least change the comment to "Unity 7 doesn't execute them with a shell, and that's all we care about." There are a lot of desktops out there that do different things.
|
Thanks for the detailed reviews I got! I addressed all points, except for the regexp removal one. I wonder if we may consider leaving the regexp (unless you think its much easier code without them, but I suspect it will also not be super straightforward without them). If there is anything else that should be addressed before this can land, please let me know! |
|
@mvo5 I didn't comment on regexp originally because I didn't feel like creating more work for this branch, but have you seen this: http://play.golang.org/p/2KAuk4nXUg This looks quite straightforward. |
mvo5
added some commits
Mar 7, 2016
|
@niemeyer The code is updated with the suggested changes. Please let me know if there is anything else I should do. |
elopio
reviewed
Mar 7, 2016
| +below. If there is a line with an unknown key or an unofficial key | ||
| +that line is silently removed from the desktop file on install. | ||
| + | ||
| +Only `Exec=` lines that starts with `Exec=$snap.$app` are valid, but |
|
@mvo5 what about a snap+test for basic-with-desktop-file in https://github.com/ubuntu-core/snappy/tree/master/integration-tests/data/snaps ? |
|
Thanks Michael, and sorry for the churn on this one. LGTM |
|
@elopio I will prepare a new branch with a integration test, this review is already pretty long |
added a commit
that referenced
this pull request
Mar 7, 2016
mvo5
merged commit 9ddb765
into
snapcore:master
Mar 7, 2016
|
agree. Thanks mvo. |
mvo5 commentedFeb 29, 2016
This adds support for desktop files inside snaps. The files will be exported to /varl/lib/snappy/desktop and the desktop environment (like unity) needs to be tweaked with something like
<LegacyDir>/var/lib/snappy/desktop</LegacyDir>in/etc/xdg/menus/unity-lens-applications.menu(or better proper .directory files).Happy to talk about the best names for the keys. Right now it looks like this:
but we could also use
desktop-fileinstead ofdesktophere.