mirror of
https://github.com/mudler/luet.git
synced 2025-09-17 23:58:48 +00:00
Deploying to gh-pages from @ 5ee1ff6d5a
🚀
This commit is contained in:
@@ -27,12 +27,12 @@
|
||||
<meta property="og:type" content="article" />
|
||||
<meta property="og:url" content="https://luet.io/docs/concepts/overview/build_packages/" /><meta property="article:section" content="docs" />
|
||||
<meta property="article:published_time" content="2017-01-05T00:00:00+00:00" />
|
||||
<meta property="article:modified_time" content="2022-10-18T08:22:08+00:00" /><meta property="og:site_name" content="Luet" />
|
||||
<meta property="article:modified_time" content="2023-02-02T11:59:57+01:00" /><meta property="og:site_name" content="Luet" />
|
||||
|
||||
<meta itemprop="name" content="Building packages">
|
||||
<meta itemprop="description" content="How to build packages with Luet
|
||||
"><meta itemprop="datePublished" content="2017-01-05T00:00:00+00:00" />
|
||||
<meta itemprop="dateModified" content="2022-10-18T08:22:08+00:00" />
|
||||
<meta itemprop="dateModified" content="2023-02-02T11:59:57+01:00" />
|
||||
<meta itemprop="wordCount" content="1351">
|
||||
<meta itemprop="keywords" content="" /><meta name="twitter:card" content="summary"/>
|
||||
<meta name="twitter:title" content="Building packages"/>
|
||||
@@ -353,9 +353,9 @@ if (!doNotTrack) {
|
||||
<p><img src="/docs/tree.jpg" alt="Build packages"></p>
|
||||
<p>Luet provides an abstraction layer on top of the container image layer to make the package a first class construct. A package definition and all its dependencies are translated by Luet to Dockerfiles which can then be built anywhere that docker runs.</p>
|
||||
<p>To resolve the dependency tree Luet uses a SAT solver and no database. It is responsible for calculating the dependencies of a package and to prevent conflicts. The Luet core is still young, but it has a comprehensive test suite that we use to validate any future changes.</p>
|
||||
<p>Building a package with Luet requires only a <a href="/docs/docs/concepts/packages/specfile">definition</a>. This definition can be self-contained and be only composed of one <a href="/docs/docs/concepts/packages/specfile">specfile</a>, or a group of them, forming a Luet tree. For more complex use-cases, see <a href="/docs/docs/concepts/packages/collections">collections</a>. Luet also supports building packages from standard <code>Dockerfile</code> directly.</p>
|
||||
<p>Building a package with Luet requires only a <a href="/docs/concepts/packages/specfile">definition</a>. This definition can be self-contained and be only composed of one <a href="/docs/concepts/packages/specfile">specfile</a>, or a group of them, forming a Luet tree. For more complex use-cases, see <a href="/docs/concepts/packages/collections">collections</a>. Luet also supports building packages from standard <code>Dockerfile</code> directly.</p>
|
||||
<p>Run <code>luet build --help</code> to get more help for each parameter.</p>
|
||||
<p>Build accepts a list of packages to build, which syntax is in the <code>category/name-version</code> notation. See also <a href="/docs/docs/concepts/packages/specfile/#refering-to-packages-from-the-cli">specfile documentation page</a> to see how to express packages from the CLI.</p>
|
||||
<p>Build accepts a list of packages to build, which syntax is in the <code>category/name-version</code> notation. See also <a href="/docs/concepts/packages/specfile/#refering-to-packages-from-the-cli">specfile documentation page</a> to see how to express packages from the CLI.</p>
|
||||
<h2 id="reproducible-builds">Reproducible builds</h2>
|
||||
<p>Pinning a container build is not easy - there are always so many moving pieces, and sometimes just set <code>FROM</code> an image tag might not be enough.</p>
|
||||
<p>Luet while building a package generates intermediate images that are stored and can be optionally pushed in a registry. Those images can be re-used by Luet if building again the same tree to guarantuee highly reproducible builds.</p>
|
||||
@@ -381,7 +381,7 @@ $~/workdir> cat <span style="color:#4e9a06"><<EOF > curl/Dockerfile
|
||||
$~/workdir> luet build --all
|
||||
</code></pre></div><p>However, <code>luet</code> supports an extended syntax that allows to define packages with a more fine-grained control, templating support, and several other features that makes creation batch images much faster.</p>
|
||||
<h3 id="the-extended-syntax">The extended syntax</h3>
|
||||
<p>A <a href="/docs/docs/concepts/packages/specfile">package definition</a> is composed of a <code>build.yaml</code> and a sibiling <code>definition.yaml</code>.</p>
|
||||
<p>A <a href="/docs/concepts/packages/specfile">package definition</a> is composed of a <code>build.yaml</code> and a sibiling <code>definition.yaml</code>.</p>
|
||||
<p>In the following example, we are creating a dummy package (<code>bar/foo</code>). Which ships one file only, <code>/foo</code></p>
|
||||
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">$> <span style="color:#8f5902;font-style:italic"># put yourself in some workdir</span>
|
||||
|
||||
@@ -544,7 +544,7 @@ $~/workdir> cat <span style="color:#4e9a06"><<EOF > package3/definit
|
||||
|
||||
|
||||
<div class="text-muted mt-5 pt-3 border-top">
|
||||
Last modified October 18, 2022: <a href="https://github.com/mudler/luet/commit/2513760b00de6aebb0444e6a7221ac8967d62b6c">Tag 0.33.0 (2513760)</a>
|
||||
Last modified February 2, 2023: <a href="https://github.com/mudler/luet/commit/5ee1ff6d5aee5e5bb6d98382ff232b5d828afd36">:arrow_up: Bump to go 1.19 as requirement for building (#319) (5ee1ff6)</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@@ -586,7 +586,7 @@ $~/workdir> cat <span style="color:#4e9a06"><<EOF > package3/definit
|
||||
|
||||
</div>
|
||||
<div class="col-12 col-sm-4 text-center py-2 order-sm-2">
|
||||
<small class="text-white">© 2022 Ettore Di Giacinto All Rights Reserved</small>
|
||||
<small class="text-white">© 2023 Ettore Di Giacinto All Rights Reserved</small>
|
||||
<small class="ml-1"><a href="https://policies.google.com/privacy" target="_blank" rel="noopener">Privacy Policy</a></small>
|
||||
|
||||
<p class="mt-2"><a href="/about/">About Luet</a></p>
|
||||
|
@@ -27,12 +27,12 @@
|
||||
<meta property="og:type" content="article" />
|
||||
<meta property="og:url" content="https://luet.io/docs/concepts/overview/constraints/" /><meta property="article:section" content="docs" />
|
||||
|
||||
<meta property="article:modified_time" content="2022-10-18T08:22:08+00:00" /><meta property="og:site_name" content="Luet" />
|
||||
<meta property="article:modified_time" content="2023-02-02T11:59:57+01:00" /><meta property="og:site_name" content="Luet" />
|
||||
|
||||
<meta itemprop="name" content="CSP, SAT && RL">
|
||||
<meta itemprop="description" content="How Luet turns Image resolution into CSP
|
||||
">
|
||||
<meta itemprop="dateModified" content="2022-10-18T08:22:08+00:00" />
|
||||
<meta itemprop="dateModified" content="2023-02-02T11:59:57+01:00" />
|
||||
<meta itemprop="wordCount" content="241">
|
||||
<meta itemprop="keywords" content="" /><meta name="twitter:card" content="summary"/>
|
||||
<meta name="twitter:title" content="CSP, SAT && RL"/>
|
||||
@@ -318,7 +318,7 @@ if (!doNotTrack) {
|
||||
|
||||
</header>
|
||||
<p>Under the hood, Luet uses boolean satisfiability problem (<a href="https://en.wikipedia.org/wiki/Boolean_satisfiability_problem">SAT</a>) <a href="https://en.wikipedia.org/wiki/Reinforcement_learning">reinforcement learning</a> techniques to solve package constraints.</p>
|
||||
<p>Luet allows you to specify 3 types of set of contraints on a <a href="/docs/docs/concepts/packages/">package</a> definition:</p>
|
||||
<p>Luet allows you to specify 3 types of set of contraints on a <a href="/docs/concepts/packages/">package</a> definition:</p>
|
||||
<ul>
|
||||
<li>Requires</li>
|
||||
<li>Conflicts</li>
|
||||
@@ -326,7 +326,7 @@ if (!doNotTrack) {
|
||||
</ul>
|
||||
<p>The package definition in your tree definition, along with its Requires and Conflicts, are turned into Boolean formulas that are consumed by the solver to compute a solution. The solution represent the state of your system after a particular query is asked to the solver (Install, Uninstall, Upgrade).</p>
|
||||
<h2 id="requires-and-conflicts">Requires and Conflicts</h2>
|
||||
<p>A list of requires and conflicts, composed of one or more <a href="/docs/docs/concepts/packages/">packages</a>, becomes a SAT formula. The formula is then given to the SAT solver to compute a finite state set of packages which must be installed in the system in order to met the requirements.</p>
|
||||
<p>A list of requires and conflicts, composed of one or more <a href="/docs/concepts/packages/">packages</a>, becomes a SAT formula. The formula is then given to the SAT solver to compute a finite state set of packages which must be installed in the system in order to met the requirements.</p>
|
||||
<p>As Luet allows to express constraints with selectors ( e.g. <code>A depends on >=B-1.0</code>) it generates additional constraints to guarantee that at least one package and at most one is picked as dependency (<em>ALO</em> and <em>AMO</em>).</p>
|
||||
<h2 id="provides">Provides</h2>
|
||||
<p>Provides constraints are not encoded in a SAT formula. Instead, they are <code>expanded</code> into an in-place substitution of the packages that they have to be replaced with.
|
||||
@@ -403,7 +403,7 @@ They share the same SAT logic of expansion, allowing to swap entire version rang
|
||||
|
||||
|
||||
<div class="text-muted mt-5 pt-3 border-top">
|
||||
Last modified October 18, 2022: <a href="https://github.com/mudler/luet/commit/2513760b00de6aebb0444e6a7221ac8967d62b6c">Tag 0.33.0 (2513760)</a>
|
||||
Last modified February 2, 2023: <a href="https://github.com/mudler/luet/commit/5ee1ff6d5aee5e5bb6d98382ff232b5d828afd36">:arrow_up: Bump to go 1.19 as requirement for building (#319) (5ee1ff6)</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@@ -445,7 +445,7 @@ They share the same SAT logic of expansion, allowing to swap entire version rang
|
||||
|
||||
</div>
|
||||
<div class="col-12 col-sm-4 text-center py-2 order-sm-2">
|
||||
<small class="text-white">© 2022 Ettore Di Giacinto All Rights Reserved</small>
|
||||
<small class="text-white">© 2023 Ettore Di Giacinto All Rights Reserved</small>
|
||||
<small class="ml-1"><a href="https://policies.google.com/privacy" target="_blank" rel="noopener">Privacy Policy</a></small>
|
||||
|
||||
<p class="mt-2"><a href="/about/">About Luet</a></p>
|
||||
|
@@ -326,7 +326,7 @@ if (!doNotTrack) {
|
||||
<p>There is no known package manager with 0-dependency that fully leverages the container ecosystem. This gap forces current package managers to depend on a specific system layout as base of the building process and the corresponding depencies. This can cause situations leading to a broken system. We want to fix that by empowering the user, by building their own packages, and redistribute them.
|
||||
Luet allows also to create packages entirely from Docker images content. In this way the user can actually bundle all the files of an image into a package and deliver part of it, or entirely as a layer. All of that, without the package manager depending on a single bit from it.</p>
|
||||
<h2 id="package-definitions">Package definitions</h2>
|
||||
<p>Luet uses <a href="https://en.wikipedia.org/wiki/YAML">YAML</a> for the package specification format, Luet parses the <a href="/docs/docs/concepts/overview/constraints">requirements</a> to build <a href="/docs/docs/concepts/packages">packages</a>, so Luet can consume them.</p>
|
||||
<p>Luet uses <a href="https://en.wikipedia.org/wiki/YAML">YAML</a> for the package specification format, Luet parses the <a href="/docs/concepts/overview/constraints">requirements</a> to build <a href="/docs/concepts/packages">packages</a>, so Luet can consume them.</p>
|
||||
<p>Below you can find links to tutorials on how to build packages, images and repositories.</p>
|
||||
|
||||
<div class="section-index">
|
||||
@@ -440,7 +440,7 @@ Luet allows also to create packages entirely from Docker images content. In this
|
||||
|
||||
|
||||
<div class="text-muted mt-5 pt-3 border-top">
|
||||
Last modified October 18, 2022: <a href="https://github.com/mudler/luet/commit/2513760b00de6aebb0444e6a7221ac8967d62b6c">Tag 0.33.0 (2513760)</a>
|
||||
Last modified February 2, 2023: <a href="https://github.com/mudler/luet/commit/5ee1ff6d5aee5e5bb6d98382ff232b5d828afd36">:arrow_up: Bump to go 1.19 as requirement for building (#319) (5ee1ff6)</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@@ -481,7 +481,7 @@ Luet allows also to create packages entirely from Docker images content. In this
|
||||
|
||||
</div>
|
||||
<div class="col-12 col-sm-4 text-center py-2 order-sm-2">
|
||||
<small class="text-white">© 2022 Ettore Di Giacinto All Rights Reserved</small>
|
||||
<small class="text-white">© 2023 Ettore Di Giacinto All Rights Reserved</small>
|
||||
<small class="ml-1"><a href="https://policies.google.com/privacy" target="_blank" rel="noopener">Privacy Policy</a></small>
|
||||
|
||||
<p class="mt-2"><a href="/about/">About Luet</a></p>
|
||||
|
@@ -34,9 +34,9 @@
|
||||
<p><img src="https://luet.io/docs/tree.jpg" alt="Build packages"></p>
|
||||
<p>Luet provides an abstraction layer on top of the container image layer to make the package a first class construct. A package definition and all its dependencies are translated by Luet to Dockerfiles which can then be built anywhere that docker runs.</p>
|
||||
<p>To resolve the dependency tree Luet uses a SAT solver and no database. It is responsible for calculating the dependencies of a package and to prevent conflicts. The Luet core is still young, but it has a comprehensive test suite that we use to validate any future changes.</p>
|
||||
<p>Building a package with Luet requires only a <a href="https://luet.io/docs/docs/concepts/packages/specfile">definition</a>. This definition can be self-contained and be only composed of one <a href="https://luet.io/docs/docs/concepts/packages/specfile">specfile</a>, or a group of them, forming a Luet tree. For more complex use-cases, see <a href="https://luet.io/docs/docs/concepts/packages/collections">collections</a>. Luet also supports building packages from standard <code>Dockerfile</code> directly.</p>
|
||||
<p>Building a package with Luet requires only a <a href="https://luet.io/docs/concepts/packages/specfile">definition</a>. This definition can be self-contained and be only composed of one <a href="https://luet.io/docs/concepts/packages/specfile">specfile</a>, or a group of them, forming a Luet tree. For more complex use-cases, see <a href="https://luet.io/docs/concepts/packages/collections">collections</a>. Luet also supports building packages from standard <code>Dockerfile</code> directly.</p>
|
||||
<p>Run <code>luet build --help</code> to get more help for each parameter.</p>
|
||||
<p>Build accepts a list of packages to build, which syntax is in the <code>category/name-version</code> notation. See also <a href="https://luet.io/docs/docs/concepts/packages/specfile/#refering-to-packages-from-the-cli">specfile documentation page</a> to see how to express packages from the CLI.</p>
|
||||
<p>Build accepts a list of packages to build, which syntax is in the <code>category/name-version</code> notation. See also <a href="https://luet.io/docs/concepts/packages/specfile/#refering-to-packages-from-the-cli">specfile documentation page</a> to see how to express packages from the CLI.</p>
|
||||
<h2 id="reproducible-builds">Reproducible builds</h2>
|
||||
<p>Pinning a container build is not easy - there are always so many moving pieces, and sometimes just set <code>FROM</code> an image tag might not be enough.</p>
|
||||
<p>Luet while building a package generates intermediate images that are stored and can be optionally pushed in a registry. Those images can be re-used by Luet if building again the same tree to guarantuee highly reproducible builds.</p>
|
||||
@@ -62,7 +62,7 @@ $~/workdir&gt; cat <span style="color:#4e9a06">&lt;&lt
|
||||
$~/workdir&gt; luet build --all
|
||||
</code></pre></div><p>However, <code>luet</code> supports an extended syntax that allows to define packages with a more fine-grained control, templating support, and several other features that makes creation batch images much faster.</p>
|
||||
<h3 id="the-extended-syntax">The extended syntax</h3>
|
||||
<p>A <a href="https://luet.io/docs/docs/concepts/packages/specfile">package definition</a> is composed of a <code>build.yaml</code> and a sibiling <code>definition.yaml</code>.</p>
|
||||
<p>A <a href="https://luet.io/docs/concepts/packages/specfile">package definition</a> is composed of a <code>build.yaml</code> and a sibiling <code>definition.yaml</code>.</p>
|
||||
<p>In the following example, we are creating a dummy package (<code>bar/foo</code>). Which ships one file only, <code>/foo</code></p>
|
||||
<div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">$&gt; <span style="color:#8f5902;font-style:italic"># put yourself in some workdir</span>
|
||||
|
||||
@@ -379,7 +379,7 @@ $ luet search --table &lt;regex&gt;
|
||||
|
||||
|
||||
<p>Under the hood, Luet uses boolean satisfiability problem (<a href="https://en.wikipedia.org/wiki/Boolean_satisfiability_problem">SAT</a>) <a href="https://en.wikipedia.org/wiki/Reinforcement_learning">reinforcement learning</a> techniques to solve package constraints.</p>
|
||||
<p>Luet allows you to specify 3 types of set of contraints on a <a href="https://luet.io/docs/docs/concepts/packages/">package</a> definition:</p>
|
||||
<p>Luet allows you to specify 3 types of set of contraints on a <a href="https://luet.io/docs/concepts/packages/">package</a> definition:</p>
|
||||
<ul>
|
||||
<li>Requires</li>
|
||||
<li>Conflicts</li>
|
||||
@@ -387,7 +387,7 @@ $ luet search --table &lt;regex&gt;
|
||||
</ul>
|
||||
<p>The package definition in your tree definition, along with its Requires and Conflicts, are turned into Boolean formulas that are consumed by the solver to compute a solution. The solution represent the state of your system after a particular query is asked to the solver (Install, Uninstall, Upgrade).</p>
|
||||
<h2 id="requires-and-conflicts">Requires and Conflicts</h2>
|
||||
<p>A list of requires and conflicts, composed of one or more <a href="https://luet.io/docs/docs/concepts/packages/">packages</a>, becomes a SAT formula. The formula is then given to the SAT solver to compute a finite state set of packages which must be installed in the system in order to met the requirements.</p>
|
||||
<p>A list of requires and conflicts, composed of one or more <a href="https://luet.io/docs/concepts/packages/">packages</a>, becomes a SAT formula. The formula is then given to the SAT solver to compute a finite state set of packages which must be installed in the system in order to met the requirements.</p>
|
||||
<p>As Luet allows to express constraints with selectors ( e.g. <code>A depends on &gt;=B-1.0</code>) it generates additional constraints to guarantee that at least one package and at most one is picked as dependency (<em>ALO</em> and <em>AMO</em>).</p>
|
||||
<h2 id="provides">Provides</h2>
|
||||
<p>Provides constraints are not encoded in a SAT formula. Instead, they are <code>expanded</code> into an in-place substitution of the packages that they have to be replaced with.
|
||||
|
@@ -27,12 +27,12 @@
|
||||
<meta property="og:type" content="article" />
|
||||
<meta property="og:url" content="https://luet.io/docs/concepts/overview/repositories/" /><meta property="article:section" content="docs" />
|
||||
<meta property="article:published_time" content="2017-01-05T00:00:00+00:00" />
|
||||
<meta property="article:modified_time" content="2022-10-18T08:22:08+00:00" /><meta property="og:site_name" content="Luet" />
|
||||
<meta property="article:modified_time" content="2023-02-02T11:59:57+01:00" /><meta property="og:site_name" content="Luet" />
|
||||
|
||||
<meta itemprop="name" content="Creating Luet repositories">
|
||||
<meta itemprop="description" content="How to create Luet repositories
|
||||
"><meta itemprop="datePublished" content="2017-01-05T00:00:00+00:00" />
|
||||
<meta itemprop="dateModified" content="2022-10-18T08:22:08+00:00" />
|
||||
<meta itemprop="dateModified" content="2023-02-02T11:59:57+01:00" />
|
||||
<meta itemprop="wordCount" content="883">
|
||||
<meta itemprop="keywords" content="" /><meta name="twitter:card" content="summary"/>
|
||||
<meta name="twitter:title" content="Creating Luet repositories"/>
|
||||
@@ -507,7 +507,7 @@ foo-bar-0.1-builder.image.tar foo-bar-0.1.image.tar foo-bar-0.1.metadata.yaml
|
||||
|
||||
|
||||
<div class="text-muted mt-5 pt-3 border-top">
|
||||
Last modified October 18, 2022: <a href="https://github.com/mudler/luet/commit/2513760b00de6aebb0444e6a7221ac8967d62b6c">Tag 0.33.0 (2513760)</a>
|
||||
Last modified February 2, 2023: <a href="https://github.com/mudler/luet/commit/5ee1ff6d5aee5e5bb6d98382ff232b5d828afd36">:arrow_up: Bump to go 1.19 as requirement for building (#319) (5ee1ff6)</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@@ -549,7 +549,7 @@ foo-bar-0.1-builder.image.tar foo-bar-0.1.image.tar foo-bar-0.1.metadata.yaml
|
||||
|
||||
</div>
|
||||
<div class="col-12 col-sm-4 text-center py-2 order-sm-2">
|
||||
<small class="text-white">© 2022 Ettore Di Giacinto All Rights Reserved</small>
|
||||
<small class="text-white">© 2023 Ettore Di Giacinto All Rights Reserved</small>
|
||||
<small class="ml-1"><a href="https://policies.google.com/privacy" target="_blank" rel="noopener">Privacy Policy</a></small>
|
||||
|
||||
<p class="mt-2"><a href="/about/">About Luet</a></p>
|
||||
|
@@ -27,12 +27,12 @@
|
||||
<meta property="og:type" content="article" />
|
||||
<meta property="og:url" content="https://luet.io/docs/concepts/overview/usage/" /><meta property="article:section" content="docs" />
|
||||
<meta property="article:published_time" content="2019-12-14T00:00:00+00:00" />
|
||||
<meta property="article:modified_time" content="2022-10-18T08:22:08+00:00" /><meta property="og:site_name" content="Luet" />
|
||||
<meta property="article:modified_time" content="2023-02-02T11:59:57+01:00" /><meta property="og:site_name" content="Luet" />
|
||||
|
||||
<meta itemprop="name" content="CLI usage">
|
||||
<meta itemprop="description" content="How to install packages, manage repositories, ...
|
||||
"><meta itemprop="datePublished" content="2019-12-14T00:00:00+00:00" />
|
||||
<meta itemprop="dateModified" content="2022-10-18T08:22:08+00:00" />
|
||||
<meta itemprop="dateModified" content="2023-02-02T11:59:57+01:00" />
|
||||
<meta itemprop="wordCount" content="335">
|
||||
<meta itemprop="keywords" content="" /><meta name="twitter:card" content="summary"/>
|
||||
<meta name="twitter:title" content="CLI usage"/>
|
||||
@@ -462,7 +462,7 @@ $ luet search --table <regex>
|
||||
|
||||
|
||||
<div class="text-muted mt-5 pt-3 border-top">
|
||||
Last modified October 18, 2022: <a href="https://github.com/mudler/luet/commit/2513760b00de6aebb0444e6a7221ac8967d62b6c">Tag 0.33.0 (2513760)</a>
|
||||
Last modified February 2, 2023: <a href="https://github.com/mudler/luet/commit/5ee1ff6d5aee5e5bb6d98382ff232b5d828afd36">:arrow_up: Bump to go 1.19 as requirement for building (#319) (5ee1ff6)</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@@ -504,7 +504,7 @@ $ luet search --table <regex>
|
||||
|
||||
</div>
|
||||
<div class="col-12 col-sm-4 text-center py-2 order-sm-2">
|
||||
<small class="text-white">© 2022 Ettore Di Giacinto All Rights Reserved</small>
|
||||
<small class="text-white">© 2023 Ettore Di Giacinto All Rights Reserved</small>
|
||||
<small class="ml-1"><a href="https://policies.google.com/privacy" target="_blank" rel="noopener">Privacy Policy</a></small>
|
||||
|
||||
<p class="mt-2"><a href="/about/">About Luet</a></p>
|
||||
|
Reference in New Issue
Block a user