1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758
|
.. index:: migrating known device
.. _migrating_known_device_example:
Worked example of migrating a known device
##########################################
This guide makes the following assumptions:
#. You have access to a working LAVA instance with pipeline support.
#. You have at least one working device of a known device type
#. You have at least one working JSON job submission for that device.
#. You are migrating to a deployment type and boot type which is
already supported by the pipeline code.
#. You have read access to the current configuration of that device,
including PDU port numbers and serial port access.
Things will go more easily if you also have:
#. admin access to the django configuration of the LAVA instance
#. root command line access to the dispatcher currently using the device.
#. a browser tab open at the `Online YAML parser
<http://yaml-online-parser.appspot.com/?yaml=>`_
.. note:: some parts of the refactoring are still in development, so not all of
the support may be available. However, as YAML supports comments, this data
is not lost.
.. seealso:: :ref:`YAML syntax errors <writing_new_job_yaml>`
The objective is to migrate the configuration of the existing device such that
exactly the same commands are sent to the device as in the current dispatcher
jobs, with the benefit of pipeline validation, results and metadata.
.. note:: The specific example follows a real conversion but the hardware
concerned has since changed to a different deployment method. The examples
here worked when the example was written but will not work on current
deployments of the hardware concerned.
.. _writing_device_config_yaml:
Writing a device configuration in YAML
**************************************
The current dispatcher configuration is in two parts and these will typically
be respected in the migration.
The :term:`device type` configuration will become a device type template.
The device configuration will become a device dictionary.
However, initially, we need a single YAML file which contains the data that the
pipeline will send to the dispatcher - a combination of the device type and
device information. You can see examples of such content when validating
pipeline jobs. (This is example and has been edited slightly to take out some
of the noise.)::
$ sudo lava-dispatch --target devices/bbb-01.yaml bbb-uboot-ramdisk.yaml --validate --output-dir=/tmp/test/
Don't worry about running this example yourself at this stage. The files
themselves may be useful for reference. The device YAML file comes from the
lava-dispatcher unit tests:
https://gitlab.com/lava/lava/-/raw/master/tests/lava_scheduler_app/devices/bbb-01.yaml
The job submission YAML used in the example comes from the lava-team
refactoring repository of functional tests:
https://git.linaro.org/lava-team/refactoring.git/tree/bbb-uboot-ramdisk.yaml
.. code-block:: yaml
device: !!python/object/new:lava_dispatcher.device.NewDevice
dictitems:
actions:
boot:
prompts:
- 'linaro-test'
- 'root@debian:~#'
connections: {serial: null, ssh: null}
methods:
u-boot:
parameters: {boot_message: Booting Linux, bootloader_prompt: U-Boot}
ramdisk:
commands: [setenv autoload no, setenv initrd_high '0xffffffff', setenv
fdt_high '0xffffffff', 'setenv kernel_addr_r ''{KERNEL_ADDR}''',
'setenv initrd_addr_r ''{RAMDISK_ADDR}''', 'setenv fdt_addr_r ''{DTB_ADDR}''',
'setenv loadkernel ''tftp ${kernel_addr_r} {KERNEL}''', 'setenv loadinitrd
''tftp ${initrd_addr_r} {RAMDISK}; setenv initrd_size ${filesize}''',
'setenv loadfdt ''tftp ${fdt_addr_r} {DTB}''', 'setenv bootargs ''console=ttyO0,115200n8
root=/dev/ram0 ip=dhcp''', 'setenv bootcmd ''dhcp; setenv serverip
{SERVER_IP}; run loadkernel; run loadinitrd; run loadfdt; {BOOTX}''',
boot]
deploy:
methods:
tftp: null
usb: null
commands: {connect: telnet localhost 6000}
hostname: bbb-01
parameters:
bootm: {dtb: '0x815f0000', kernel: '0x80200000', ramdisk: '0x81600000'}
bootz: {dtb: '0x81f00000', kernel: '0x81000000', ramdisk: '0x82000000'}
power_state: 'off'
timeouts:
apply-overlay-image: {seconds: 120}
lava-test-shell: {seconds: 30}
power_off: {seconds: 5}
umount-retry: {seconds: 45}
state: {target: bbb-01}
This snippet includes the connection command (``telnet localhost 6000``) from
the device configuration and the ramdisk uboot parameters from the device type
configuration - note that as this is the validation output, no job files have
been downloaded, so the substitution placeholders remain, ``{DTB}``,
``{SERVER_IP}``, ``{KERNEL}`` etc. - this is correct and will help with the
next steps. What isn't so helpful at the moment is the layout of this YAML
dump.
.. _migrating_mustang:
Migrating a mustang
===================
Existing configuration::
device_type = mustang
hostname = staging-mustang01
hard_reset_command = /usr/bin/pduclient --daemon services --hostname pdu15 --command reboot --port 05
power_off_cmd = /usr/bin/pduclient --daemon services --hostname pdu15 --command off --port 05
connection_command = telnet serial4 7012
reset_port_command = flock /var/lock/serial1.lock /usr/local/lab-scripts/reset-serial5000 serial4 12
image_boot_msg_timeout = 240
Start with a new file:
.. code-block:: yaml
# hostname is irrelevant in the refactoring, the dispatcher uses what it is given.
commands:
connect: telnet serial4 7012
hard_reset: /usr/bin/pduclient --daemon services --hostname pdu15 --command reboot --port 05
power_off: /usr/bin/pduclient --daemon services --hostname pdu15 --command off --port 05
power_on: /usr/bin/pduclient --daemon services --hostname pdu15 --command on --port 05
# power_on is new in the refactoring.
# reset_port_command not yet ported:
# reset_port: flock /var/lock/serial1.lock /usr/local/lab-scripts/reset-serial5000 serial4 12
# timeouts are handled later in the file.
So far, so good. Now add the device type configuration blocks. This is the
existing configuration::
client_type = bootloader
bootloader_prompt = Mustang
uimage_only = True
boot_cmd_timeout = 60
text_offset = 0x80000
u_load_addrs =
0x4002000000
0x4004000000
0x4003000000
z_load_addrs =
0x4002000000
0x4004000000
0x4003000000
boot_cmds_nfs =
setenv autoload no,
setenv kernel_addr_r "'{KERNEL_ADDR}'",
setenv initrd_addr_r "'{RAMDISK_ADDR}'",
setenv fdt_addr_r "'{DTB_ADDR}'",
setenv loadkernel "'tftp ${kernel_addr_r} {KERNEL}'",
setenv loadinitrd "'tftp ${initrd_addr_r} {RAMDISK}'",
setenv loadfdt "'tftp ${fdt_addr_r} {DTB}'",
setenv nfsargs "'setenv bootargs root=/dev/nfs rw nfsroot={SERVER_IP}:{NFSROOTFS},tcp,hard,intr panic=1 console=ttyS0,115200 earlyprintk=uart8250-32bit,0x1c020000 debug ip=dhcp'",
setenv bootcmd "'dhcp; setenv serverip {SERVER_IP}; run loadkernel; run loadinitrd; run loadfdt; run nfsargs; {BOOTX}'",
boot
boot_cmds_ramdisk =
setenv autoload no,
setenv kernel_addr_r "'{KERNEL_ADDR}'",
setenv initrd_addr_r "'{RAMDISK_ADDR}'",
setenv fdt_addr_r "'{DTB_ADDR}'",
setenv loadkernel "'tftp ${kernel_addr_r} {KERNEL}'",
setenv loadinitrd "'tftp ${initrd_addr_r} {RAMDISK}'",
setenv loadfdt "'tftp ${fdt_addr_r} {DTB}'",
setenv bootargs "'root=/dev/ram0 rw panic=1 console=ttyS0,115200 earlyprintk=uart8250-32bit,0x1c020000 debug ip=dhcp'",
setenv bootcmd "'dhcp; setenv serverip {SERVER_IP}; run loadkernel; run loadinitrd; run loadfdt; {BOOTX}'",
boot
boot_cmds =
boot
boot_options =
boot_cmds
[boot_cmds]
default = boot_cmds
Extend the existing YAML file, to add:
#. parameters
#. actions
#. deploy and boot methods
#. method parameters
#. method commands
Parameters
----------
Note how the existing config just lists the addresses without identifying which
is the kernel load addr. Although these blocks are the same in this example,
the addresses can differ between z_load and u_load.::
u_load_addrs =
0x4002000000
0x4004000000
0x4003000000
z_load_addrs =
0x4002000000
0x4004000000
0x4003000000
Use a working job log file to identify which is where::
<LAVA_DISPATCHER>2015-06-19 08:32:29 AM DEBUG: boot_cmds(after preprocessing):
['setenv autoload no', u"setenv kernel_addr_r '0x4002000000'",
u"setenv initrd_addr_r '0x4004000000'",
u"setenv fdt_addr_r '0x4003000000'",
u"setenv loadkernel 'tftp ${kernel_addr_r} tmplv_wQe/uImage_1.11'",
"setenv loadinitrd 'tftp ${initrd_addr_r} {RAMDISK}'",
u"setenv loadfdt 'tftp ${fdt_addr_r} tmplv_wQe/mustang.dtb_1.11'",
u"setenv nfsargs 'setenv bootargs root=/dev/nfs rw
nfsroot=10.3.2.1:/var/lib/lava/dispatcher/tmp/tmplv_wQe/tmprhrAXO,tcp,hard,intr
panic=1 console=ttyS0,115200 earlyprintk=uart8250-32bit,0x1c020000 debug ip=dhcp'",
u"setenv bootcmd 'dhcp; setenv serverip 10.3.2.1; run loadkernel;
run loadinitrd; run loadfdt; run nfsargs; bootm ${kernel_addr_r} - ${fdt_addr_r}'", 'boot']
Note here that the action job uses ``bootm``, so it is ``bootm`` parameters we
need to specify.
.. code-block:: yaml
parameters:
bootm:
kernel: '0x4002000000'
ramdisk: '0x4004000000'
dtb: '0x4003000000'
Only add ``bootz`` support if you know that the U-Boot ``bootz`` command is
present in the U-Boot version on the board and that it works with zImage
kernels. The eventual templates will exist on the server and can be used to
declare the detailed device support so that test writers know in advance what
kind of images the device can use.
.. index:: trailing comma
.. _v1_trailing_commas:
Actions
-------
For this example, the deployment method is relatively simple - you can see from
the working job that it is using ``tftp`` to deploy.
.. code-block:: yaml
actions:
deploy:
methods:
- tftp
**Always** check your YAML syntax. The YAML parser can provide links to small
snippets of YAML, `like the one above
<http://yaml-online-parser.appspot.com/?yaml=actions%3A%0A++deploy%3A%0A++++methods%3A%0A++++-+tftp%0A&type=json>`_
The boot support is where things become more detailed.
.. code-block:: yaml
boot:
prompts:
- 'linaro-test'
- 'root@debian:~#'
methods:
u-boot:
parameters:
bootloader_prompt: Mustang
boot_message: Starting kernel
The bootloader prompt (at this stage) comes from the device type configuration.
The boot message will later be supportable as image-specific. For now, you need
whatever values work with the current state of the device. The ``boot_message``
is a string emitted during the boot which denotes a successful attempt to boot.
There is no need to quote the string unless it contains an illegal character in
YAML like a colon.
Next are the commands for the deployment method itself:
.. code-block:: yaml
nfs:
commands:
- setenv autoload no
- setenv kernel_addr_r '{KERNEL_ADDR}'
- setenv initrd_addr_r '{RAMDISK_ADDR}'
- setenv fdt_addr_r '{DTB_ADDR}'
- setenv loadkernel 'tftp ${kernel_addr_r} {KERNEL}'
- setenv loadinitrd 'tftp ${initrd_addr_r} {RAMDISK}'
- setenv loadfdt 'tftp ${fdt_addr_r} {DTB}'
- "setenv nfsargs 'setenv bootargs root=/dev/nfs rw nfsroot={SERVER_IP}:{NFSROOTFS},tcp,hard,intr panic=1 console=ttyS0,115200 earlyprintk=uart8250-32bit,0x1c020000 debug ip=dhcp'"
- setenv bootcmd 'dhcp; setenv serverip {SERVER_IP}; run loadkernel; run loadinitrd; run loadfdt; run nfsargs; {BOOTX}'
- boot
These are retained with only formatting changes - after all, these are what the
device needs to be able to boot.
#. Remove **trailing commas** (remnants of the old config)
#. Remove one level of quote marks **unless** the command embeds a colon (e.g.
NFS), in which case the **whole line** is quoted.
#. Make each line part of a list by prefixing with a hyphen and a space.
.. note:: Trailing commas are known to cause problems on devices - check the
config carefully and be particularly watchful for failures where the device
reports ``cannot find device 'net0,'`` when working V1 jobs would report
using ``device 'net0'``. Commas are required in V1 but YAML processing for
V2 will include trailing commas as part of the string, not part of the
formatting.
Timeouts
--------
A process of trial and error will illuminate which timeouts are appropriate to
set at this level.
.. code-block:: yaml
timeouts:
power_off:
seconds: 5
Complete device YAML
====================
Untested at this point, but this is the start of the integration.
.. code-block:: yaml
# hostname is irrelevant in the refactoring, the dispatcher uses what it is given.
commands:
connect: telnet serial4 7012
hard_reset: /usr/bin/pduclient --daemon services --hostname pdu15 --command reboot --port 05
power_off: /usr/bin/pduclient --daemon services --hostname pdu15 --command off --port 05
power_on: /usr/bin/pduclient --daemon services --hostname pdu15 --command on --port 05
# power_on is new in the refactoring.
# reset_port_command not yet ported:
# reset_port: flock /var/lock/serial1.lock /usr/local/lab-scripts/reset-serial5000 serial4 12
# timeouts are handled later in the file.
parameters:
bootm:
kernel: '0x4002000000'
ramdisk: '0x4004000000'
dtb: '0x4003000000'
actions:
deploy:
methods:
- tftp
boot:
prompts:
- 'linaro-test'
- 'root@debian:~#'
methods:
u-boot:
parameters:
bootloader_prompt: Mustang
boot_message: Starting kernel
nfs:
commands:
- setenv autoload no
- setenv kernel_addr_r '{KERNEL_ADDR}'
- setenv initrd_addr_r '{RAMDISK_ADDR}'
- setenv fdt_addr_r '{DTB_ADDR}'
- setenv loadkernel 'tftp ${kernel_addr_r} {KERNEL}'
- setenv loadinitrd 'tftp ${initrd_addr_r} {RAMDISK}'
- setenv loadfdt 'tftp ${fdt_addr_r} {DTB}'
- "setenv nfsargs 'setenv bootargs root=/dev/nfs rw nfsroot={SERVER_IP}:{NFSROOTFS},tcp,hard,intr panic=1 console=ttyS0,115200 earlyprintk=uart8250-32bit,0x1c020000 debug ip=dhcp'"
- setenv bootcmd 'dhcp; setenv serverip {SERVER_IP}; run loadkernel; run loadinitrd; run loadfdt; run nfsargs; {BOOTX}'
- boot
timeouts:
power_off:
seconds: 5
.. _writing_job_submission_yaml:
Writing a job submission in YAML
********************************
.. warning:: Do **not** be tempted into writing a script to convert the JSON to
YAML. You need to understand what the job is doing and why. e.g. the
original job gives no clue that ``U-Boot`` is involved nor that the required
``U-Boot`` parameters for this job are ``bootm`` and not ``bootz``. Any such
attempts would re-introduce assumptions that the refactoring is deliberately
removing. Just because a file has a particular name or suffix does not mean
that the job can make any safe assumptions about the content of that file.
Migrating a job for the mustang
===============================
Existing JSON::
{
"actions": [
{
"command": "deploy_linaro_kernel",
"metadata": {
"distribution": "debian"
},
"parameters": {
"dtb": "http://images-internal/mustang/mustang.dtb_1.11",
"kernel": "http://images-internal/mustang/uImage_1.11",
"login_prompt": "login:",
"nfsrootfs": "https://people.linaro.org/~neil.williams/arm64/debian-jessie-arm64-rootfs.tar.gz",
"target_type": "ubuntu",
"username": "root"
}
},
{
"command": "boot_linaro_image"
},
{
"command": "lava_test_shell",
"parameters": {
"testdef_repos": [
{
"git-repo": "https://git.linaro.org/people/neil.williams/temp-functional-tests.git",
"testdef": "singlenode/singlenode03.yaml"
}
],
"timeout": 900
}
},
{
"command": "submit_results",
"parameters": {
"server": "https://staging.validation.linaro.org/RPC2",
"stream": "/anonymous/lava-functional-tests/"
}
}
],
"device_type": "mustang",
"job_name": "mustang-singlenode-jessie",
"timeout": 900
}
Identifying the elements of the job
-----------------------------------
Forget the ``deploy_linaro_kernel``, this is a deployment of a kernel, a DTB
and an NFS root filesystem.
Start with the top level structures:
.. code-block:: yaml
device_type: mustang
job_name: mustang-singlenode-jessie
timeouts:
job:
minutes: 15
``device_type`` isn't strictly necessary at this point but it will become
necessary once this job is able to be submitted via the server rather than
directly to the dispatcher.
Now identify the actions - a single deploy, a single boot and a single test.
Deploy
^^^^^^
.. include:: examples/test-jobs/mustang-admin-example-job.yaml
:code: yaml
:start-after: actions:
:end-before: - boot
Boot
^^^^
Note that ``boot`` has the details of the autologin which will occur at the end
of the boot action.
.. include:: examples/test-jobs/mustang-admin-example-job.yaml
:code: yaml
:start-after: url: http://images-internal/mustang/mustang.dtb_1.11
:end-before: - test
Test
^^^^
Note how the test action can have a name and the test definition can also have
a name, separate from the content of the YAML file.
.. include:: examples/test-jobs/mustang-admin-example-job.yaml
:code: yaml
:start-after: username: root
Complete YAML submission
========================
.. include:: examples/test-jobs/mustang-admin-example-job.yaml
:code: yaml
Writing a device type template
******************************
The purpose of a template is to move as much common data out of each individual
template and into the base template for sharing of code. Where parameters
differ (e.g. the console port), these are supplied as variables. The device
dictionary then only needs to supply information which is specific to that one
device - usually including the serial connection command and the power
commands.
The first point of reference with a new template is the ``lava-server``
`base.jinja2
<https://gitlab.com/lava/lava/-/raw/master/etc/dispatcher-config/device-types/base.jinja2>`_
template and existing examples (e.g. `beaglebone-black
<https://gitlab.com/lava/lava/-/raw/master/etc/dispatcher-config/device-types/beaglebone-black.jinja2>`_)
- templates live on the server, are populated with data from the database and
the resulting YAML is sent to the dispatcher.
Starting a new device type template
===================================
For example, a new mustang template starts as::
{% extends 'base.jinja2' %}
{% block body %}
{% endblock %}
The content is a jinja2 template based directly on the working device jinja2
template above. Where there are values, these are provided with defaults
matching the currently working values. Where there are common blocks of code in
``base.jinja2``, these are pulled in using Jinja2 templates. The ``commands``
block itself is left to the device dictionary (and picked up by
``base.jinja2``).
``ramdisk`` and ``nfs`` are particularly common deployment methods, so the
majority of the commands are already available in ``base.jinja2``. These
commands use ``{{ console_device }}`` and ``{{ baud_rate }}``, which need to be
defined with defaults:
.. code-block:: jinja
{% set console_device = console_device | default('ttyS0') %}
{% set baud_rate = baud_rate | default(115200) %}
parameters:
bootm:
kernel: '{{ bootm_kernel_addr|default('0x4002000000') }}'
ramdisk: '{{ bootm_ramdisk_addr|default('0x4004000000') }}'
dtb: '{{ bootm_dtb_addr|default('0x4003000000') }}'
The actions are determined by the available support for this device, initially,
templates can simply support the initial working configuration, more support
can be added later.
.. code-block:: jinja
actions:
deploy:
methods:
tftp
boot:
prompts:
- 'linaro-test'
- 'root@debian:~#'
methods:
u-boot:
parameters:
bootloader_prompt: {{ bootloader_prompt|default('Mustang') }}
boot_message: {{ boot_message|default('Starting kernel') }}
nfs:
commands:
{{ base_uboot_commands }}
{{ base_uboot_addr_commands }}
{{ base_tftp_commands }}
# Always quote the entire string if the command includes a colon to support correct YAML.
- "setenv nfsargs 'setenv bootargs console={{ console_device }},{{ baud_rate }}n8 root=/dev/nfs rw {{ base_nfsroot_args }} panic=1 earlyprintk=uart8250-32bit,0x1c020000 debug ip=dhcp'"
{{ base_uboot_bootcmd }}
Completed mustang template
--------------------------
.. code-block:: jinja
{% extends 'base.jinja2' %}
{% block body %}
device_type: mustang
{% set console_device = console_device | default('ttyS0') %}
{% set baud_rate = baud_rate | default(115200) %}
parameters:
bootm:
kernel: '{{ bootm_kernel_addr|default('0x4002000000') }}'
ramdisk: '{{ bootm_ramdisk_addr|default('0x4004000000') }}'
dtb: '{{ bootm_dtb_addr|default('0x4003000000') }}'
actions:
deploy:
methods:
- tftp
boot:
prompts:
- 'linaro-test'
- 'root@debian:~#'
methods:
u-boot:
parameters:
bootloader_prompt: {{ bootloader_prompt|default('Mustang') }}
boot_message: {{ boot_message|default('Starting kernel') }}
nfs:
commands:
- setenv autoload no
{{ base_uboot_addr_commands }}
{{ base_tftp_commands }}
# Always quote the entire string if the command includes a colon to support correct YAML.
- "setenv nfsargs 'setenv bootargs console={{ console_device }},{{ baud_rate }}n8 root=/dev/nfs rw {{ base_nfsroot_args }} panic=1 earlyprintk=uart8250-32bit,0x1c020000 debug ip=dhcp'"
{{ base_uboot_bootcmd }}
{% endblock %}
Creating a device dictionary for the device
===========================================
Examples of exported device dictionaries exist in the ``lava-server`` `codebase
<https://gitlab.com/lava/lava/-/raw/master/tests/lava_scheduler_app/devices/bbb-01.jinja2>`_
for unit test support. The dictionary extends the new template and provides the
device-specific values.
.. code-block:: jinja
{% extends 'mustang.jinja2' %}
{% set connection_list = [‘uart0’] %}
{% set connection_commands = {‘uart0’: ‘telnet serial4 7012’} %}
{% set connection_tags = {‘uart0’: [‘primary’, 'telnet']} %}
{% set hard_reset_command = "/usr/bin/pduclient --daemon services --hostname pdu15 --command reboot --port 05" %}
{% set power_off_command = "/usr/bin/pduclient --daemon services --hostname pdu15 --command off --port 05" %}
{% set power_on_command = "/usr/bin/pduclient --daemon services --hostname pdu15 --command on --port 05" %}
.. _testing_templates_dictionaries:
Testing the template and dictionary
===================================
``lava-tool`` has support for comparing the templates with working YAML files
and this can be done using files already deployed or local changes prior to
submission. To test the local files, create a new directory, add the YAML file
used when calling ``lava-dispatch`` directly and add two sub-directories::
mkdir ./device-types
mkdir ./devices
Copy ``base.jinja2`` into the ``device-types`` directory, along with your new
local template. Copy the device dictionary file to ``devices``. If your locally
working jinja2 file is called ``working.jinja2``, the comparison would be::
$ lava-tool compare-device-conf --wdiff --dispatcher-config-dir . devices/mustang01.yaml working.jinja2
$ lava-tool compare-device-conf --dispatcher-config-dir . devices/mustang01.yaml working.jinja2
Iterate through the changes, testing any changes to the ``working.jinja2`` at
each stage, until you have no differences between the generated YAML and the
working jinja2.
Pay particular attention to whitespace and indentation which have a direct
impact on the structure of the object represented by the file. ``wdiff`` output
is very useful for identifying content changes and it is often necessary to
change the order of fields within a single command to get an appropriate match,
even if that order has no actual effect. By ensuring that the content does
match, it allows the comparison to show other changes like indents. Be prepared
to change both the ``working.jinja2`` and the template so that the indenting is
the same in each even after commands have been substituted.
.. note:: The snippets here are just examples. In particular, formatting these
examples for the documentation has changed some of the indents, so take
particular care to compare and fix the indents of your files and ensure that
your working YAML file continues to work as well as to match the output of
the template.
Adapting the base commands to the device type
---------------------------------------------
``base.jinja2`` for most devices uses the command
``base_uboot_commands`` which expands to::
- setenv autoload no
- setenv initrd_high '0xffffffff'
- setenv fdt_high '0xffffffff'
This command works well on 32-bit systems, on the mustang, it causes:
.. code-block:: yaml
- {target: ERROR: Failed to allocate 0xa38c bytes below 0xffffffff.}
- {target: Failed using fdt_high value for Device TreeFDT creation failed! hanging...### ERROR ### Please RESET the board ###}
So the mustang template simply omits ``base_uboot_commands``, using:
.. code-block:: yaml
- setenv autoload no
Completing the migration
************************
The device dictionary and the template need to be introduced into the
``lava-server`` configuration and database entries created for the device type
and device. Helpers may be implemented for this in due course but the process
involves:
#. Add a device type to lava_scheduler_app in the admin interface
#. Populate fields (you can omit health check for now - pipeline health checks
are not yet ready).
#. Add a device of the specified type to lava_scheduler_app in the admin
interface. Set the device as a pipeline device by checking the "Pipeline
Device" box.
#. Add the template to the ``lava-server`` configuration::
$ sudo cp device-types/mustang.jinja2 /etc/lava-server/dispatcher-config/device-types/
#. Import the device dictionary to provide the device-specific configuration::
$ sudo lava-server manage device-dictionary --hostname mustang1 --import mustang1.yaml
#. Review the generated YAML::
$ sudo lava-server manage device-dictionary --hostname mustang1 --review
#. Submit a test job against ``localhost`` and ensure it runs to completion::
$ lavacli jobs submit mustang-nfs.yaml
#. Offer the new template as a :ref:`code review <contribute_upstream>`
against ``lava-server``.
|