Python socket.gethostname() 数据源

Python socket.gethostname() 数据源

对于我正在 dockerized python3 模块内进行的项目。我遇到了socket.gethostname()总是返回随机 docker 名称的问题。由于这些实例是临时的,并且在重新生成之前只存在很短的时间,因此随机名称的积累速度非常快,我希望有一种方法来全面标准化这些名称。

我的限制是:

  1. 我无法控制上游源代码,因此修改它或维护我自己的版本是绝对不行的。
  2. 我无法控制 docker 容器的配置方式,因此在 docker 运行时设置名称是不可行的。

我的问题是:

  1. 数据从哪里socket.gethostname()获取?显然是从系统获取的,但具体从哪里获取,又是如何获取的?如果你更改/etc/hosts,它仍然会提取先前的值。
  2. 有没有办法直接告诉你的 python 环境,我想将主机名值设置为x无论系统设置的主机名如何(如果可能的话,这可能是理想的)?
  3. 处理这个问题最明智的方法是什么?

此外,如果有人愿意指出实际的源代码,以便socket.gethostname()我可以亲自了解它是如何工作的,我将不胜感激!

答案1

我期望 Pythonsocket.gethostname()只是一个薄包装系统gethostname调用, 哪个在 Ubuntu 上(使用 glibc)反过来又包装了系统uname调用

C library/kernel differences
   The  GNU  C  library does not employ the gethostname() system call; instead, it implements
   gethostname() as a library function that calls uname(2) and copies up to  len  bytes  from
   the  returned  nodename  field  into  name.

对于uname(2)

   This is a system call, and the operating system presumably knows its  name,  release,  and
   version.   It  also  knows what hardware it runs on.  So, four of the fields of the struct
   are meaningful.  On the other hand, the field nodename is meaningless: it gives  the  name
   of  the present machine in some undefined network, but typically machines are in more than
   one network and have several names.  Moreover, the kernel has no way of knowing about such
   things,  so  it  has  to  be  told what to answer here.  The same holds for the additional
   domainname field.

   To this end, Linux uses the system calls sethostname(2) and setdomainname(2).   Note  that
   there  is no standard that says that the hostname set by sethostname(2) is the same string
   as the nodename field of the struct returned by uname()  (indeed,  some  systems  allow  a
   256-byte  hostname and an 8-byte nodename), but this is true on Linux.  The same holds for
   setdomainname(2) and the domainname field.

所以:

  1. 这取决于做什么sethostname()。对于 Docker 容器来说,那就是 Docker 本身。

  2. 我不知道。

  3. 只是要求 Docker 设置任意主机名你想要的容器:

    % docker run --rm -it python:3.9 python -c 'import socket; print(socket.gethostname())'
    dd247ca179da
    % docker run --rm -it --hostname my-own-hostname python:3.9 python -c 'import socket; print(socket.gethostname())'
    my-own-hostname
    

以下是源代码的相关部分,Python 3.11.3

#ifdef HAVE_GETHOSTNAME
/* Python interface to gethostname(). */

/*ARGSUSED*/
static PyObject *
socket_gethostname(PyObject *self, PyObject *unused)
{
    if (PySys_Audit("socket.gethostname", NULL) < 0) {
        return NULL;
    }

#ifdef MS_WINDOWS
// snip
#else
    char buf[1024];
    int res;
    Py_BEGIN_ALLOW_THREADS
    res = gethostname(buf, (int) sizeof buf - 1);
    Py_END_ALLOW_THREADS
    if (res < 0)
        return set_error();
    buf[sizeof buf - 1] = '\0';
    return PyUnicode_DecodeFSDefault(buf);
#endif
}

相关内容