New FAMILUG

The PyMiers

Monday, 24 November 2025

Đọc code Python xem Ansible group priority thay đổi thứ tự gộp group vars

Ansible group dùng để nhóm các máy lại thành từng nhóm trong kho inventory. Khi một máy nằm trong nhiều group, các group vars sẽ được gộp lại, theo thứ tự children sẽ ghi đè parent, group sau sẽ ghi đè group trước. Sau và trước mặc định dựa theo tên group theo thứ tự bảng chữ cái. Trong Ansible inventory có thể cấu hình group priority cho group, khi không set có giá trị mặc định là 1, giá trị priority có kiểu int, có thể là số âm.

#  lib/ansible/inventory/group.py 
class Group:
    """A group of ansible hosts."""

    def __init__(self, name: str) -> None:
        name = helpers.remove_trust(name)

        self.depth: int = 0
        self.name: str = to_safe_group_name(name)
        self.hosts: list[Host] = []
        self._hosts: set[str] | None = None
        self.vars: dict[str, t.Any] = {}
        self.child_groups: list[Group] = []
        self.parent_groups: list[Group] = []
        self._hosts_cache: list[Host] | None = None
        self.priority: int = 1
...
    def set_variable(self, key: str, value: t.Any) -> None:
        ...
        if key == 'ansible_group_priority':
            self.set_priority(int(value))
        else:
            if key in self.vars and isinstance(self.vars[key], MutableMapping) and isinstance(value, Mapping):
                self.vars = combine_vars(self.vars, {key: value})
            else:
                self.vars[key] = value

Xem online GitHub.

Khi gộp var của các groups, Ansible sắp xếp theo thứ tự tăng dần theo:

  • depth: mỗi cấp children tăng depth lên 1
  • group priority
  • group name

rồi cho var sau ghi đè lên var trước:

#  lib/ansible/inventory/helpers.py 
def sort_groups(groups):
    return sorted(groups, key=lambda g: (g.depth, g.priority, g.name))

def get_group_vars(groups):
    """
    Combine all the group vars from a list of inventory groups.

    :param groups: list of ansible.inventory.group.Group objects
    :rtype: dict
    """
    results = {}
    for group in sort_groups(groups):
        results = combine_vars(results, group.get_vars())

    return results

Xem online GitHub.

Nếu file inventory.yml viết:

db:
  ansible_group_priority: 20
  hosts:
    vm1:

webserver:
  hosts:
    vm1:

Thì var user: abcdb trong group_vars/db sẽ được dùng thay vì var user: webuser ghi trong group_vars/webserver.

Kết luận

ansible_group_priority chỉ được nhắc tới 1 lần duy nhất trong tài liệu nhưng là tính năng rất quan trọng khi cần sắp xếp thứ tự ưu tiên group vars.

Hết.

HVN at https://pymi.vn and https://www.familug.org.

Ủng hộ tác giả 🍺

Wednesday, 12 November 2025

Thẻ HTML link rel=alternate

Trong HTML, thẻ <link> thường dùng để liên kết các file file CSS hay favicon:

<link rel="stylesheet" type="text/css" href="./theme/css/custom.css" media="screen">
<link rel="icon" href="favicon.ico" />

The <link> HTML element specifies relationships between the current document and an external resource. This element is most commonly used to link to stylesheets, but is also used to establish site icons (both "favicon" style icons and icons for the home screen and apps on mobile devices) among other things. https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/link

Ngoài hai giá trị rel (relation) stylesheet, icon nói trên, còn nhiều giá trị khác, trong đó đáng chú ý là alternate

The rel attribute defines the relationship between a linked resource and the current document

Alternate representations of the current document.

rel="alternate" dùng để liên kết tới các phiên bản, định dạng thay thế của trang web hiện tại:

  • trang dành riêng cho ngôn ngữ khác
  • biểu diễn khác thay vì HTML: RSS/XML - RSS feed

Ví dụ trên https://wordpress.com:

<link rel="alternate" hreflang="ja" href="https://wordpress.com/ja/" />
<link rel="alternate" hreflang="vi" href="https://wordpress.com/vi/" />
<link rel="alternate" type="application/rss+xml" title="WordPress.com Blog" href="https://wordpress.com/blog/feed/" />
<link rel="alternate" type="application/rss+xml" title="WordPress.com Discover" href="//discover.wordpress.com/feed/" />

Các chương trình đọc RSS (RSS reader) có thể tự tìm trong mã nguồn HTML của trang (page source) các thẻ <link rel="alternate" type="application/rss+xml"> để tìm ra đường dẫn tới feed, ngay cả khi chúng không hiện trực tiếp lên trang chủ.

Kết luận

<link rel="alternate"> là nơi chứa thông tin quan trọng, dù không hiện trực tiếp lên giao diện người dùng.

Hết.

HVN at https://pymi.vn and https://www.familug.org.

Ủng hộ tác giả 🍺

Saturday, 1 November 2025

Ansible không ưu tiên CLI option --user cao bằng inventory

99% các chương trình có giao diện dòng lệnh CLI đều ưu tiên option được người dùng chỉ định mức ưu tiên cao nhất. Ansible đặc biệt, vì nó nằm trong 1% còn lại.

Mặc định, ansible sử dụng user của người dùng gõ lệnh $USER để ssh vào máy cần quản lý. Người dùng có thể thay đổi giá trị này với option --user REMOTE_USER. Nhưng khi trong inventory có chỉ định ansible_user thì khác:

all:
  hosts:
    vm1:
      ansible_host: 127.0.0.1
      ansible_user: inventory_user

Chạy:

$ ansible-playbook -i inventory.yml order.yml --user cli_user

PLAY [all] **************************************************************************

TASK [Gathering Facts] **************************************************************
[ERROR]: Task failed: Failed to connect to the host via ssh: inventory_user@127.0.0.1: Permission denied (publickey,password).
fatal: [vm1]: UNREACHABLE! => {"changed": false, "msg": "Task failed: Failed to connect to the host via ssh: inventory_user@127.0.0.1: Permission denied (publickey,password).", "unreachable": true}

PLAY RECAP **************************************************************************
vm1                        : ok=0    changed=0    unreachable=1    failed=0    skipped=0    rescued=0    ignored=0   

ansible sử dụng user inventory_user cấu hình trong file inventory.yml để kết nối tới máy vm1 chứ không dùng cli_user và thất bại:

Failed to connect to the host via ssh: inventory_user@127.0.0.1: Permission denied.

Đừng cảm thấy cô đơn, vì bạn không phải người duy nhất: ansible -u does not take precedence over ansible_ssh_user from inventory #4622

Ansible set CLI option ở mức ưu tiên thấp nhất

Some behavioral parameters that you can set in variables you can also set in Ansible configuration, as command-line options, and using playbook keywords. For example, you can define the user that Ansible uses to connect to remote devices as a variable with ansible_user, in a configuration file with DEFAULT_REMOTE_USER, as a command-line option with -u, and with the playbook keyword remote_user. If you define the same parameter in a variable and by another method, the variable overrides the other setting. This approach allows host-specific settings to override more general settings. For examples and more details on the precedence of these various settings, see Controlling how Ansible behaves: precedence rules.

ansible_user là 1 variable, nó tuân theo luật ưu tiên:

Ansible does apply variable precedence, and you might have a use for it. Here is the order of precedence from least to greatest (the last listed variables override all other variables):

. Command-line values (for example, -u my_user, these are not variables)

...

. Inventory file or script host vars [2]_

tức command-line value có mức ưu tiên thấp nhất.

When you type something directly at the command line, you may feel that your hand-crafted values should override all others, but Ansible does not work that way. Command-line options have low precedence - they override configuration only. They do not override playbook keywords, variables from inventory or variables from playbooks. source

Giải pháp

#. Extra vars (for example, -e "user=my_user")(always win precedence) source

extra vars được gán qua option -e có độ ưu tiên cao nhất, thay vì -u cli_user, hãy dùng -e ansible_user=cli_user.

Kết luận

Ansible rất thành công so với các đối thủ lừng lẫy một thời của nó: Salt, Puppet, Chef. Người thành công thường có lối đi riêng ???!!!

Hết.

HVN at https://pymi.vn and https://www.familug.org.

Ủng hộ tác giả 🍺