1# test code for the lineinfile module 2# (c) 2014, James Cammarata <jcammarata@ansible.com> 3 4# This file is part of Ansible 5# 6# Ansible is free software: you can redistribute it and/or modify 7# it under the terms of the GNU General Public License as published by 8# the Free Software Foundation, either version 3 of the License, or 9# (at your option) any later version. 10# 11# Ansible is distributed in the hope that it will be useful, 12# but WITHOUT ANY WARRANTY; without even the implied warranty of 13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14# GNU General Public License for more details. 15# 16# You should have received a copy of the GNU General Public License 17# along with Ansible. If not, see <http://www.gnu.org/licenses/>. 18 19- name: deploy the test file for lineinfile 20 copy: 21 src: test.txt 22 dest: "{{ output_dir }}/test.txt" 23 register: result 24 25- name: assert that the test file was deployed 26 assert: 27 that: 28 - result is changed 29 - "result.checksum == '5feac65e442c91f557fc90069ce6efc4d346ab51'" 30 - "result.state == 'file'" 31 32- name: insert a line at the beginning of the file, and back it up 33 lineinfile: 34 dest: "{{ output_dir }}/test.txt" 35 state: present 36 line: "New line at the beginning" 37 insertbefore: "BOF" 38 backup: yes 39 register: result1 40 41- name: insert a line at the beginning of the file again 42 lineinfile: 43 dest: "{{ output_dir }}/test.txt" 44 state: present 45 line: "New line at the beginning" 46 insertbefore: "BOF" 47 register: result2 48 49- name: assert that the line was inserted at the head of the file 50 assert: 51 that: 52 - result1 is changed 53 - result2 is not changed 54 - result1.msg == 'line added' 55 - result1.backup != '' 56 57- name: stat the backup file 58 stat: 59 path: "{{ result1.backup }}" 60 register: result 61 62- name: assert the backup file matches the previous hash 63 assert: 64 that: 65 - "result.stat.checksum == '5feac65e442c91f557fc90069ce6efc4d346ab51'" 66 67- name: stat the test after the insert at the head 68 stat: 69 path: "{{ output_dir }}/test.txt" 70 register: result 71 72- name: assert test hash is what we expect for the file with the insert at the head 73 assert: 74 that: 75 - "result.stat.checksum == '7eade4042b23b800958fe807b5bfc29f8541ec09'" 76 77- name: insert a line at the end of the file 78 lineinfile: 79 dest: "{{ output_dir }}/test.txt" 80 state: present 81 line: "New line at the end" 82 insertafter: "EOF" 83 register: result 84 85- name: assert that the line was inserted at the end of the file 86 assert: 87 that: 88 - result is changed 89 - "result.msg == 'line added'" 90 91- name: stat the test after the insert at the end 92 stat: 93 path: "{{ output_dir }}/test.txt" 94 register: result 95 96- name: assert test checksum matches after the insert at the end 97 assert: 98 that: 99 - "result.stat.checksum == 'fb57af7dc10a1006061b000f1f04c38e4bef50a9'" 100 101- name: insert a line after the first line 102 lineinfile: 103 dest: "{{ output_dir }}/test.txt" 104 state: present 105 line: "New line after line 1" 106 insertafter: "^This is line 1$" 107 register: result 108 109- name: assert that the line was inserted after the first line 110 assert: 111 that: 112 - result is changed 113 - "result.msg == 'line added'" 114 115- name: stat the test after insert after the first line 116 stat: 117 path: "{{ output_dir }}/test.txt" 118 register: result 119 120- name: assert test checksum matches after the insert after the first line 121 assert: 122 that: 123 - "result.stat.checksum == '5348da605b1bc93dbadf3a16474cdf22ef975bec'" 124 125- name: insert a line before the last line 126 lineinfile: 127 dest: "{{ output_dir }}/test.txt" 128 state: present 129 line: "New line before line 5" 130 insertbefore: "^This is line 5$" 131 register: result 132 133- name: assert that the line was inserted before the last line 134 assert: 135 that: 136 - result is changed 137 - "result.msg == 'line added'" 138 139- name: stat the test after the insert before the last line 140 stat: 141 path: "{{ output_dir }}/test.txt" 142 register: result 143 144- name: assert test checksum matches after the insert before the last line 145 assert: 146 that: 147 - "result.stat.checksum == '2e9e460ff68929e4453eb765761fd99814f6e286'" 148 149- name: Replace a line with backrefs 150 lineinfile: 151 dest: "{{ output_dir }}/test.txt" 152 state: present 153 line: "This is line 3" 154 backrefs: yes 155 regexp: "^(REF) .* \\1$" 156 register: backrefs_result1 157 158- name: Replace a line with backrefs again 159 lineinfile: 160 dest: "{{ output_dir }}/test.txt" 161 state: present 162 line: "This is line 3" 163 backrefs: yes 164 regexp: "^(REF) .* \\1$" 165 register: backrefs_result2 166- command: cat {{ output_dir }}/test.txt 167 168- name: assert that the line with backrefs was changed 169 assert: 170 that: 171 - backrefs_result1 is changed 172 - backrefs_result2 is not changed 173 - "backrefs_result1.msg == 'line replaced'" 174 175- name: stat the test after the backref line was replaced 176 stat: 177 path: "{{ output_dir }}/test.txt" 178 register: result 179 180- name: assert test checksum matches after backref line was replaced 181 assert: 182 that: 183 - "result.stat.checksum == '72f60239a735ae06e769d823f5c2b4232c634d9c'" 184 185- name: remove the middle line 186 lineinfile: 187 dest: "{{ output_dir }}/test.txt" 188 state: absent 189 regexp: "^This is line 3$" 190 register: result 191 192- name: assert that the line was removed 193 assert: 194 that: 195 - result is changed 196 - "result.msg == '1 line(s) removed'" 197 198- name: stat the test after the middle line was removed 199 stat: 200 path: "{{ output_dir }}/test.txt" 201 register: result 202 203- name: assert test checksum matches after the middle line was removed 204 assert: 205 that: 206 - "result.stat.checksum == 'd4eeb07bdebab2d1cdb3ec4a3635afa2618ad4ea'" 207 208- name: run a validation script that succeeds 209 lineinfile: 210 dest: "{{ output_dir }}/test.txt" 211 state: absent 212 regexp: "^This is line 5$" 213 validate: "true %s" 214 register: result 215 216- name: assert that the file validated after removing a line 217 assert: 218 that: 219 - result is changed 220 - "result.msg == '1 line(s) removed'" 221 222- name: stat the test after the validation succeeded 223 stat: 224 path: "{{ output_dir }}/test.txt" 225 register: result 226 227- name: assert test checksum matches after the validation succeeded 228 assert: 229 that: 230 - "result.stat.checksum == 'ab56c210ea82839a54487464800fed4878cb2608'" 231 232- name: run a validation script that fails 233 lineinfile: 234 dest: "{{ output_dir }}/test.txt" 235 state: absent 236 regexp: "^This is line 1$" 237 validate: "/bin/false %s" 238 register: result 239 ignore_errors: yes 240 241- name: assert that the validate failed 242 assert: 243 that: 244 - "result.failed == true" 245 246- name: stat the test after the validation failed 247 stat: 248 path: "{{ output_dir }}/test.txt" 249 register: result 250 251- name: assert test checksum matches the previous after the validation failed 252 assert: 253 that: 254 - "result.stat.checksum == 'ab56c210ea82839a54487464800fed4878cb2608'" 255 256- name: use create=yes 257 lineinfile: 258 dest: "{{ output_dir }}/new_test.txt" 259 create: yes 260 insertbefore: BOF 261 state: present 262 line: "This is a new file" 263 register: result 264 265- name: assert that the new file was created 266 assert: 267 that: 268 - result is changed 269 - "result.msg == 'line added'" 270 271- name: validate that the newly created file exists 272 stat: 273 path: "{{ output_dir }}/new_test.txt" 274 register: result 275 ignore_errors: yes 276 277- name: assert the newly created test checksum matches 278 assert: 279 that: 280 - "result.stat.checksum == '038f10f9e31202451b093163e81e06fbac0c6f3a'" 281 282- name: Create a file without a path 283 lineinfile: 284 dest: file.txt 285 create: yes 286 line: Test line 287 register: create_no_path_test 288 289- name: Stat the file 290 stat: 291 path: file.txt 292 register: create_no_path_file 293 294- name: Ensure file was created 295 assert: 296 that: 297 - create_no_path_test is changed 298 - create_no_path_file.stat.exists 299 300# Test EOF in cases where file has no newline at EOF 301- name: testnoeof deploy the file for lineinfile 302 copy: 303 src: testnoeof.txt 304 dest: "{{ output_dir }}/testnoeof.txt" 305 register: result 306 307- name: testnoeof insert a line at the end of the file 308 lineinfile: 309 dest: "{{ output_dir }}/testnoeof.txt" 310 state: present 311 line: "New line at the end" 312 insertafter: "EOF" 313 register: result 314 315- name: testempty assert that the line was inserted at the end of the file 316 assert: 317 that: 318 - result is changed 319 - "result.msg == 'line added'" 320 321- name: insert a multiple lines at the end of the file 322 lineinfile: 323 dest: "{{ output_dir }}/test.txt" 324 state: present 325 line: "This is a line\nwith \\n character" 326 insertafter: "EOF" 327 register: result 328 329- name: assert that the multiple lines was inserted 330 assert: 331 that: 332 - result is changed 333 - "result.msg == 'line added'" 334 335- name: testnoeof stat the no newline EOF test after the insert at the end 336 stat: 337 path: "{{ output_dir }}/testnoeof.txt" 338 register: result 339 340- name: testnoeof assert test checksum matches after the insert at the end 341 assert: 342 that: 343 - "result.stat.checksum == 'f9af7008e3cb67575ce653d094c79cabebf6e523'" 344 345# Test EOF with empty file to make sure no unnecessary newline is added 346- name: testempty deploy the testempty file for lineinfile 347 copy: 348 src: testempty.txt 349 dest: "{{ output_dir }}/testempty.txt" 350 register: result 351 352- name: testempty insert a line at the end of the file 353 lineinfile: 354 dest: "{{ output_dir }}/testempty.txt" 355 state: present 356 line: "New line at the end" 357 insertafter: "EOF" 358 register: result 359 360- name: testempty assert that the line was inserted at the end of the file 361 assert: 362 that: 363 - result is changed 364 - "result.msg == 'line added'" 365 366- name: testempty stat the test after the insert at the end 367 stat: 368 path: "{{ output_dir }}/testempty.txt" 369 register: result 370 371- name: testempty assert test checksum matches after the insert at the end 372 assert: 373 that: 374 - "result.stat.checksum == 'f440dc65ea9cec3fd496c1479ddf937e1b949412'" 375 376- stat: 377 path: "{{ output_dir }}/test.txt" 378 register: result 379 380- name: assert test checksum matches after inserting multiple lines 381 assert: 382 that: 383 - "result.stat.checksum == 'fde683229429a4f05d670e6c10afc875e1d5c489'" 384 385- name: replace a line with backrefs included in the line 386 lineinfile: 387 dest: "{{ output_dir }}/test.txt" 388 state: present 389 line: "New \\1 created with the backref" 390 backrefs: yes 391 regexp: "^This is (line 4)$" 392 register: result 393 394- name: assert that the line with backrefs was changed 395 assert: 396 that: 397 - result is changed 398 - "result.msg == 'line replaced'" 399 400- name: stat the test after the backref line was replaced 401 stat: 402 path: "{{ output_dir }}/test.txt" 403 register: result 404 405- name: assert test checksum matches after backref line was replaced 406 assert: 407 that: 408 - "result.stat.checksum == '981ad35c4b30b03bc3a1beedce0d1e72c491898e'" 409 410################################################################### 411# issue 8535 412 413- name: create a new file for testing quoting issues 414 file: 415 dest: "{{ output_dir }}/test_quoting.txt" 416 state: touch 417 register: result 418 419- name: assert the new file was created 420 assert: 421 that: 422 - result is changed 423 424- name: use with_items to add code-like strings to the quoting txt file 425 lineinfile: 426 dest: "{{ output_dir }}/test_quoting.txt" 427 line: "{{ item }}" 428 insertbefore: BOF 429 with_items: 430 - "'foo'" 431 - "dotenv.load();" 432 - "var dotenv = require('dotenv');" 433 register: result 434 435- name: assert the quote test file was modified correctly 436 assert: 437 that: 438 - result.results|length == 3 439 - result.results[0] is changed 440 - result.results[0].item == "'foo'" 441 - result.results[1] is changed 442 - result.results[1].item == "dotenv.load();" 443 - result.results[2] is changed 444 - result.results[2].item == "var dotenv = require('dotenv');" 445 446- name: stat the quote test file 447 stat: 448 path: "{{ output_dir }}/test_quoting.txt" 449 register: result 450 451- name: assert test checksum matches after backref line was replaced 452 assert: 453 that: 454 - "result.stat.checksum == '7dc3cb033c3971e73af0eaed6623d4e71e5743f1'" 455 456- name: insert a line into the quoted file with a single quote 457 lineinfile: 458 dest: "{{ output_dir }}/test_quoting.txt" 459 line: "import g'" 460 register: result 461 462- name: assert that the quoted file was changed 463 assert: 464 that: 465 - result is changed 466 467- name: stat the quote test file 468 stat: 469 path: "{{ output_dir }}/test_quoting.txt" 470 register: result 471 472- name: assert test checksum matches after backref line was replaced 473 assert: 474 that: 475 - "result.stat.checksum == '73b271c2cc1cef5663713bc0f00444b4bf9f4543'" 476 477- name: insert a line into the quoted file with many double quotation strings 478 lineinfile: 479 dest: "{{ output_dir }}/test_quoting.txt" 480 line: "\"quote\" and \"unquote\"" 481 register: result 482 483- name: assert that the quoted file was changed 484 assert: 485 that: 486 - result is changed 487 488- name: stat the quote test file 489 stat: 490 path: "{{ output_dir }}/test_quoting.txt" 491 register: result 492 493- name: assert test checksum matches after backref line was replaced 494 assert: 495 that: 496 - "result.stat.checksum == 'b10ab2a3c3b6492680c8d0b1d6f35aa6b8f9e731'" 497 498################################################################### 499# Issue 28721 500 501- name: Deploy the testmultiple file 502 copy: 503 src: testmultiple.txt 504 dest: "{{ output_dir }}/testmultiple.txt" 505 register: result 506 507- name: Assert that the testmultiple file was deployed 508 assert: 509 that: 510 - result is changed 511 - result.checksum == '3e0090a34fb641f3c01e9011546ff586260ea0ea' 512 - result.state == 'file' 513 514# Test insertafter 515- name: Write the same line to a file inserted after different lines 516 lineinfile: 517 path: "{{ output_dir }}/testmultiple.txt" 518 insertafter: "{{ item.regex }}" 519 line: "{{ item.replace }}" 520 register: _multitest_1 521 with_items: "{{ test_regexp }}" 522 523- name: Assert that the line is added once only 524 assert: 525 that: 526 - _multitest_1.results.0 is changed 527 - _multitest_1.results.1 is not changed 528 - _multitest_1.results.2 is not changed 529 - _multitest_1.results.3 is not changed 530 531- name: Do the same thing again to check for changes 532 lineinfile: 533 path: "{{ output_dir }}/testmultiple.txt" 534 insertafter: "{{ item.regex }}" 535 line: "{{ item.replace }}" 536 register: _multitest_2 537 with_items: "{{ test_regexp }}" 538 539- name: Assert that the line is not added anymore 540 assert: 541 that: 542 - _multitest_2.results.0 is not changed 543 - _multitest_2.results.1 is not changed 544 - _multitest_2.results.2 is not changed 545 - _multitest_2.results.3 is not changed 546 547- name: Stat the insertafter file 548 stat: 549 path: "{{ output_dir }}/testmultiple.txt" 550 register: result 551 552- name: Assert that the insertafter file matches expected checksum 553 assert: 554 that: 555 - result.stat.checksum == 'c6733b6c53ddd0e11e6ba39daa556ef8f4840761' 556 557# Test insertbefore 558 559- name: Deploy the testmultiple file 560 copy: 561 src: testmultiple.txt 562 dest: "{{ output_dir }}/testmultiple.txt" 563 register: result 564 565- name: Assert that the testmultiple file was deployed 566 assert: 567 that: 568 - result is changed 569 - result.checksum == '3e0090a34fb641f3c01e9011546ff586260ea0ea' 570 - result.state == 'file' 571 572- name: Write the same line to a file inserted before different lines 573 lineinfile: 574 path: "{{ output_dir }}/testmultiple.txt" 575 insertbefore: "{{ item.regex }}" 576 line: "{{ item.replace }}" 577 register: _multitest_3 578 with_items: "{{ test_regexp }}" 579 580- name: Assert that the line is added once only 581 assert: 582 that: 583 - _multitest_3.results.0 is changed 584 - _multitest_3.results.1 is not changed 585 - _multitest_3.results.2 is not changed 586 - _multitest_3.results.3 is not changed 587 588- name: Do the same thing again to check for changes 589 lineinfile: 590 path: "{{ output_dir }}/testmultiple.txt" 591 insertbefore: "{{ item.regex }}" 592 line: "{{ item.replace }}" 593 register: _multitest_4 594 with_items: "{{ test_regexp }}" 595 596- name: Assert that the line is not added anymore 597 assert: 598 that: 599 - _multitest_4.results.0 is not changed 600 - _multitest_4.results.1 is not changed 601 - _multitest_4.results.2 is not changed 602 - _multitest_4.results.3 is not changed 603 604- name: Stat the insertbefore file 605 stat: 606 path: "{{ output_dir }}/testmultiple.txt" 607 register: result 608 609- name: Assert that the insertbefore file matches expected checksum 610 assert: 611 that: 612 - result.stat.checksum == '5d298651fbc377b45257da10308a9dc2fe1f8be5' 613 614################################################################### 615# Issue 36156 616# Test insertbefore and insertafter with regexp 617 618- name: Deploy the test.conf file 619 copy: 620 src: test.conf 621 dest: "{{ output_dir }}/test.conf" 622 register: result 623 624- name: Assert that the test.conf file was deployed 625 assert: 626 that: 627 - result is changed 628 - result.checksum == '6037f13e419b132eb3fd20a89e60c6c87a6add38' 629 - result.state == 'file' 630 631# Test instertafter 632- name: Insert lines after with regexp 633 lineinfile: 634 path: "{{ output_dir }}/test.conf" 635 regexp: "{{ item.regexp }}" 636 line: "{{ item.line }}" 637 insertafter: "{{ item.after }}" 638 with_items: "{{ test_befaf_regexp }}" 639 register: _multitest_5 640 641- name: Do the same thing again and check for changes 642 lineinfile: 643 path: "{{ output_dir }}/test.conf" 644 regexp: "{{ item.regexp }}" 645 line: "{{ item.line }}" 646 insertafter: "{{ item.after }}" 647 with_items: "{{ test_befaf_regexp }}" 648 register: _multitest_6 649 650- name: Assert that the file was changed the first time but not the second time 651 assert: 652 that: 653 - item.0 is changed 654 - item.1 is not changed 655 with_together: 656 - "{{ _multitest_5.results }}" 657 - "{{ _multitest_6.results }}" 658 659- name: Stat the file 660 stat: 661 path: "{{ output_dir }}/test.conf" 662 register: result 663 664- name: Assert that the file contents match what is expected 665 assert: 666 that: 667 - result.stat.checksum == '06e2c456e5028dd7bcd0b117b5927a1139458c82' 668 669- name: Do the same thing a third time without regexp and check for changes 670 lineinfile: 671 path: "{{ output_dir }}/test.conf" 672 line: "{{ item.line }}" 673 insertafter: "{{ item.after }}" 674 with_items: "{{ test_befaf_regexp }}" 675 register: _multitest_7 676 677- name: Stat the file 678 stat: 679 path: "{{ output_dir }}/test.conf" 680 register: result 681 682- name: Assert that the file was changed when no regexp was provided 683 assert: 684 that: 685 - item is not changed 686 with_items: "{{ _multitest_7.results }}" 687 688- name: Stat the file 689 stat: 690 path: "{{ output_dir }}/test.conf" 691 register: result 692 693- name: Assert that the file contents match what is expected 694 assert: 695 that: 696 - result.stat.checksum == '06e2c456e5028dd7bcd0b117b5927a1139458c82' 697 698# Test insertbefore 699- name: Deploy the test.conf file 700 copy: 701 src: test.conf 702 dest: "{{ output_dir }}/test.conf" 703 register: result 704 705- name: Assert that the test.conf file was deployed 706 assert: 707 that: 708 - result is changed 709 - result.checksum == '6037f13e419b132eb3fd20a89e60c6c87a6add38' 710 - result.state == 'file' 711 712- name: Insert lines before with regexp 713 lineinfile: 714 path: "{{ output_dir }}/test.conf" 715 regexp: "{{ item.regexp }}" 716 line: "{{ item.line }}" 717 insertbefore: "{{ item.before }}" 718 with_items: "{{ test_befaf_regexp }}" 719 register: _multitest_8 720 721- name: Do the same thing again and check for changes 722 lineinfile: 723 path: "{{ output_dir }}/test.conf" 724 regexp: "{{ item.regexp }}" 725 line: "{{ item.line }}" 726 insertbefore: "{{ item.before }}" 727 with_items: "{{ test_befaf_regexp }}" 728 register: _multitest_9 729 730- name: Assert that the file was changed the first time but not the second time 731 assert: 732 that: 733 - item.0 is changed 734 - item.1 is not changed 735 with_together: 736 - "{{ _multitest_8.results }}" 737 - "{{ _multitest_9.results }}" 738 739- name: Stat the file 740 stat: 741 path: "{{ output_dir }}/test.conf" 742 register: result 743 744- name: Assert that the file contents match what is expected 745 assert: 746 that: 747 - result.stat.checksum == 'c3be9438a07c44d4c256cebfcdbca15a15b1db91' 748 749- name: Do the same thing a third time without regexp and check for changes 750 lineinfile: 751 path: "{{ output_dir }}/test.conf" 752 line: "{{ item.line }}" 753 insertbefore: "{{ item.before }}" 754 with_items: "{{ test_befaf_regexp }}" 755 register: _multitest_10 756 757- name: Stat the file 758 stat: 759 path: "{{ output_dir }}/test.conf" 760 register: result 761 762- name: Assert that the file was changed when no regexp was provided 763 assert: 764 that: 765 - item is not changed 766 with_items: "{{ _multitest_10.results }}" 767 768- name: Stat the file 769 stat: 770 path: "{{ output_dir }}/test.conf" 771 register: result 772 773- name: Assert that the file contents match what is expected 774 assert: 775 that: 776 - result.stat.checksum == 'c3be9438a07c44d4c256cebfcdbca15a15b1db91' 777 778- name: Copy empty file to test with insertbefore 779 copy: 780 src: testempty.txt 781 dest: "{{ output_dir }}/testempty.txt" 782 783- name: Add a line to empty file with insertbefore 784 lineinfile: 785 path: "{{ output_dir }}/testempty.txt" 786 line: top 787 insertbefore: '^not in the file$' 788 register: oneline_insbefore_test1 789 790- name: Add a line to file with only one line using insertbefore 791 lineinfile: 792 path: "{{ output_dir }}/testempty.txt" 793 line: top 794 insertbefore: '^not in the file$' 795 register: oneline_insbefore_test2 796 797- name: Stat the file 798 stat: 799 path: "{{ output_dir }}/testempty.txt" 800 register: oneline_insbefore_file 801 802- name: Assert that insertebefore worked properly with a one line file 803 assert: 804 that: 805 - oneline_insbefore_test1 is changed 806 - oneline_insbefore_test2 is not changed 807 - oneline_insbefore_file.stat.checksum == '4dca56d05a21f0d018cd311f43e134e4501cf6d9' 808 809################################################################### 810# Issue 29443 811# When using an empty regexp, replace the last line (since it matches every line) 812# but also provide a warning. 813 814- name: Deploy the test file for lineinfile 815 copy: 816 src: test.txt 817 dest: "{{ output_dir }}/test.txt" 818 register: result 819 820- name: Assert that the test file was deployed 821 assert: 822 that: 823 - result is changed 824 - result.checksum == '5feac65e442c91f557fc90069ce6efc4d346ab51' 825 - result.state == 'file' 826 827- name: Insert a line in the file using an empty string as a regular expression 828 lineinfile: 829 path: "{{ output_dir }}/test.txt" 830 regexp: '' 831 line: This is line 6 832 register: insert_empty_regexp 833 834- name: Stat the file 835 stat: 836 path: "{{ output_dir }}/test.txt" 837 register: result 838 839- name: Assert that the file contents match what is expected and a warning was displayed 840 assert: 841 that: 842 - insert_empty_regexp is changed 843 - warning_message in insert_empty_regexp.warnings 844 - result.stat.checksum == '23555a98ceaa88756b4c7c7bba49d9f86eed868f' 845 vars: 846 warning_message: >- 847 The regular expression is an empty string, which will match every line in the file. 848 This may have unintended consequences, such as replacing the last line in the file rather than appending. 849 If this is desired, use '^' to match every line in the file and avoid this warning. 850 851################################################################### 852## Issue #58923 853## Using firstmatch with insertafter and ensure multiple lines are not inserted 854 855- name: Deploy the firstmatch test file 856 copy: 857 src: firstmatch.txt 858 dest: "{{ output_dir }}/firstmatch.txt" 859 register: result 860 861- name: Assert that the test file was deployed 862 assert: 863 that: 864 - result is changed 865 - result.checksum == '1d644e5e2e51c67f1bd12d7bbe2686017f39923d' 866 - result.state == 'file' 867 868- name: Insert a line before an existing line using firstmatch 869 lineinfile: 870 path: "{{ output_dir }}/firstmatch.txt" 871 line: INSERT 872 insertafter: line1 873 firstmatch: yes 874 register: insertafter1 875 876- name: Insert a line before an existing line using firstmatch again 877 lineinfile: 878 path: "{{ output_dir }}/firstmatch.txt" 879 line: INSERT 880 insertafter: line1 881 firstmatch: yes 882 register: insertafter2 883 884- name: Stat the file 885 stat: 886 path: "{{ output_dir }}/firstmatch.txt" 887 register: result 888 889- name: Assert that the file was modified appropriately 890 assert: 891 that: 892 - insertafter1 is changed 893 - insertafter2 is not changed 894 - result.stat.checksum == '114aae024073a3ee8ec8db0ada03c5483326dd86' 895 896######################################################################################## 897# Tests of fixing the same issue as above (#58923) by @Andersson007 <aaklychkov@mail.ru> 898# and @samdoran <sdoran@redhat.com>: 899 900# Test insertafter with regexp 901- name: Deploy the test file 902 copy: 903 src: test_58923.txt 904 dest: "{{ output_dir }}/test_58923.txt" 905 register: initial_file 906 907- name: Assert that the test file was deployed 908 assert: 909 that: 910 - initial_file is changed 911 - initial_file.checksum == 'b6379ba43261c451a62102acb2c7f438a177c66e' 912 - initial_file.state == 'file' 913 914# Regarding the documentation: 915# If regular expressions are passed to both regexp and 916# insertafter, insertafter is only honored if no match for regexp is found. 917# Therefore, 918# when regular expressions are passed to both regexp and insertafter, then: 919# 1. regexp was found -> ignore insertafter, replace the founded line 920# 2. regexp was not found -> insert the line after 'insertafter' line 921 922# Regexp is not present in the file, so the line must be inserted after ^#!/bin/sh 923- name: Add the line using firstmatch, regexp, and insertafter 924 lineinfile: 925 path: "{{ output_dir }}/test_58923.txt" 926 insertafter: '^#!/bin/sh' 927 regexp: ^export FISHEYE_OPTS 928 firstmatch: true 929 line: export FISHEYE_OPTS="-Xmx4096m -Xms2048m" 930 register: insertafter_test1 931 932- name: Stat the file 933 stat: 934 path: "{{ output_dir }}/test_58923.txt" 935 register: insertafter_test1_file 936 937- name: Add the line using firstmatch, regexp, and insertafter again 938 lineinfile: 939 path: "{{ output_dir }}/test_58923.txt" 940 insertafter: '^#!/bin/sh' 941 regexp: ^export FISHEYE_OPTS 942 firstmatch: true 943 line: export FISHEYE_OPTS="-Xmx4096m -Xms2048m" 944 register: insertafter_test2 945 946# Check of the prev step. 947# We tried to add the same line with the same playbook, 948# so nothing has been added: 949- name: Stat the file again 950 stat: 951 path: "{{ output_dir }}/test_58923.txt" 952 register: insertafter_test2_file 953 954- name: Assert insertafter tests gave the expected results 955 assert: 956 that: 957 - insertafter_test1 is changed 958 - insertafter_test1_file.stat.checksum == '9232aed6fe88714964d9e29d13e42cd782070b08' 959 - insertafter_test2 is not changed 960 - insertafter_test2_file.stat.checksum == '9232aed6fe88714964d9e29d13e42cd782070b08' 961 962# Test insertafter without regexp 963- name: Deploy the test file 964 copy: 965 src: test_58923.txt 966 dest: "{{ output_dir }}/test_58923.txt" 967 register: initial_file 968 969- name: Assert that the test file was deployed 970 assert: 971 that: 972 - initial_file is changed 973 - initial_file.checksum == 'b6379ba43261c451a62102acb2c7f438a177c66e' 974 - initial_file.state == 'file' 975 976- name: Insert the line using firstmatch and insertafter without regexp 977 lineinfile: 978 path: "{{ output_dir }}/test_58923.txt" 979 insertafter: '^#!/bin/sh' 980 firstmatch: true 981 line: export FISHEYE_OPTS="-Xmx4096m -Xms2048m" 982 register: insertafter_test3 983 984- name: Stat the file 985 stat: 986 path: "{{ output_dir }}/test_58923.txt" 987 register: insertafter_test3_file 988 989- name: Insert the line using firstmatch and insertafter without regexp again 990 lineinfile: 991 path: "{{ output_dir }}/test_58923.txt" 992 insertafter: '^#!/bin/sh' 993 firstmatch: true 994 line: export FISHEYE_OPTS="-Xmx4096m -Xms2048m" 995 register: insertafter_test4 996 997- name: Stat the file again 998 stat: 999 path: "{{ output_dir }}/test_58923.txt" 1000 register: insertafter_test4_file 1001 1002- name: Assert insertafter without regexp tests gave the expected results 1003 assert: 1004 that: 1005 - insertafter_test3 is changed 1006 - insertafter_test3_file.stat.checksum == '9232aed6fe88714964d9e29d13e42cd782070b08' 1007 - insertafter_test4 is not changed 1008 - insertafter_test4_file.stat.checksum == '9232aed6fe88714964d9e29d13e42cd782070b08' 1009 1010 1011# Test insertbefore with regexp 1012- name: Deploy the test file 1013 copy: 1014 src: test_58923.txt 1015 dest: "{{ output_dir }}/test_58923.txt" 1016 register: initial_file 1017 1018- name: Assert that the test file was deployed 1019 assert: 1020 that: 1021 - initial_file is changed 1022 - initial_file.checksum == 'b6379ba43261c451a62102acb2c7f438a177c66e' 1023 - initial_file.state == 'file' 1024 1025- name: Add the line using regexp, firstmatch, and insertbefore 1026 lineinfile: 1027 path: "{{ output_dir }}/test_58923.txt" 1028 insertbefore: '^#!/bin/sh' 1029 regexp: ^export FISHEYE_OPTS 1030 firstmatch: true 1031 line: export FISHEYE_OPTS="-Xmx4096m -Xms2048m" 1032 register: insertbefore_test1 1033 1034- name: Stat the file 1035 stat: 1036 path: "{{ output_dir }}/test_58923.txt" 1037 register: insertbefore_test1_file 1038 1039- name: Add the line using regexp, firstmatch, and insertbefore again 1040 lineinfile: 1041 path: "{{ output_dir }}/test_58923.txt" 1042 insertbefore: '^#!/bin/sh' 1043 regexp: ^export FISHEYE_OPTS 1044 firstmatch: true 1045 line: export FISHEYE_OPTS="-Xmx4096m -Xms2048m" 1046 register: insertbefore_test2 1047 1048- name: Stat the file again 1049 stat: 1050 path: "{{ output_dir }}/test_58923.txt" 1051 register: insertbefore_test2_file 1052 1053- name: Assert insertbefore with regexp tests gave the expected results 1054 assert: 1055 that: 1056 - insertbefore_test1 is changed 1057 - insertbefore_test1_file.stat.checksum == '3c6630b9d44f561ea9ad999be56a7504cadc12f7' 1058 - insertbefore_test2 is not changed 1059 - insertbefore_test2_file.stat.checksum == '3c6630b9d44f561ea9ad999be56a7504cadc12f7' 1060 1061 1062# Test insertbefore without regexp 1063- name: Deploy the test file 1064 copy: 1065 src: test_58923.txt 1066 dest: "{{ output_dir }}/test_58923.txt" 1067 register: initial_file 1068 1069- name: Assert that the test file was deployed 1070 assert: 1071 that: 1072 - initial_file is changed 1073 - initial_file.checksum == 'b6379ba43261c451a62102acb2c7f438a177c66e' 1074 - initial_file.state == 'file' 1075 1076- name: Add the line using insertbefore and firstmatch 1077 lineinfile: 1078 path: "{{ output_dir }}/test_58923.txt" 1079 insertbefore: '^#!/bin/sh' 1080 firstmatch: true 1081 line: export FISHEYE_OPTS="-Xmx4096m -Xms2048m" 1082 register: insertbefore_test3 1083 1084- name: Stat the file 1085 stat: 1086 path: "{{ output_dir }}/test_58923.txt" 1087 register: insertbefore_test3_file 1088 1089- name: Add the line using insertbefore and firstmatch again 1090 lineinfile: 1091 path: "{{ output_dir }}/test_58923.txt" 1092 insertbefore: '^#!/bin/sh' 1093 firstmatch: true 1094 line: export FISHEYE_OPTS="-Xmx4096m -Xms2048m" 1095 register: insertbefore_test4 1096 1097- name: Stat the file again 1098 stat: 1099 path: "{{ output_dir }}/test_58923.txt" 1100 register: insertbefore_test4_file 1101 1102# Test when the line is presented in the file but 1103# not in the before/after spot and it does match the regexp: 1104- name: > 1105 Add the line using insertbefore and firstmatch when the regexp line 1106 is presented but not close to insertbefore spot 1107 lineinfile: 1108 path: "{{ output_dir }}/test_58923.txt" 1109 insertbefore: ' Darwin\*\) if \[ -z \"\$JAVA_HOME\" \] ; then' 1110 firstmatch: true 1111 line: export FISHEYE_OPTS="-Xmx4096m -Xms2048m" 1112 register: insertbefore_test5 1113 1114- name: Stat the file again 1115 stat: 1116 path: "{{ output_dir }}/test_58923.txt" 1117 register: insertbefore_test5_file 1118 1119- name: Assert insertbefore with regexp tests gave the expected results 1120 assert: 1121 that: 1122 - insertbefore_test3 is changed 1123 - insertbefore_test3_file.stat.checksum == '3c6630b9d44f561ea9ad999be56a7504cadc12f7' 1124 - insertbefore_test4 is not changed 1125 - insertbefore_test4_file.stat.checksum == '3c6630b9d44f561ea9ad999be56a7504cadc12f7' 1126 - insertbefore_test5 is not changed 1127 - insertbefore_test5_file.stat.checksum == '3c6630b9d44f561ea9ad999be56a7504cadc12f7' 1128 1129 1130# Test inserting a line at the end of the file using regexp with insertafter 1131# https://github.com/ansible/ansible/issues/63684 1132- name: Create a file by inserting a line 1133 lineinfile: 1134 path: "{{ output_dir }}/testend.txt" 1135 create: yes 1136 line: testline 1137 register: testend1 1138 1139- name: Insert a line at the end of the file 1140 lineinfile: 1141 path: "{{ output_dir }}/testend.txt" 1142 insertafter: testline 1143 regexp: line at the end 1144 line: line at the end 1145 register: testend2 1146 1147- name: Stat the file 1148 stat: 1149 path: "{{ output_dir }}/testend.txt" 1150 register: testend_file 1151 1152- name: Assert inserting at the end gave the expected results. 1153 assert: 1154 that: 1155 - testend1 is changed 1156 - testend2 is changed 1157 - testend_file.stat.checksum == 'ef36116966836ce04f6b249fd1837706acae4e19' 1158