=====
 kw
=====

.. _manual:

-----------------------------------------
Inglorious kernel developer workflow tool
-----------------------------------------

:Author: Rodrigo Siqueira <rodrigosiqueiramelo@gmail.com>
:Author: Matheus Tavares <matheus.bernardino@usp.br>
:Date: 2018-05-18
:Copyright: GPLv2+
:Manual section: 1
:Manual group: Kernel Workflow

SYNOPSIS
========
*kw* *<command>* [<option> ...]

DESCRIPTION
===========
**kw** mission is: reduce the overhead related with infrastructure project
setup in projects that have a similar workflow to the Linux Kernel. It can (and
should) be customized by editing the **kworkflow.config** file, as discussed in
section `ABOUT kworflow.config`_.

COMMANDS
========
**kw** offers several subcommands catering to different audiences and targeting
different functionality groups. Most subcommands have sane defaults.

COMMANDS FOR DEPLOY NEW KERNEL IMAGE AND MODULE
-----------------------------------------------
When we develop for Linux Kernel, we continuously want to install or update the
current version of the Kernel image or modules, and these tasks may require
several steps to be accomplished. For this reason, **kw** provides a command
named **deploy** that attempts to handle all the complexity related to
the new Kernel installation. It is essential to highlight that we try to
support two different types of deploy: *local* and *remote*. When you
want to update your host machine, you can use the *local* option.  Also, we
provide the *remote* option, which is much more flexible since it uses network;
notice that this approach is the most generic one because you can use it for
*vm* and *local*.

  :ref:`kw-deploy<deploy-doc>`

COMMANDS FOR WORKING WITH CODE
------------------------------
Projects that have a similar workflow to the Linux Kernel usually have a set of
tools that simplify part of the tasks related with the code. This section
describes some of the key features supported by **kw** to help with code.

  | :ref:`kw-build<build-doc>`
  | :ref:`kw-codestyle<codestyle-doc>`
  | :ref:`kw-explore<explore-doc>`
  | :ref:`kw-maintainers<maintainers-doc>`

SUBSYSTEM COMMANDS
------------------
Linux kernel has multiple subsystems that expose operations via sysfs or
provide mechanisms for userspace to interact with the driver. For this reason,
kw offers some options that target some specific subsystems for providing
facilities for users to interact with a particular subsystem. Currently, we
only support drm.

  :ref:`kw-drm<drm-doc>`

COMMAND TO DEBUG THE LINUX KERNEL
---------------------------------

Linux kernel provides multiple mechanisms for debugging; in particular, kw
tries to simplify the debug process for three of them: events, ftrace, and
dmesg. All the debug options are intended to support remote and local targets.

  :ref:`kw-debug<debug-doc>`

OTHER COMMANDS
--------------
This section describes a tool available in **kw** to help developers keep track
of configuration files and other features provided by **kw** that do not fit in
the previous sections.

  | :ref:`kw-backup<backup-doc>`
  | :ref:`kw-init<init-doc>`
  | :ref:`kw-device<device-doc>`
  | :ref:`kw-ssh<ssh-doc>`
  | :ref:`kw-kernel-config-manager<kernel-config-manager-doc>`
  | :ref:`kw-vars<vars-doc>`
  | :ref:`kw-diff<diff-doc>`
  | :ref:`kw-report<report-doc>`
  | :ref:`kw-pomodoro<pomodoro-doc>`
  | :ref:`kw-mail<mail-doc>`
  | :ref:`kw-self-update<self-update-doc>`

clear-cache
~~~~~~~~~~~
Clean all files generated by kw.

h, help
~~~~~~~
Show basic help.

version, \--version, -v
~~~~~~~~~~~~~~~~~~~~~~~
Show kworkflow version.

ABOUT kworflow.config
=====================
.. _`ABOUT kworkflow.config`:

**kw** reads its configuration from two files: the global
*<path>/etc/kworkflow.config* file and the local **kworkflow.config** file
present at the current working directory. The global **kworkflow.config** is a
part of the **kw** code and provides the overall behavior for **kw**. Local
**kworkflow.config** settings override global ones; you may have one
**kworkflow.config** per project. In this section, we describe the possible
fields you can specify in the configuration files.

ssh_user=<user>
---------------
Sets the user to be used by ssh. By default **kw** uses ``root``.

ssh_ip=<ip>
-----------
Sets the IP address to be used by ssh. By default **kw** uses ``localhost``.

ssh_port=<port>
---------------
Sets the ssh port. By default **kw** uses ``2222``.

ssh_configfile=<ssh-config-file>
--------------------------------
Provides an optional SSH configuration file to be used by ssh. For more details
see ``man ssh_config``.

hostname=<hostname>
-------------------
Sets the hostname to be used when an SSH configuration file is provided.

arch=<architecture>
-------------------
Allows you to specify the default architecture used by **kw**. By default,
**kw** uses ``x86_64``.

kernel_img_name=<kernel-image-name>
-----------------------------------
Use this option as a way to indicate to kw the kernel image name. This is the
file present in the directory ``arch/*/boot/``; keep in mind that the kernel
image name might change based on the user config file or target architecture.

cross_compile=<cross-compile-toolchain-name>
--------------------------------------------
Kw supports cross compile setup, use this option to indicate the target
toolchain.

menu_config=<menu-option>
-------------------------
Default kernel menu used by **kw**, the default is ``nconfig``.

alert=[vs | s | v | n]
----------------------
Default alert options, you have:

1. v: enables visual notification.

2. s: enables sound notification.

3. vs or sv: enables both.

4. n (or any other option): disables notifications.

sound_alert_command=<command>
-----------------------------
Command to run for sound completion alert. By default, **kw** uses
``paplay INSTALLPATH/sounds/complete.wav &``

visual_alert_command=<command>
------------------------------
Command to run for visual completion alert. By default, **kw** uses
``notify-send -i checkbox -t 10000 "kw" "Command: \\"$COMMAND\\" completed!"``

.. note::
  You may use the *COMMAND* variable, which will be replaced by the kw command
  whose conclusion the user wished to be alerted of.

default_deploy_target
---------------------
By default, **kw** deploys in the *remote*; however, you can change this
behavior with this variable. The available options are: *local* and *remote*.

reboot_remote_by_default
------------------------
Reboot machine after the deploy finishes.

gui_on=<command>
----------------
This option is disabled by default, if enabled, it requires a command that
instructs kw to turn on the GUI.

gui_off=<command>
-----------------
This option is disabled by default, if enabled, it requires a command that
instructs kw to turn off the GUI.

EXAMPLES
========
For these examples, we suppose the fields in your **kworkflow.config** file is
already configured.

First, if you are working in a specific kernel module, and if you want to
install your recent changes in your local machine you can use::

  cd <kernel-path>
  kw d --local --modules

For building and installing a new module version based on the current kernel
version, you can use::

  cd <kernel-path>
  kw bd

For checking the code style::

  cd <kernel-path>
  kw c drivers/iio/dummy/
  kw c drivers/iio/dummy/iio_simple_dummy.c

If you want to check the maintainers::

  cd <kernel-path>
  kw m drivers/iio/dummy/iio_simple_dummy.c

In case you want that kw saves your current .config file, you can use::

    cd <kernel-path>
    kw k --save my_current_config

You can see the config's file maintained by kw with::

  kw k --list

You can turn on your VM with::

  kw u

After you start your VM you can ssh into it with::

  kw s -c="dmesg -wH"
  kw s

You can see data related to your kw usage by using the ``--statistics`` flag on
the report option, see some examples below::

  kw report --statistics --day
  kw report --statistics --week
  kw report --statistics --month
  kw report --statistics --year

You can also request a specific day, week, month, or year. For example::

  kw report --statistics --day=2020/05/12
  kw report --statistics --week=2020/02/29
  kw report --statistics --month=2020/04
  kw report --statistics --year=1984

If you are working with DRM drivers, you can take advantage of load and unload
commands combined with GUI control commands. For example::

  kw drm --load-module='amdgpu' --gui-on # Load a driver and trigger the user GUI
  kw drm --unload-module='amdgpu' # Turn off user GUI and unload the driver

If you need to debug an issue based on event values, you can try the debug
options. For example::

  kw debug --list # Show all events debug available in the target
  kw debug --list --event="amdgpu_dm" # Show all events available under amdgpu_dm
  kw debug --event='amdgpu_dm:amdgpu_dm_dce_clocks_state[sclk_khz > 0]' # Enable amdgpu_dm_dce_clocks_state event and filter by sclk_khz > 0
  kw debug --disable --event='amdgpu_dm:amdgpu_dm_dce_clocks_state' # Disable amdgpu_dm_dce_clocks_state events
  kw debug --event='amdgpu_dm:amdgpu_dm_dce_clocks_state' --history # Save each debug in a separated set of files
  kw debug --event='amdgpu_dm:amdgpu_dm_dce_clocks_state' --follow # Wait for new event message
  kw debug --event='amdgpu_dm:amdgpu_dm_dce_clocks_state' --cmd="export DISPLAY=:0.0 && xrandr --props" # Enable amdgpu_dm_dce_clocks_state, run "export DISPLAY=:0.0 && xrandr --props", collect logs, and disable events

.. note::
   You have to wait for the sshd to become ready.
