89luca89 / distrobox

Use any linux distribution inside your terminal. Enable both backward and forward compatibility with software and freedom to use whatever distribution you’re more comfortable with. Mirror available at: https://gitlab.com/89luca89/distrobox
https://distrobox.it/
GNU General Public License v3.0
10.2k stars 419 forks source link

Use something other than hostname to indicate container name in command line prompt #62

Closed castedo closed 7 months ago

castedo commented 2 years ago

distrobox runs podman/docker with --host set to the name of the container which in turn changes the contents of /etc/hostname to be the name of the container. But /etc/hostname is supposed to be the name of the host on the network and affects many system functions (see man hostname). Since the container is sharing the network, both the container and the host should have the same hostname.

On Debian there is a precedence for indicating the chroot in the command line prompt (chroot being a precursor to containers). To my knowledge there isn't an equivalent on Fedora based distros. Not knowing of an alternative I started using osvirtalias in cnest.

I describe the situation in more detail here: https://github.com/castedo/cnest/tree/master/prompt

So I can suggest doing similarly and set osvirtalias and/or debian_chroot to be the name of the container, and let the distro and container configuration determine the command line prompts however they are supposed to. And do this without incorrectly repurposing the hostname for a purpose other than what hostname is supposed to mean.

If you come across an alternative to osvirtalias please let me know. I don't want to start a precedent that is non-standard, but I do want to start a precedent other than debian_chroot. If it catches on, Debian distros probably want to use a name without chroot in it anyway.

89luca89 commented 2 years ago

Hi @castedo interesting approach What type of problems does using The hostname rise? Generally speaking if we're talking about the network traffic, I'd say it's an intended behavior

89luca89 commented 2 years ago

Anyway if we want to have an alternative to the hostnames, we need to find something that works across all distros

castedo commented 2 years ago

What type of problems does using The hostname rise?

Any application that actually wants to programmatically get the real hostname or FQDN. For instance, a python application that does

import socket
socket.gethostname()
socket.getfqdn()

Because distrobox resets the hostname, the hostname and FQDN are no longer actual network reachable names on any network. In particular they aren't valid names on the network to which the container is actually connected. It's not hard to imagine applications where this is not the desired behavior. For instance, a web application that reports to the users how to connect to the machine via browser URL etc...

Generally speaking if we're talking about the network traffic, I'd say it's an intended behavior

If the container is supposed to have a new hostname and FQDN on the network then distrobox has a separate bug which is it makes no effort to actually register this new name on its network.

Anyway if we want to have an alternative to the hostnames, we need to find something that works across all distros

My impression is that distrobox is showing the container name only in distros that show the hostname in the command line prompt. If a distro that does not show hostname in the prompt, then distrobox is not showing the container name in the prompt. So it is already the case that distrobox does not have prompt setting that works across all distros. It is true that showing hostname in the prompt is very popular across many distros.

castedo commented 2 years ago

Today I learned that podman and docker have a --cidfile option. So that together with -v can be used to set the container name inside the container, either /etc/debian_chroot or some other hopefully-eventually-standard location like perhaps /etc/osvirtalias. Then distros and users can use that file to customize the command prompt as desired. (This is what I'm planning to do https://github.com/castedo/cnest/issues/6)

89luca89 commented 2 years ago

Yea I see what you mean

If the container is supposed to have a new hostname and FQDN on the network then distrobox has a separate bug which is it makes no effort to actually register this new name on its network.

Probably I'd be a bit more inclined this way

My impression is that distrobox is showing the container name only in distros that show the hostname in the command line prompt. If a distro that does not show hostname in the prompt, then distrobox is not showing the container name in the prompt. So it is already the case that distrobox does not have prompt setting that works across all distros. It is true that showing hostname in the prompt is very popular across many distros.

yea because it's (almost) ubiquitous among all non-minimal distributions to show the hostname this way.

I'm more inclined to have something to register container's hostname outside, and maybe make the container hostname configurable at this point

castedo commented 2 years ago

OK, sounds like you're going for "hostname" a bit in the spirit of web servers handling multiple different hostnames for different websites even though they all have the same IP address. If DNS was setup right, I could imagine some users might expect http://myhost:80 to be handled by a process on the host with hostname 'myhost' but then http://myhost-test:8080 to be handled by a process running in a container named myhost-test with hostname myhost-test even though they are sharing the network and have the same IP address.

So sounds like different users can have different expectations about the relationship between the host and whether a container sharing a network has the same hostname or not. I find myself thinking of my 'pet' containers that share the network with the host as more like chroots which are handling different roles but on the same host (same hostname). So when I ssh to my different computers and enter a 'pet' container, I still think of myself as ssh'd into the same hostname. In fact, I tend to have pet containers with the exact same name on different computers. So when I'm ssh'd into another machine and inside one of these containers, it's the hostname distinct from the container name that gives me a clue that I'm not on my localhost.

I guess that's a question to really ask yourself. If you name a container distrobox-fedora on computer with hostname laptop.home does that mean you would NOT name an equivalent container also distrobox-fedora on computer with hostname desktop.home? If DNS was setup properly where does ssh distrobox-fedora or http://distrobox-fedora/ go to?

I doubt the usual scenario here is for container names to be network names (and thus hostnames). I think the usual scenario is that container names are NOT network names but people like to see the container name appear in the command line prompt.

89luca89 commented 2 years ago

A service on network in the container (be it python server, netcat, nginx etc etc) is available always from the host's hostname anyways

I find myself thinking of my 'pet' containers that share the network with the host as more like chroots which are handling different roles but on the same host (same hostname). So when I ssh to my different computers and enter a 'pet' container, I still think of myself as ssh'd into the same hostname. In fact, I tend to have pet containers with the exact same name on different computers. So when I'm ssh'd into another machine and inside one of these containers, it's the hostname distinct from the container name that gives me a clue that I'm not on my localhost.

That's just preference I think

I guess that's a question to really ask yourself. If you name a container distrobox-fedora on computer with hostname laptop.home does that mean you would NOT name an equivalent container also distrobox-fedora on computer with hostname desktop.home? If DNS was setup properly where does ssh distrobox-fedora or http://distrobox-fedora/ go to?

Well that's something to really define well before starting work on something like that :smile: Probably something like host's hostname + container-name as container's hostname

I doubt the usual scenario here is for container names to be network names (and thus hostnames). I think the usual scenario is that container names are NOT network names but people like to see the container name appear in the command line prompt.

It's not that we like it, it's that it is the most ubiquitous way to show it in the prompt without having to create custom prompts (as each user has it's own I guess) And having at first glance the ability to know if you're in a container or in the host is really important I think

I agree we could include a --hostname flag so that anyone can customize it, and (for example in your case) you can set it to the host's name itself

Today I learned that podman and docker have a --cidfile option. So that together with -v can be used to set the container name inside the container, either /etc/debian_chroot or some other hopefully-eventually-standard location like perhaps /etc/osvirtalias. Then distros and users can use that file to customize the command prompt as desired. (This is what I'm planning to do castedo/cnest#6)

I'll investigate it, if it's a standard for both, I see no problem including this option by default :+1:

89luca89 commented 2 years ago

Didn't find anything similar to debian_chroot on other distros without fiddling with either rc files, profiles etc etc

Closing this for now, if there are updates feel free to reopen it or open a new one

castedo commented 2 years ago

This reminds me, here are three observation that might be of interest.

1) When podman creates a container that is not sharing the network, by default it changes the hostname to the container ID (hexadecimal) and not the container name. This container ID is by default not a valid network destination name in DNS. I'm guessing this is because container names can contain periods and underscores which are not valid characters for the components of a FQDN. It's a bit odd to have \h and socket.getfqdn() etc... returning a component with invalid characters.

2) Looks like there is a way to enable local DNS so that containers names show up as real network destination names. I haven't used it yet or fully understand it yet, but here's more details: https://github.com/containers/dnsname/blob/main/README_PODMAN.md

3) the '\h' in the prompt is only the first part of a FQDN, which there is little reason to expect to be unique. So in my example earlier, of having two containers with the same name but on different physical computers (laptop and desktop), it's really only them having the same FQDN that is strange. Lots of computers have the same '\h' show up. It's the FQDN that is different.

In light of 3) perhaps there is some sense in setting the hostname to something longer, like container-name.thehost-hostname so that /etc/hostname has something slightly more sensible and socket.getfqdn() returns something suggestive of what actually is valid on the network, yet \h will still show only the container name.

89luca89 commented 2 years ago

perhaps there is some sense in setting the hostname to something longer, like container-name.thehost-hostname so that /etc/hostname

I like this idea, I'll fiddle with it these days and if all works well with backward compatibility, I'll include this I was thinking to use container-name.container-id but probably container-name.host-hostname it's better Will open a new issue referring this one if all goes well for the implementation :+1: thanks a lot 😄

For 2 I don't think it's in the scope of the tool as a service exposed in the container is also reachable from the host's hostname, which is what you expect from a pet container ,

castedo commented 2 years ago

perhaps there is some sense in setting the hostname to something longer, like container-name.thehost-hostname so that /etc/hostname

I like this idea, I'll fiddle with it these days and if all works well with backward compatibility, I'll include this I was thinking to use container-name.container-id but probably container-name.host-hostname it's better Will open a new issue referring this one if all goes well for the implementation +1 thanks a lot

I've started going with this approach too for containers that do not share the network: https://github.com/castedo/cnest/blob/3b5d92b428611c932d62d710a2312dbfed4457bd/config/profiles/isolated-docker-library#L8

I think I will also try this approach too for containers that do share the network. Although somehow it still feels wrong to me to use the same hostname when they share the network. But I probably just need to get used to this new approach and stop thinking it's wrong.

And I think I will stop using debian_chroot and osvirtalias too if this approach works well.

Thanks for helping us explore and find a smarter solution! :+1:

89luca89 commented 2 years ago

Thanks to you for the ideas and brainstorming 😄

89luca89 commented 8 months ago

Reopening this discussion! In the end I think @castedo you were right all along :grin:

I'd like to open a discussion on the future behavior of distrobox

Right now distrobox uses the container's name as hostname for the box

This leads to the upside of being easily recognizable But on the other hand, it creates some issues with KDE and GNOME for exported apps (missing icons, freezes and such)

What I was thinking is to modify the default prompt (the one with the little box) to use $CONTAINER_ID (which is the container's name) and be recognizable that way. I know that some custom prompts already support that variable so that should be ok. Then switch to use host's hostname for created boxes by default and keep it synced with the host

If using --unshare-netns or setting explicitly --hostname the user's preference will be preserved, no changes will occur

This would be a change for new boxes, old boxes will keep functioning as they are

I'm open to feedbak and workflows that might be affected by this, if I'm missing something and such

castedo commented 8 months ago

Right now distrobox uses the container's name as hostname for the box

Just the container name alone or 'container-name.thehost-hostname'?

castedo commented 8 months ago

@89luca89 This is what I have been dogfooding for a long time now:

https://github.com/castedo/cnest/blob/beb989f00d5051975b35f98b4709ac255cc21cbd/bin/create-nest#L52-L54

So far it's been working fine for me. But I might just be lucky and not hitting the issue you are hitting.

89luca89 commented 8 months ago

@89luca89 This is what I have been dogfooding for a long time now:

https://github.com/castedo/cnest/blob/beb989f00d5051975b35f98b4709ac255cc21cbd/bin/create-nest#L52-L54

So far it's been working fine for me. But I might just be lucky and not hitting the issue you are hitting.

This is also what distrobox is doing now (container_name.host_hostname) but this will give problems for graphical applications, as discussed in this gnome issue: https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/7531#note_2066704

The WM_CLIENT_MACHINE set on that window does not match your hostname, so the application is considered remote and will not be associated with a local .desktop file.

The only way to fix this is to actually have the same hostname between host and container it seems

castedo commented 8 months ago

Oh bummer. Us doing 'container_name.host_hostname' is kind of a hack. I'm not surprised it has confused some software somewhere. I've managed to not hit this problem because over the years I've drifted towards only using containers for CLI environments. For the few GUI apps that I use, I rely on existing Flatpacks.

Overall your idea of tweaking the shell prompt to use a $CONTAINER_ID environment variable sounds like a more proper approach than the hack we've been doing.

FWIW, this is the the way I tweak the shell prompt now in case it has useful elements:

Some parts of this approach might be useful for your $CONTAINER_ID fix.

cdock1029 commented 8 months ago

I think it's a great idea to default to same hostname and adjust the shell prompt for disambiguation of context. I use vscode, qtcreator, and a few other gui apps that benefit from shared dev environment in container when using openSUSE Aeon.

I didn't realize this was something you were already doing with the prompt as it doesn't display on my tumbleweed container though. I had to modify the PS1 in .bashrc myself for it to show up. Any ideas where this might be getting overwritten in tumbleweed?

castedo commented 1 month ago

For future visitors to this thread ...

I have changed Cnest v2.x to not mess with the hostname at all and not rely on changing the hostname to give a shell prompt indication.

To tweak the prompt Cnest 2.1 does this when the container is created:

https://github.com/castedo/cnest/blob/cnest-2.1-2/bin/create-cnest#L73

and passes $CONTAINER_NAME in for each shell session:

https://github.com/castedo/cnest/blob/cnest-2.1-2/bin/cnest#L57

Another of numerous advantages to not messing with the hostname automatically is that running podman rename to rename the container will not rename the hostname.