LibreQoS/_readthedocs/html/CONTRIBUTING.html
2023-05-19 14:17:54 -06:00

337 lines
24 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html class="writer-html5" lang="en" >
<head>
<meta charset="utf-8" /><meta name="generator" content="Docutils 0.18.1: http://docutils.sourceforge.net/" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Contributing to LibreQoS &mdash; LibreQoE documentation</title>
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<link rel="stylesheet" href="_static/css/theme.css" type="text/css" />
<!--[if lt IE 9]>
<script src="_static/js/html5shiv.min.js"></script>
<![endif]-->
<script data-url_root="./" id="documentation_options" src="_static/documentation_options.js"></script>
<script src="_static/doctools.js"></script>
<script src="_static/sphinx_highlight.js"></script>
<script src="_static/js/theme.js"></script>
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
</head>
<body class="wy-body-for-nav">
<div class="wy-grid-for-nav">
<nav data-toggle="wy-nav-shift" class="wy-nav-side">
<div class="wy-side-scroll">
<div class="wy-side-nav-search" >
<a href="index.html" class="icon icon-home">
LibreQoE
</a>
<div role="search">
<form id="rtd-search-form" class="wy-form" action="search.html" method="get">
<input type="text" name="q" placeholder="Search docs" aria-label="Search docs" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div><div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="Navigation menu">
<p class="caption" role="heading"><span class="caption-text">Readme:</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="README.html">Sponsors</a></li>
<li class="toctree-l1"><a class="reference internal" href="README.html#support-libreqos">Support LibreQoS</a></li>
<li class="toctree-l1"><a class="reference internal" href="README.html#documentation">Documentation</a></li>
<li class="toctree-l1"><a class="reference internal" href="README.html#matrix-chat">Matrix Chat</a></li>
<li class="toctree-l1"><a class="reference internal" href="README.html#features">Features</a></li>
</ul>
<p class="caption" role="heading"><span class="caption-text">Read me first!</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="docs/Quickstart/networkdesignassumptions.html">Network Design Assumptions</a></li>
</ul>
<p class="caption" role="heading"><span class="caption-text">Change Notes:</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="docs/ChangeNotes/v1.4.html">LibreQoS v1.3.1 to v1.4 Change Summary</a></li>
</ul>
<p class="caption" role="heading"><span class="caption-text">Quickstart:</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="docs/SystemRequirements/Compute.html">System Requirements</a></li>
<li class="toctree-l1"><a class="reference internal" href="docs/SystemRequirements/Networking.html">Network Interface Requirements</a></li>
<li class="toctree-l1"><a class="reference internal" href="docs/Quickstart/quickstart-prereq.html">Server Setup - Pre-requisites</a></li>
<li class="toctree-l1"><a class="reference internal" href="docs/Quickstart/quickstart-libreqos-1.4.html">Install LibreQoS 1.4</a></li>
<li class="toctree-l1"><a class="reference internal" href="docs/Quickstart/share.html">Share your before and after</a></li>
</ul>
<p class="caption" role="heading"><span class="caption-text">Updates:</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="docs/Updates/update.html">Updating 1.4 To Latest Version</a></li>
</ul>
<p class="caption" role="heading"><span class="caption-text">Technical Documentation:</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="docs/TechnicalDocs/troubleshooting.html">Troubleshooting</a></li>
<li class="toctree-l1"><a class="reference internal" href="docs/TechnicalDocs/integrations.html">Integrations</a></li>
<li class="toctree-l1"><a class="reference internal" href="docs/TechnicalDocs/extras.html">Extras</a></li>
<li class="toctree-l1"><a class="reference internal" href="docs/TechnicalDocs/performance-tuning.html">Performance Tuning</a></li>
</ul>
<p class="caption" role="heading"><span class="caption-text">Legacy:</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="docs/Legacy/v1.3.1.html">LibreQoS v1.3.1</a></li>
</ul>
</div>
</div>
</nav>
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap"><nav class="wy-nav-top" aria-label="Mobile navigation menu" >
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
<a href="index.html">LibreQoE</a>
</nav>
<div class="wy-nav-content">
<div class="rst-content">
<div role="navigation" aria-label="Page navigation">
<ul class="wy-breadcrumbs">
<li><a href="index.html" class="icon icon-home" aria-label="Home"></a></li>
<li class="breadcrumb-item active">Contributing to LibreQoS</li>
<li class="wy-breadcrumbs-aside">
<a href="_sources/CONTRIBUTING.md.txt" rel="nofollow"> View page source</a>
</li>
</ul>
<hr/>
</div>
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
<div itemprop="articleBody">
<blockquote>
<div><p>This is <strong>draft 1</strong> of the contributing guide. Comments/edits appreciated.</p>
</div></blockquote>
<section id="contributing-to-libreqos">
<h1>Contributing to LibreQoS<a class="headerlink" href="#contributing-to-libreqos" title="Permalink to this heading"></a></h1>
<p>So your interested in contributing to LibreQoS! Awesome! Feel free to pitch in with whatever interests you, and well be happy to help.</p>
<p>Check out our <a class="reference external" href="https://github.com/LibreQoE/LibreQoS/blob/main/.github/CODE_OF_CONDUCT.md">Code of Conduct</a>, wed like to keep this a happy, constructive place. Also, please join the chat on <a class="reference external" href="https://app.element.io/#/room/#libreqos:matrix.org">Matrix</a>—the core developers hang out there, and will be happy to help you.</p>
<p>In particular:</p>
<ul class="simple">
<li><p>We can check that an issue isnt already being worked on. Theres nothing more frustrating than working hard on an issue only to discover that someone else already fixed it!</p></li>
<li><p>We can help point you at issues that might interest you.</p></li>
<li><p>We can offer help and/or mentoring with Rust and C.</p></li>
</ul>
</section>
<section id="how-you-can-help">
<h1>How You Can Help<a class="headerlink" href="#how-you-can-help" title="Permalink to this heading"></a></h1>
<p>Theres lots of ways you can help:</p>
<ul class="simple">
<li><p><strong>Battle-Testing LibreQos</strong>: use the software, let us know what does/doesnt work!</p></li>
<li><p><strong>Donate</strong>: its free software, but we appreciate your support.</p></li>
<li><p><strong>Let us Know Your Thoughts</strong>: Hop on the chat or our discussions page and let us know what youre thinking about.</p></li>
<li><p><strong>Finding Bugs</strong> - something doesnt work for you? We cant fix it if you dont tell us about it.</p></li>
<li><p><strong>Fixing Bugs</strong> and <strong>Adding Features</strong>: See the “Development Guide”, below.</p></li>
<li><p><strong>Teaching Others</strong>: if LibreQoS is working well for you, you can help others benefit by sharing your experience. See someone struggling? Feel free to pitch in and help them.</p></li>
</ul>
<p>LibreQos strive to create an open, friendly environment. If you have an idea for how to help, let us know.</p>
</section>
<section id="development-guidelines">
<h1>Development Guidelines<a class="headerlink" href="#development-guidelines" title="Permalink to this heading"></a></h1>
<p>This section contains some advice to help get you started writing code for LibreQoS.</p>
<section id="getting-oriented-with-libreqos">
<h2>Getting Oriented with LibreQoS<a class="headerlink" href="#getting-oriented-with-libreqos" title="Permalink to this heading"></a></h2>
<p>LibreQos is divided into several sections:</p>
<ul class="simple">
<li><p><strong>Rust: system management/control plane</strong></p>
<ul>
<li><p><strong>System Daemons</strong></p>
<ul>
<li><p><code class="docutils literal notranslate"><span class="pre">lqosd</span></code> is probably the most important part of the Rust system. It loads the eBPF system that provides bridging and traffic shaping control, runs the “bus” for other systems to communicate, and gathers information directly from the eBPF and kernel systems. It has several sub-crates:</p>
<ul>
<li><p><code class="docutils literal notranslate"><span class="pre">lqos_heimdall</span></code> handles all of the packet sniffing, flow tracking and <code class="docutils literal notranslate"><span class="pre">libcap</span></code> compatible packet data.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">lqos_queue_tracker</span></code> maintains statistics for Linux <code class="docutils literal notranslate"><span class="pre">tc</span></code> shaping queues, particularly Cake.</p></li>
</ul>
</li>
<li><p><code class="docutils literal notranslate"><span class="pre">lqos_node_manager</span></code> provides a per-node management web interface. It gathers most of its data from <code class="docutils literal notranslate"><span class="pre">lqosd</span></code> via the bus.</p></li>
</ul>
</li>
<li><p><strong>CLI Utilities</strong></p>
<ul>
<li><p><code class="docutils literal notranslate"><span class="pre">lqusers</span></code> provides a CLI interface for managing authentication to the node manager.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">lqtop</span></code> provides a quick and easy way to see what the shaper is doing from the local management console.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">xdp_iphash_to_cpu_cmdline</span></code> (the name is inherited from previous projects) provides a command-line interface to map IP subnets to TC and CPU handles.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">xdp_pping</span></code> provides a CLI tool to give a quick summary of TCP RTT times, grouped by TC handle.</p></li>
</ul>
</li>
<li><p><strong>Libraries</strong></p>
<ul>
<li><p><code class="docutils literal notranslate"><span class="pre">lqos_bus</span></code> provides a local-only (never leaving the shaper node) inter-process communication system. Its used by programs that need to ask <code class="docutils literal notranslate"><span class="pre">lqosd</span></code> to do something, or retrieve information from it.</p>
<ul>
<li><p>The <code class="docutils literal notranslate"><span class="pre">lqos_bus</span></code> crate also acts as a repository for shared data structures when data is passed between portions of the program.</p></li>
</ul>
</li>
<li><p><code class="docutils literal notranslate"><span class="pre">lqos_config</span></code> manages Rust integration with the <code class="docutils literal notranslate"><span class="pre">ispConfig.py</span></code> configuration file, and the <code class="docutils literal notranslate"><span class="pre">/etc/lqos.conf</span></code> file. It is designed as a helper for other systems to quickly access configuration parameters.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">lqos_python</span></code> compiles into a Python loadable library, providing a convenient interface to Rust code from the Python portions of the program.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">lqos_setup</span></code> provides a text-based initial setup system for users who install LibreQoS via <code class="docutils literal notranslate"><span class="pre">apt-get</span></code>.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">lqos_utils</span></code> provides a grab-bag of handy functions weve found useful elsewhere in the system.</p></li>
</ul>
</li>
</ul>
</li>
<li><p><strong>Python: system operation and integration</strong></p>
<ul>
<li><p><code class="docutils literal notranslate"><span class="pre">LibreQoS.py</span></code> maps all circuits to TC handles and gets the shaper system running.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">ispConfig.py</span></code> provides a system-wide configuration.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">integrationX.py</span></code> provide integrations with UISP, Spylnx and other CRM tools.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">lqTools.py</span></code> provides an interface for gathering statistics.</p></li>
</ul>
</li>
</ul>
</section>
<section id="what-we-re-building">
<h2>What Were Building<a class="headerlink" href="#what-we-re-building" title="Permalink to this heading"></a></h2>
<p>LibreQoS is a free/open source fair queueing system. Its designed for ISPs, but can be useful elsewhere. Primary goals:</p>
<ul class="simple">
<li><p>Provide fair-queueing to help maximize the use of the Internet resources you have.</p></li>
<li><p>Keep end-user latency low.</p></li>
<li><p>Dont alter user traffic (for example by lowering the quality of their streaming video).</p></li>
<li><p>Dont invade users privacy.</p></li>
<li><p>Provide excellent support tools to help keep your ISP running smoothly.</p></li>
</ul>
<p>Some secondary goals include:</p>
<ul class="simple">
<li><p>Visualize data to facilitate moving the state-of-the-art in fair queueing forwards.</p></li>
<li><p>Provide amazing throughput on inexpensive hardware.</p></li>
</ul>
</section>
<section id="making-changes-to-libreqos">
<h2>Making Changes to LibreQoS<a class="headerlink" href="#making-changes-to-libreqos" title="Permalink to this heading"></a></h2>
<p>We try to remain fast-moving and “process light”.</p>
<blockquote>
<div><p>When we use the word “agile”, we dont mean the heavily formalized process with scrums, kanban boards and similar. We mean lightweight, fast moving, and adhering to useful guides like “Code Complete” and “The Pragmatic Programmer”. Not getting bogged down in heavy process.</p>
</div></blockquote>
<section id="simple-changes">
<h3>Simple Changes<a class="headerlink" href="#simple-changes" title="Permalink to this heading"></a></h3>
<p>For a straightforward change, do the following:</p>
<ol class="arabic simple">
<li><p>Do one (or more!) of the following:</p>
<ul class="simple">
<li><p>Let us know on the chat that youre working on it.</p></li>
<li><p>Create an Issue in our GitHub repo.</p></li>
<li><p>Submit a PR, following the Branch Guidelines below.</p></li>
</ul>
</li>
<li><p>Other community members review and comment on your change in an informal manner.</p></li>
<li><p>Once consensus is reached, well merge to the <code class="docutils literal notranslate"><span class="pre">develop</span></code> branch (or a branch parented from <code class="docutils literal notranslate"><span class="pre">develop</span></code> if its a big change) and test it on our server resources at Equinix.</p></li>
<li><p>When ready, well merge it into the next release.</p></li>
</ol>
</section>
<section id="complex-changes">
<h3>Complex Changes<a class="headerlink" href="#complex-changes" title="Permalink to this heading"></a></h3>
<p>If you need/want a complicated change, please get in touch with us on the Matrix chat first. Wed like to avoid duplicating effort and wasting anyones time. Well be happy to offer advice and guidance. Then the process is similar:</p>
<ol class="arabic simple">
<li><p>Work on your local branch, parented off of <code class="docutils literal notranslate"><span class="pre">develop</span></code>.</p></li>
<li><p>Create a PR (targeting <code class="docutils literal notranslate"><span class="pre">develop</span></code>). If youd like interim feedback, create a “draft PR” and we can help test your branch before the PR finalizes.</p></li>
<li><p>Once your PR is ready, submit it.</p></li>
<li><p>The community will review/comment on your PR.</p></li>
<li><p>Once consensus is reached, well merge it into <code class="docutils literal notranslate"><span class="pre">develop</span></code>.</p></li>
<li><p>Once ready, <code class="docutils literal notranslate"><span class="pre">develop</span></code> will merge into <code class="docutils literal notranslate"><span class="pre">main</span></code>.</p></li>
</ol>
</section>
</section>
<section id="branch-guidelines">
<h2>Branch Guidelines<a class="headerlink" href="#branch-guidelines" title="Permalink to this heading"></a></h2>
<p>LibreQoS has adopted the following scheme for branches:</p>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">main</span></code> - released code (tagged at releases), safe to pull.</p>
<ul>
<li><p><code class="docutils literal notranslate"><span class="pre">develop</span></code> - Parented from <code class="docutils literal notranslate"><span class="pre">main</span></code> and rebased on release. Nothing gets directly comitted into <code class="docutils literal notranslate"><span class="pre">develop</span></code>, its the parent tree for ongoing development work.</p>
<ul>
<li><p><code class="docutils literal notranslate"><span class="pre">my_feature</span></code> - if youre working on a feature, your feature branch goes here - with <code class="docutils literal notranslate"><span class="pre">develop</span></code> as the parent. PRs—once the feature is ready for inclusion—should be targeted at <code class="docutils literal notranslate"><span class="pre">develop</span></code>.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">issue_xxx_name</span></code> - if youre working on a bugfix, work on it in a branch here. When the issue resolution is complete, PRs should be targeted at <code class="docutils literal notranslate"><span class="pre">develop</span></code>.</p></li>
</ul>
</li>
<li><p><code class="docutils literal notranslate"><span class="pre">hotfix_xxx</span></code> - If an emergency occurs and you have to push a fix to <code class="docutils literal notranslate"><span class="pre">main</span></code> in a hurry, hotfix branches can be parented from <code class="docutils literal notranslate"><span class="pre">main</span></code>. The resulting PR should target <code class="docutils literal notranslate"><span class="pre">main</span></code>. Let the developers know that they need to rebase <code class="docutils literal notranslate"><span class="pre">develop</span></code>.</p></li>
</ul>
</li>
</ul>
<p>The goal is for <code class="docutils literal notranslate"><span class="pre">main</span></code> to <em>always</em> be safe to clone and run, without surprises.</p>
</section>
<section id="code-guidelines">
<h2>Code Guidelines<a class="headerlink" href="#code-guidelines" title="Permalink to this heading"></a></h2>
<p>This is very much a work in progress.</p>
<section id="rust">
<h3>Rust<a class="headerlink" href="#rust" title="Permalink to this heading"></a></h3>
<section id="code-formatting">
<h4>Code Formatting<a class="headerlink" href="#code-formatting" title="Permalink to this heading"></a></h4>
<ul class="simple">
<li><p>Use <code class="docutils literal notranslate"><span class="pre">cargo</span> <span class="pre">fmt</span></code> to format your code. Weve got a customized format setup in place.</p></li>
<li><p>Adhere to standard Rust case and naming guidelines.</p></li>
</ul>
</section>
<section id="dependencies">
<h4>Dependencies<a class="headerlink" href="#dependencies" title="Permalink to this heading"></a></h4>
<ul class="simple">
<li><p>Check that you arent including any dependencies that incompatible with our license—GPL v2.</p></li>
<li><p>Look through the <code class="docutils literal notranslate"><span class="pre">Cargo.toml</span></code> files (or run <code class="docutils literal notranslate"><span class="pre">cargo</span> <span class="pre">tree</span></code>) and try to prefer using a dependency we use elsewhere.</p></li>
<li><p>Try to avoid using unmaintained crates.</p></li>
</ul>
</section>
<section id="naming">
<h4>Naming<a class="headerlink" href="#naming" title="Permalink to this heading"></a></h4>
<ul class="simple">
<li><p>Dont use short, incomprehensible names in any API or function accessible from outside. You dont save any RAM by naming your variable <code class="docutils literal notranslate"><span class="pre">sz</span></code> instead of <code class="docutils literal notranslate"><span class="pre">size</span></code>—you just make it harder for anyone reading the code.</p></li>
<li><p>Its fine to use <code class="docutils literal notranslate"><span class="pre">i</span></code> and similar for internal counting iterators. Try to use meaningful names for everything else.</p></li>
</ul>
</section>
<section id="code-style">
<h4>Code Style<a class="headerlink" href="#code-style" title="Permalink to this heading"></a></h4>
<ul class="simple">
<li><p>Prefer functional/iterative code to imperative. Sometimes you need a <code class="docutils literal notranslate"><span class="pre">for</span></code> loop, but if it can be replaced with an <code class="docutils literal notranslate"><span class="pre">iter</span></code>, <code class="docutils literal notranslate"><span class="pre">map</span></code> and <code class="docutils literal notranslate"><span class="pre">fold</span></code> it will both compile into faster code and be less error prone.</p></li>
<li><p>Its better to have lots of small functions than one big one. Rust is really good at inlining, and its much easier to understand short functions. Its also easier to test small functions.</p></li>
<li><p>If you have to override a Clippy warning, add a comment explaining why you did so.</p></li>
<li><p>Functions accessible from other crates should use the RustDoc standard for documentation.</p></li>
</ul>
</section>
<section id="unit-tests">
<h4>Unit Tests<a class="headerlink" href="#unit-tests" title="Permalink to this heading"></a></h4>
<ul class="simple">
<li><p>If you fix an issue, and its testable: add a unit test to check that we dont regress and suffer from that bug again.</p></li>
<li><p>If you create a type, write unit tests to test its constraints.</p></li>
</ul>
</section>
<section id="error-handling">
<h4>Error Handling<a class="headerlink" href="#error-handling" title="Permalink to this heading"></a></h4>
<ul class="simple">
<li><p>Use <code class="docutils literal notranslate"><span class="pre">thiserror</span></code> to emit readable error messages from your functions.</p></li>
<li><p>Its fine to use <code class="docutils literal notranslate"><span class="pre">?</span></code> and <code class="docutils literal notranslate"><span class="pre">anyhow</span></code> inside function chains; prefer <code class="docutils literal notranslate"><span class="pre">result.map_err</span></code> to transform your errors into your own errors whenever its possible that an error can be returned from a function accessible beyond the immediate crate.</p></li>
<li><p>Issue a <code class="docutils literal notranslate"><span class="pre">log::error!</span></code> or <code class="docutils literal notranslate"><span class="pre">log::warn!</span></code> messaage when an error occurs. Dont trust the callee to do it for you. Its better to have duplicate error messages than none at all.</p></li>
</ul>
</section>
</section>
</section>
</section>
</div>
</div>
<footer>
<hr/>
<div role="contentinfo">
<p>&#169; Copyright 2023, LibreQoE.</p>
</div>
Built with <a href="https://www.sphinx-doc.org/">Sphinx</a> using a
<a href="https://github.com/readthedocs/sphinx_rtd_theme">theme</a>
provided by <a href="https://readthedocs.org">Read the Docs</a>.
</footer>
</div>
</div>
</section>
</div>
<script>
jQuery(function () {
SphinxRtdTheme.Navigation.enable(true);
});
</script>
</body>
</html>