2014-11-17 17 views
9

Yêu cầu đơn giản: Tôi muốn xóa một số tệp nếu việc sử dụng phân vùng vượt quá một tỷ lệ nhất định.Sử dụng không thể quản lý dung lượng đĩa

Tôi có quyền truy cập vào "size_total" và "size_available" qua "ansible_mounts". tức là:

ansible myhost -m setup -a 'filter=ansible_mounts' 
myhost | success >> { 
"ansible_facts": { 
    "ansible_mounts": [ 
     { 
      "device": "/dev/mapper/RootVolGroup00-lv_root", 
      "fstype": "ext4", 
      "mount": "/", 
      "options": "rw", 
      "size_available": 5033046016, 
      "size_total": 8455118848 
     }, 

Làm cách nào để truy cập vào các giá trị đó và làm cách nào để thực hiện các hành động có điều kiện dựa trên chúng bằng Ansible?

Trả lời

12

câu trả lời Slava của chắc chắn đã đi đúng hướng, đây là những gì tôi đã sử dụng:

- name: test for available disk space 
    assert: 
    that: 
     - not {{ item.mount == '/' and (item.size_available < item.size_total - (item.size_total|float * 0.8)) }} 
     - not {{ item.mount == '/var' and (item.size_available < item.size_total - (item.size_total|float * 0.8)) }} 
    with_items: ansible_mounts 
    ignore_errors: yes 
    register: disk_free 

- name: free disk space 
    command: "/some/command/that/fixes/it" 
    when: disk_free|failed 

Nhiệm vụ khẳng định chỉ đơn giản là kiểm tra cho một điều kiện, bằng cách thiết lập ignore_errors, và đăng ký kết quả của thử nghiệm với một biến mới, chúng ta có thể thực hiện một nhiệm vụ có điều kiện sau này trong vở kịch thay vì chỉ thất bại khi kết quả của xác nhận thất bại.

Bản thân các bài kiểm tra có thể được viết hiệu quả hơn, nhưng với chi phí dễ đọc. Vì vậy, tôi đã không sử dụng vòng lặp nhiều danh sách trong ví dụ. Trong trường hợp này, tác vụ lặp lại trên mỗi mục trong danh sách các hệ thống tập tin được gắn kết (một thực tế được tạo ra ansible, được gọi là ansible_mounts.)

Bằng cách loại bỏ phép thử mà chúng ta tránh không nằm trên hệ thống tập tin không có trong danh sách, sau đó xử lý toán học đơn giản phần còn lại. Phần mà tôi vấp phải là các biến size_available và size_total là các chuỗi, vì vậy một bộ lọc jinja chuyển đổi chúng thành một phao trước khi tính toán phần trăm.

+2

Vui lòng thêm một số giải thích về mã của bạn. – Nilambar

+0

Khi tôi đã thử điều này, tôi nhận được lỗi này: "Lỗi là: 'đối tượng unicode' không có thuộc tính 'mount'" – konrad

+0

Câu trả lời cho 'không có thuộc tính' mount '' vấn đề là sử dụng: with_items: '{{ansible_mounts }} '... tuy nhiên, ví dụ dường như cũng bị ngắt (ít nhất là trên Ans 2.2.1.0) khi cố gắng sử dụng cấu trúc | failed trên danh sách. .. Tôi có thể nhận được các xác nhận làm việc, nhưng gặp khó khăn để có được phần làm việc thất bại. – Cognitiaclaeves

2

tôi đã không kiểm tra nó nhưng tôi đề nghị để thử một cái gì đó như thế này:

file: 
    dest: /path/to/big/file 
    state: absent 
    when: "{% for point in ansible_mounts %}{% if point.mount == '/' and point.size_available > (point.size_total/100 * 85) %}true{% endif %}{% endfor %}" == "true" 

Trong ví dụ này, chúng ta lặp qua điểm lắp và tìm "/", sau đó chúng tôi tính toán là có sử dụng đi qua 85 phần trăm và bản in "true" nếu đó là sự thật. Tiếp theo, chúng tôi so sánh chuỗi đó và quyết định tệp này có bị xóa hay không.

Lấy cảm hứng từ các ví dụ từ blog sau đây: https://blog.codecentric.de/en/2014/08/jinja2-better-ansible-playbooks-templates/

0

Giải pháp của tôi

- name: cleanup logs, free disk space below 20% 
    sudo: yes 
    command: find /var -name "*.log" \(\(-size +50M -mtime +7 \) -o -mtime +30 \) -exec truncate {} --size 0 \; 
    when: "item.mount == '/var' and (item.size_available < item.size_total * 0.2)" 
    with_items: ansible_mounts 

này sẽ cắt bất kỳ *.log tập tin trên volume /var rằng hoặc là lớn hơn 7 ngày và lớn hơn 50M hoặc cũ hơn 30 ngày nếu không gian đĩa miễn phí giảm xuống dưới 20%.

3

Trong trường hợp của tôi, tất cả những gì tôi quan tâm là phân vùng gốc. Nhưng tôi tìm thấy khi sử dụng ví dụ từ frameloss ở trên, rằng tôi cần một điều kiện 'hoặc' phủ định, bởi vì mỗi điểm gắn kết sẽ được kiểm tra dựa trên xác nhận. Nếu có nhiều hơn một điểm gắn kết tồn tại, thì điều đó có nghĩa là xác nhận sẽ luôn thất bại. Trong ví dụ của tôi, tôi đang thử nghiệm nếu size_available nhỏ hơn 50% size_total trực tiếp, thay vì tính toán nó như frameloss đã làm.

Thứ hai, ít nhất là trong phiên bản ansible tôi đã sử dụng, cần phải bao gồm {{}} xung quanh biến trong with_items. Một sai lầm mà tôi đã thực hiện mà không có trong ví dụ trên là không căn chỉnh mệnh đề 'khi' ở cùng một thụt đầu dòng như chỉ thị 'không thành công'. (Nếu sai lầm đó được thực hiện, thì giải pháp không hoạt động ...)

# This works with ansible 2.2.1.0 
- hosts: api-endpoints 
    become: True 
    tasks: 

    - name: Test disk space available 
     assert: 
     that: 
      - item.mount != '/' or {{ item.mount == '/' and item.size_available > (item.size_total|float * 0.4) }} 
     with_items: '{{ ansible_mounts }}' 
     ignore_errors: yes 
     register: disk_free 

    - name: Fail when disk space needs attention 
     fail: 
     msg: 'Disk space needs attention.' 
     when: disk_free|failed 
Các vấn đề liên quan