-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path_impl.tex
96 lines (83 loc) · 4.27 KB
/
_impl.tex
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
\FloatBarrier
\chapter{Implementation}
The following chapter describes the implementation of miq.
Miq is the program that was developed as a proof of concept
of the topics described in this document. As such, miq
(pronounced [miku]), is a package manager for Linux. It can
be categorized as a ``source-based'' package manager,
because the user would build every package from its sources
(for example, Gentoo's package manager |emerge| or |nix|),
as opposed to to a ``binary-based'' package manager, which
distributes the already-built packages to its users.
The model of a source-based package manager provides some
advantages, such as being able to edit the recipes that
build the packages. Moreover, by integrating the tool that
builds the packages and the tool that installs them, the
user gets a fast feedback loop to iterate over the writing
of the package definitions. In a source-based package
manager, the user receives a copy of a source tree that
contains the recipes, definitions of all the packages in the
repository. These files contain the instructions about all
the packages that are available, and the machine-readable
data for the package manager to build them. The user would
tell the package manager to build or install certain package
X, and the program would then:
\begin{itemize}
\item Evaluate the file tree of package definitions.
\item Calculate a transaction (which files to build or download)
\item Perform the transaction
\end{itemize}
Miq is heavily inspired by nix, the functional package
manager, a work of \Citeauthor{dolstraNixOS2008}
\cite{dolstraNixOS2008}. The work of nix of using a
hash-based path system instead of the \ac{FHS} was the idea
that lead this project, and that is implemented in miq by
following the same conventions that in nix. This means, that
packages are configured with a custom prefix that lives in
the \textbf{store} (|/miq/store| and |/nix/store| respectively), with
a unique subdirectory based on the hash of the package
definition -- which implies that any change in its
dependencies would trigger a recalculation of the store
path. Miq differs with nix in that the schema for the
calculation of the store path follows the pattern
|name-version-hash|, while nix uses |hash-name-version|.
While the result of the package is functionally the same, by
using the name first, the list of folders in |/miq/store|
can be easily ordered by package name.
Miq differs from nix in the usage of the language used for
the evaluation of the packages. On of the powerful features
of both miq and nix is the ability to declare packages as
code, using a Turing complete programming language. This is
in contrast to apt or rpm, which use a markup language to
define the packages. By using a Turing complete language,
the user is able to create any kind of abstraction around
the package primitives. This not only allows for code
deduplication, but also to easily create new ``helper''
packages that would otherwise not be considered with a
classical markup-language based package manager.
In this regard, for nix, a new programming language was
invented with the same name, nix. This is a purely
functional language inspired by the semantics of Haskell, and
often referred to as ``JSON with functions''. As this
language is sometimes alien to users, with miq the decision
was to use Lua, an easily embeddable language. This is
discussed in more depth in section \ref{sec:lua} .
Miq is implemented in the Rust programming language
\cite{RustProgrammingLanguage} . Rust is a relatively new
language created at Mozilla, which focuses on the ability to
build fast and reliable programs. This is achieved through
the use of rich type system, that guards the programmer from
making mistakes and eases the process of a refactor. Rust
also provides some other features that were viable to this
project. A very important detail is that Rust can build
native binaries (ELF) that can be run by the operating
system. Every dependency of the Rust program (crates) are
also built into the final binary, and C library requirements
(libc) are statically linked. This means that the final
result is a single |20MB| binary, with no dependencies that can be
run in any Linux system, no matter the distribution.
\input{_impl_unit.tex}
\input{_impl_dag.tex}
\input{_impl_lua.tex}
\input{_impl_builder.tex}
\input{_impl_db.tex}