tebako 0.9.3 → 0.10.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.adoc CHANGED
@@ -1,1186 +1,1189 @@
1
- = Tebako: An advanced image packager for interpretive languages
2
-
3
- Platform tests on GitHub:
4
- image:https://github.com/tamatebako/tebako/actions/workflows/ubuntu.yml/badge.svg["Ubuntu amd64", link="https://github.com/tamatebako/tebako/actions/workflows/ubuntu.yml"]
5
- image:https://github.com/tamatebako/tebako/actions/workflows/alpine.yml/badge.svg["Alpine", link="https://github.com/tamatebako/tebako/actions/workflows/alpine.yml"]
6
- image:https://github.com/tamatebako/tebako/actions/workflows/macos.yml/badge.svg["macOS amd64", link="https://github.com/tamatebako/tebako/actions/workflows/macos.yml"]
7
- image:https://github.com/tamatebako/tebako/actions/workflows/windows-msys.yml/badge.svg["Windows msys", link="https://github.com/tamatebako/tebako/actions/workflows/windows-msys.yml"]
8
-
9
- Platform tests on Cirrus:
10
- image:https://api.cirrus-ci.com/github/tamatebako/tebako.svg?branch=main&task=ubuntu-aarch64["Ubuntu aarch64", link="https://cirrus-ci.com/github/tamatebako/tebako"]
11
-
12
- Tools tests on GitHub:
13
- image:https://github.com/tamatebako/tebako-ci-containers/actions/workflows/build-containers.yml/badge.svg["Tebako cobtainers", link="https://github.com/tamatebako/tebako-ci-containers/actions/workflows/build-containers.yml"]
14
-
15
- Quality:
16
- image:https://github.com/tamatebako/tebako/actions/workflows/lint-and-rspec.yml/badge.svg["lint and rspec", link="https://github.com/tamatebako/tebako/actions/workflows/lint-and-rspec.yml"]
17
- image:https://codecov.io/gh/tamatebako/tebako/graph/badge.svg?token=XD3emQ5qsY["Tebako cli rspec coverage", link="https://codecov.io/gh/tamatebako/tebako"]
18
-
19
- == Purpose
20
-
21
- Tebako is an advanced executable packager designed for applications written in
22
- interpretive languages.
23
-
24
- It simplifies distribution and deployment by packaging your entire project with
25
- a bundled runtime into a single, performant, executable binary.
26
-
27
- == Architecture
28
-
29
- A Tebako-packaged binary is effectively a self-executing container-in-a-file.
30
-
31
- The packaged binary contains the following components:
32
-
33
- * An on-file filesystem (OFFS) containing all the project files and
34
- dependencies in DwarFS format.
35
-
36
- * A runtime environment that includes the necessary libraries and interpreters,
37
- with patched filesystem calls that redirect access of project files to the
38
- on-file filesystem.
39
-
40
- * An executable loader that loads the on-file filesystem in memory and executes
41
- the project.
42
-
43
-
44
- == Supported runtimes, platforms and architectures
45
-
46
- Tebako artifacts can be built and executed on the following platforms and
47
- architectures.
48
-
49
- .Supported platforms and architectures
50
- [cols="3", options="header"]
51
- |===
52
- | Platform and version | Architectures | Build system
53
-
54
- 3+| **Linux**
55
- | Ubuntu 20.04 | amd64, aarch64 | gcc/g+\+: 10; clang/clang++: 12
56
- | Alpine 3.17 | amd64 | gcc/g+\+: default; clang/clang++: default
57
-
58
- 3+| **macOS**
59
- | macOS 13 (Ventura) | amd64, arm64 | tested agains xcode: [14.3.1]
60
- | macOS 14 (Sonoma) | amd64, arm64 | tested agains xcode: [15.0.1, 15.4]
61
- | macOS 15 (Sequoia) | amd64, arm64 | tested agains xcode: [16.1]
62
-
63
- 3+| **Windows**
64
- | Windows 10 | amd64 | MinGW ucrt64
65
- | Windows 11 | amd64 | MinGW ucrt64
66
- | Windows Server 2019 | amd64 | MinGW ucrt64
67
- | Windows Server 2022 | amd64 | MinGW ucrt64
68
-
69
- |===
70
-
71
- [NOTE]
72
- ====
73
- Windows build caveats:
74
-
75
- * Tebako may face errors related to CMake path length limitations (https://gitlab.kitware.com/cmake/cmake/-/issues/25936).
76
- This error may affect not tebako itself but the gems that need to be package and use CMake to build native extensions.
77
- There is no workaround for this issue as it looks like is a limitation of the manifest used to build CMake executable.
78
-
79
- * MSys strip utility creates broken executable when tebako image is processed. Linking with '-s' flag produces unusable
80
- executables as well.
81
- Until this issue (https://github.com/tamatebako/tebako/issues/172) is resolved we plan to produce an Windows executable
82
- with debug information unstripped. You can opt to run 'strip -S' manually, it most cases it works.
83
- ====
84
-
85
-
86
- .Supported Ruby versions
87
- [cols="2", options="header"]
88
- |===
89
- | Ruby version | Supported platforms
90
-
91
- | 2.7.8 | Linux, macOS
92
- | 3.0.7 | Linux, macOS
93
- | 3.1.6 | Linux, macOS, Windows
94
- | 3.2.{4,5} | Linux, macOS, Windows
95
- | 3.3.{3,4,5} | Linux, macOS, Windows
96
-
97
- |===
98
-
99
- NOTE: Our goal is to support all maintained Ruby releases, including minor versions.
100
-
101
-
102
- == Package portability
103
-
104
- === General
105
-
106
- Tebako packages are designed to be "forward portable" across different operating
107
- systems and architectures to allow for easy distribution and deployment.
108
-
109
- Forward portability means that a package created on a specific platform can be
110
- executed on a newer version of the same platform.
111
-
112
- === macOS
113
-
114
- macOS packages are forward portable across different macOS versions.
115
-
116
- [example]
117
- A Tebako executable package built on macOS 12 (Monterey) can be executed on
118
- macOS 14 (Sonoma), but not vice versa.
119
-
120
- `x86_64` macOS packages can be run on Apple M (ARM) systems.
121
-
122
-
123
- === Linux distributions using `musl`
124
-
125
- Packages built for the
126
- https://musl.libc.org[`musl` implementation of the C standard library]
127
- (such as https://alpinelinux.org[Alpine Linux]) are forward portable.
128
-
129
- [example]
130
- A Tebako executable package built on Alpine 3.17 can be executed on Alpine 3.19.
131
-
132
- Usage of the
133
- https://github.com/tamatebako/tebako-ci-containers[Tebako Docker containers] for
134
- packaging is encouraged since it eliminates the effort needed for toolchain
135
- setup and configuration.
136
-
137
-
138
- === Linux distributions using `glibc`
139
-
140
- Packages built for the
141
- https://sourceware.org/glibc[`glibc` implementation of the C standard library]
142
- are forward portable if the `--patchelf` experimental option is enabled.
143
-
144
- The `--patchelf` option allows these packages to be portable to Linux GNU
145
- distributions with GLIBC version 2.31 and above.
146
-
147
- [example]
148
- A Tebako executable package built on Ubuntu 20.04 with `--patchelf` option can
149
- be executed on Rocky Linux 9.
150
-
151
- Usage of the
152
- https://github.com/tamatebako/tebako-ci-containers[Tebako Docker containers] for
153
- packaging is encouraged since it eliminates the effort needed for toolchain
154
- setup and configuration.
155
-
156
-
157
- .Minimum versions of GLIBC Linux distributions that support Tebako packages with forward portability
158
- [cols="3", options="header"]
159
- |===
160
- | Distribution | Minimal supported version | GLIBC version
161
-
162
- | Ubuntu | 20.04 (Focal Fossa) | GLIBC 2.31
163
- | Debian | 11 (Bullseye) | GLIBC 2.31
164
- | Rocky Linux | 9 | GLIBC 2.34
165
- | Fedora | 33 | GLIBC 2.32
166
- | CentOS | 9 | GLIBC 2.34
167
- | Red Hat Enterprise Linux (RHEL) | 9 | GLIBC 2.34
168
- | Oracle Linux | 9 | GLIBC 2.34
169
-
170
- |===
171
-
172
-
173
- == Future plans
174
-
175
- * Downloading new DwarFS images to be stored in the local home directory
176
- * Allowing loading multiple DwarFS images in a stacked way
177
- * Supporting a COW mechanism that the newly written files are stored
178
- in a separate image that can be loaded on top of the read-only file systems.
179
-
180
- == FAQ
181
-
182
- === Why use Tebako?
183
-
184
- Tebako is particularly useful for developers who need to:
185
-
186
- * Distribute applications without requiring users to have specific runtimes installed.
187
- * Simplify the deployment process by packaging all dependencies into one binary.
188
- * Ensure consistency across different environments by using a single executable.
189
- * Flexibility to support different runtime versions on the user's machine.
190
-
191
-
192
- === How do I know I need Tebako?
193
-
194
- You might need Tebako if you:
195
-
196
- * Want to package your application into a single, self-contained binary.
197
- * Want to avoid the complexities of managing runtime environments on target machines.
198
- * Distribute software to environments where installing runtimes and their dependencies is challenging.
199
- * Require a streamlined way to deliver applications to end-users.
200
- * Need to ensure that your application runs consistently across different environments and architectures.
201
-
202
-
203
- === What is DwarFS?
204
-
205
- https://github.com/mhx/dwarfs[DwarFS] is a fast, high compression read-only
206
- user-land file system designed for efficient storage and access of large
207
- collections of files.
208
-
209
- It is used by Tebako to package applications into a compact and efficient format.
210
-
211
- Tebako uses https://github.com/tamatebako/libdwarfs[libdwarfs], the library
212
- form of https://github.com/mhx/dwarfs[DwarFS], developed for the Tebako project.
213
-
214
- === When is Tebako better than comparable solutions?
215
-
216
- Tebako offers several advantages over comparable solutions for supported
217
- interpretive languages.
218
-
219
- They are listed in order of the degree of virtualization below.
220
-
221
- Tebako stands out by providing a lightweight runtime bundling approach that
222
- simplifies distribution and deployment while offering flexibility and
223
- efficiency.
224
-
225
- It eliminates the need for users to have specific runtimes installed and ensures
226
- consistency across different environments.
227
-
228
- With Tebako, you can package your entire project with a bundled runtime into a
229
- single, performant, executable binary.
230
-
231
- [cols="a,3a,3a"]
232
- |===
233
- | Solution | Pros | Cons
234
-
235
- | Virtual machines (VMs)
236
- |
237
- - Provides full isolation and compatibility across environments
238
- |
239
- - Requires a separate VM installation for each application
240
- - Heavy resource consumption for virtualization
241
-
242
- | Docker
243
- |
244
- - Provides portable containers
245
- - Isolates entire applications and their dependencies
246
- - Supports easy deployment and scalability
247
- |
248
- - Requires Docker installation and management
249
- - Requires administrative rights on machine
250
- - Containerization overhead
251
-
252
- | *Tebako*
253
- |
254
- - Packages all files and dependencies into a single binary
255
- - Supports multiple operating systems and architectures
256
- - Provides efficient packaging and execution with DwarFS
257
- - Offers security features like signing on macOS
258
- - Simplifies distribution and deployment
259
- - Native running speed
260
- |
261
- - Initial packaging time longer than Ruby gems
262
- - Minor runtime overhead
263
-
264
- | Ruby Gems
265
- |
266
- - Easy installation of Ruby libraries
267
- - Provides user-side version control and dependency management
268
- |
269
- - Requires Ruby installation and gem management
270
- - Runtime execution dependent on the user's installed Ruby version and gems
271
-
272
- |===
273
-
274
-
275
- == Usage
276
-
277
- === Command-line interface
278
-
279
- Tebako works by packaging your project into a single executable binary that
280
- includes all the necessary dependencies.
281
-
282
- The way to work with Tebako is through its command-line interface (CLI).
283
- It provides the following commands:
284
-
285
- `setup`::
286
- Prepares the Tebako packaging environment.
287
-
288
- `press`::
289
- Packages a project into a single executable binary.
290
-
291
- `clean`::
292
- Removes Tebako artifacts.
293
-
294
- `clean_ruby`::
295
- Removes Tebako Ruby artifacts.
296
-
297
- `hash`::
298
- Calculates the Tebako script hash for use as a cache key in CI/CD environments.
299
-
300
- `extract`::
301
- Extracts the filesystem from a Tebako package.
302
-
303
- `version`::
304
- Displays the Tebako version.
305
-
306
- `help`::
307
- Displays the help message.
308
-
309
-
310
- == Usage
311
-
312
- === General
313
-
314
- Tebako can be used in two ways:
315
-
316
- * Through the Tebako container
317
- * Local installation
318
-
319
- Please refer to the <<installation>> section on how to install Tebako.
320
-
321
-
322
- [[installation]]
323
- == Installation
324
-
325
- === General
326
-
327
- Installation of Tebako is only needed in order to package an application.
328
-
329
- There is no need to install anything for users who run the packaged application.
330
-
331
-
332
- === Using Docker
333
-
334
- ==== General
335
-
336
- If you have Docker installed and available, the easiest way to run Tebako is
337
- through the official Docker containers.
338
-
339
- Docker containers with preinstalled Tebako packaging environments for Ubuntu and
340
- Alpine Linux are available at
341
- https://github.com/tamatebako/tebako-ci-containers[tebako-ci-containers].
342
-
343
-
344
- ==== Pull the container
345
-
346
- Pull the Tebako container image.
347
-
348
- [source,sh]
349
- ----
350
- docker pull ghcr.io/tamatebako/tebako-<container_tag>:latest
351
- ----
352
-
353
- `<container_tag>`:: is the desired image tag (e.g., `ubuntu-20.04` or `alpine-3.17`).
354
-
355
-
356
- ==== Running Tebako commands in the container
357
-
358
- Simply prefix the Tebako command with `docker run` and the container image.
359
-
360
- [source,sh]
361
- ----
362
- docker run -v <application_folder>:/mnt/w \
363
- -t ghcr.io/tamatebako/tebako-<container_tag>:latest \
364
- tebako {command} {parameters}
365
- ----
366
-
367
- ==== Packaging from outside the container
368
-
369
- To package your application from outside the container, just run a single Docker
370
- command.
371
-
372
- This command mounts the application folder into the container and runs the
373
- `tebako press` command, specifying the application root, entry point, output
374
- location, and Ruby version.
375
-
376
- [source,sh]
377
- ----
378
- docker run -v <application_folder>:/mnt/w \
379
- -t ghcr.io/tamatebako/tebako-<container_tag>:latest \
380
- tebako press <tebako-press-parameters>
381
- ----
382
-
383
- `<application_folder>`:: is the path to your application folder.
384
-
385
- `<container_tag>`:: is the desired image tag (e.g., `ubuntu-20.04` or `alpine-3.17`).
386
-
387
-
388
- [example]
389
- ====
390
- Assume that you have a Ruby application in the `fontist` folder of the current
391
- directory.
392
-
393
- You can package it to `./fontist-package` using the following command:
394
-
395
- [source,sh]
396
- ----
397
- docker run -v $PWD:/mnt/w \
398
- -t ghcr.io/tamatebako/tebako-ubuntu-20.04:latest \
399
- tebako press --root=/mnt/w/fontist --entry-point=fontist --output=/mnt/w/fontist-package --Ruby=3.2.4
400
- ----
401
- ====
402
-
403
- ==== Packaging from inside the container
404
-
405
- It is also possible to package an application from inside the Tebako container.
406
-
407
- Start and enter the container interactively.
408
-
409
- [source,sh]
410
- ----
411
- docker run -it --rm -v <application_folder>:/mnt/w \
412
- ghcr.io/tamatebako/tebako-<container_tag>:latest bash
413
- ----
414
-
415
- `<application_folder>`:: is the path to your application folder.
416
-
417
- `<container_tag>`:: is the desired image tag (e.g., `ubuntu-20.04` or `alpine-3.17`).
418
-
419
-
420
- Once inside, run the `tebako press` command:
421
-
422
- [source,sh]
423
- ----
424
- tebako press <tebako press parameters>
425
- ----
426
-
427
- [example]
428
- ====
429
- Assume that you have a Ruby application in the `fontist` folder of the current
430
- directory.
431
-
432
- You can package it to `./fontist-package` using the following command:
433
-
434
- [source,sh]
435
- ----
436
- $ docker run -it --rm -v $PWD:/mnt/w ghcr.io/tamatebako/tebako-<container_tag>:latest bash
437
-
438
- # Inside the container:
439
- $ tebako press --root=/mnt/w/fontist --entry-point=fontist --output=/mnt/w/fontist-package --Ruby=3.2.4
440
- ----
441
- ====
442
-
443
-
444
- === Local installation
445
-
446
- ==== General
447
-
448
- There are cases where Docker may not be suitable for your needs, such as:
449
-
450
- . Admin privileges: Running Docker requires administrative privileges, which
451
- means Docker may not be available to users on their machines.
452
-
453
- . Performance penalty: Docker introduces a performance penalty due to the
454
- overhead of running containers. This can be a concern when packaging complex
455
- applications that require heavy memory usage.
456
-
457
- In such cases, you can choose to install Tebako locally.
458
-
459
- Tebako is distributed as a Ruby gem. A Ruby environment is necessary.
460
-
461
-
462
- [source,sh]
463
- ----
464
- $ gem install tebako
465
- ----
466
-
467
-
468
- ==== Prerequisites
469
-
470
- These prerequisites are needed only for users who want to install Tebako on
471
- their machine and build all Tebako components locally.
472
-
473
- If you use Docker, there is no need to set up these prerequisites.
474
-
475
- ===== Ubuntu 20.04
476
-
477
- ====== General
478
-
479
- There are several prerequisites that need to be installed on Ubuntu 20.04 for
480
- Tebako to work correctly.
481
-
482
-
483
- ====== GNU C/C++ 10+ or Clang C/C++ 12+
484
-
485
- [source,sh]
486
- ----
487
- apt install -y gcc-10 g++-10
488
- update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-10 10
489
- update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-10 10
490
- ----
491
-
492
- or
493
-
494
- [source,sh]
495
- ----
496
- apt install -y clang-12
497
- update-alternatives --install /usr/bin/clang clang /usr/bin/clang-12 150
498
- update-alternatives --install /usr/bin/clang++ clang++ /usr/bin/clang++-12 150
499
- ----
500
-
501
- ====== CMake version 3.20+
502
-
503
- Tebako requires CMake at a version of at least 3.20+.
504
-
505
- If such CMake version is not available as a default package, set it up as
506
- follows.
507
-
508
- .Installing CMake 3.20+
509
- [source,sh]
510
- ----
511
- apt-get remove --purge --auto-remove cmake
512
- apt-get update
513
- apt-get install -y software-properties-common lsb-release curl
514
- apt-get clean all
515
- curl https://apt.kitware.com/kitware-archive.sh | bash
516
- apt-get install cmake
517
- ----
518
-
519
- ====== Other development tools and libraries
520
-
521
- [source,sh]
522
- ----
523
- apt-get -y install sudo git curl build-essential pkg-config bison flex autoconf \
524
- binutils-dev libevent-dev acl-dev libfmt-dev libjemalloc-dev libiberty-dev \
525
- libdouble-conversion-dev liblz4-dev liblzma-dev libssl-dev libunwind-dev \
526
- libboost-filesystem-dev libboost-program-options-dev libboost-system-dev \
527
- libboost-iostreams-dev libboost-date-time-dev libboost-context-dev \
528
- libboost-regex-dev libboost-thread-dev libbrotli-dev libdwarf-dev libelf-dev \
529
- libgoogle-glog-dev libffi-dev libgdbm-dev libyaml-dev libncurses-dev \
530
- libreadline-dev libncurses-dev libreadline-dev ruby-dev ruby-bundler \
531
- libutfcpp-dev
532
- ----
533
-
534
- ===== Alpine 3.17
535
-
536
- ====== General
537
-
538
- There are several prerequisites that need to be installed on Alpine 3.17 for
539
- Tebako to work correctly.
540
-
541
- ====== APK packages
542
-
543
- Run the following command to install all prerequisites.
544
-
545
- [source,sh]
546
- ----
547
- apk --no-cache --upgrade add build-base cmake git bash autoconf boost-static \
548
- boost-dev flex-dev bison make binutils-dev libevent-dev acl-dev sed python3 \
549
- pkgconfig lz4-dev openssl-dev zlib-dev xz ninja zip unzip curl libdwarf-dev \
550
- libunwind-dev gflags-dev elfutils-dev libevent-static openssl-libs-static \
551
- lz4-static xz-dev zlib-static libunwind-static acl-static tar libffi-dev \
552
- gdbm-dev yaml-dev yaml-static ncurses-dev ncurses-static readline-dev \
553
- readline-static p7zip ruby-dev gcompat gettext-dev gperf brotli-dev \
554
- brotli-static jemalloc-dev fmt-dev xz-static
555
- ----
556
-
557
- ===== macOS
558
-
559
- ====== General
560
-
561
- There are several prerequisites that need to be installed on macOS for Tebako to work correctly.
562
-
563
- The following instructions work for:
564
-
565
- * macOS 12 (Monterey) through macOS 14 (Sonoma)
566
-
567
-
568
- ====== Homebrew packages
569
-
570
- We use Homebrew to install the necessary packages on macOS.
571
-
572
- [source,sh]
573
- ----
574
- brew update
575
- brew install gnu-sed bash pkg-config bison flex binutils libffi gdbm zlib \
576
- ncurses double-conversion boost jemalloc fmt glog libevent libsodium lz4 xz \
577
- libyaml openssl@3
578
- brew bundle
579
- ----
580
-
581
- Additionaly tebako repository includes `Brewfile` that can be used with
582
- `brew bundle` command.
583
-
584
- [source,sh]
585
- ----
586
- brew bundle
587
- ----
588
-
589
- ====== Bison 3+
590
-
591
- Tebako requires Bison 3+.
592
-
593
- On macOS 14, the default Bison version is 2.3, and the Homebrew formula is keg-only,
594
- which means that the full path to the Bison binary must be used to utilize the
595
- correct version.
596
-
597
- Run the following command prior to using Tebako, or add it into your shell
598
- profile.
599
-
600
- ====== jemalloc Library Build
601
-
602
- The `libdwarfs` build script creates an additional jemalloc installation on macOS. This is done to satisfy the magic applied by folly during linking but uses a static library.
603
- If the library is created in an emulated environment (QEMU, Rosetta, etc.), there are known issues (link:https://github.com/jemalloc/jemalloc/issues/1997[jemalloc issue #1997]) where jemalloc incorrectly defines the number of significant virtual address bits (lg-vaddr parameter).
604
-
605
- These issues can be fixed by explicitly setting the `--with-lg-vaddr` parameter for the jemalloc build. We decided not to automate this since we do not feel that we can provide reasonable test coverage. Instead, our build script accepts the `LG_VADDR` environment variable and passes it to the jemalloc build as `--with-lg-vaddr=${LG_VADDR}`.
606
-
607
- The `LG_VADDR` parameter specifies the number of significant virtual address bits, which can vary based on the CPU architecture and emulation status.
608
-
609
- Simple script to set `LG_VADDR`. Please note that it is provided for illustration only.
610
-
611
- [source,sh]
612
- ----
613
- #!/bin/bash
614
-
615
- # Check the CPU architecture
616
- ARCH=$(uname -m)
617
-
618
- # Check if running under Rosetta 2 emulation
619
- if [[ "$ARCH" == "x86_64" && $(sysctl -n sysctl.proc_translated) == "1" ]]; then
620
- echo "Running on Apple Silicon under Rosetta 2 emulation"
621
- export LG_VADDR=39
622
- elif [[ "$ARCH" == "arm64" ]]; then
623
- echo "Running on Apple Silicon"
624
- export LG_VADDR=39
625
- else
626
- echo "Running on Intel Silicon"
627
- export LG_VADDR=48
628
- fi
629
-
630
- echo "Setting lg-vaddr to $LG_VADDR"
631
- ----
632
-
633
-
634
- [source,sh]
635
- ----
636
- export PATH="$(brew --prefix bison)/bin:$PATH"
637
- ----
638
-
639
- ===== Windows
640
-
641
- ====== General
642
-
643
- There are several prerequisites that need to be installed on macOS for Tebako to work correctly.
644
-
645
- The following instructions work for:
646
-
647
- * Windows 10, 11
648
- * Windows Server 2019, 2022
649
-
650
- ====== Ruby
651
-
652
- To run Tebako you need to have Ruby installed.
653
- It is simplest to use the Ruby development environment provided by
654
- https://rubyinstaller.org[RubyInstaller].
655
-
656
- For example, Ruby+Devkit 3.1.4-1.
657
-
658
- ====== MinGW ucrt64
659
-
660
- Enable MinGW ucrt64 and install the necessary packages.
661
-
662
- The `ridk` command originates from the RubyInstaller installation.
663
-
664
- [source,sh]
665
- ----
666
- $ ridk enable ucrt64
667
- $ pacman -S git tar bison flex toolchain make cmake
668
- boost diffutils libevent double-conversion
669
- fmt glog dlfcn gtest autotools ncurses libyaml
670
- ----
671
-
672
-
673
-
674
- == Packaging
675
-
676
- === Tebako root folder (aka prefix) selection
677
-
678
- The Tebako prefix determines the base directory for the Tebako setup.
679
-
680
- It is an essential part of configuring how Tebako operates within your system.
681
-
682
- The selection of the Tebako prefix follows a specific order of precedence to
683
- ensure flexibility and ease of use:
684
-
685
- . *User-specified prefix*:
686
- The most direct way to set the root folder is by specifying it through a
687
- command-line argument.
688
-
689
- . *Current Working Directory (PWD)*:
690
- If the prefix option is explicitly set to `PWD`, Tebako uses the current working
691
- directory as Tebako root folder.
692
-
693
- . *Environment variable (`TEBAKO_PREFIX`)*:
694
- In the absence of a user-specified option, Tebako looks for an environment
695
- variable named `TEBAKO_PREFIX`. If found, its value is used as the root folder.
696
-
697
- . *Default value*:
698
- If no prefix is specified and the `TEBAKO_DIR` environment variable is not set,
699
- Tebako defaults to using a directory named `.tebako` in the user's home
700
- directory.
701
-
702
-
703
- Path Expansion: Regardless of the method used to set the Tebako prefix, Tebako
704
- expands the provided path to an absolute path. This expansion includes resolving
705
- relative paths based on the current working directory and expanding user
706
- directory shortcuts like `~`.
707
-
708
-
709
- === Commands
710
-
711
- Tebako provides several commands to manage the packaging and deployment process.
712
-
713
- ==== Press
714
-
715
- This command "presses" a Ruby project using the Tebako components built in the Tebako
716
- root folder (`<tebako-root-folder>`).
717
-
718
-
719
- [NOTE]
720
- ====
721
- The first invocation of the `press` command can take up to an hour as it sets up
722
- the packaging environment and collects the required dependencies. Subsequent
723
- invocations are much faster.
724
- ====
725
-
726
- Upon the next invocation tebako will use previously created packaging
727
- environment. The press process itself takes minutes.
728
-
729
- You can manage setup of packaging environment manually; please refer to
730
- description of setup and clean commands below.
731
-
732
- [source,sh]
733
- ----
734
- tebako press \
735
- -e|--entry-point=<entry-point> \
736
- -r|--root=<project-root-folder> \
737
- [-p|--prefix=<tebako-root-folder>] \
738
- [-R|--Ruby=<ruby-version>] \
739
- [-o|--output=<packaged-file-name>] \
740
- [-l|--log-level=<error|warn|debug|trace>] \
741
- [-c|--cwd=<package current working directory>]
742
- [-D|--devmode] \
743
- [-P|--patchelf] \
744
- [-t|--tebafile=<path-to-tebafile>]
745
- ----
746
-
747
- Where:
748
-
749
- `<tebako-root-folder>`::
750
- the Tebako root folder (see details in the Tebako Root Folder Selection section)
751
-
752
- `Ruby`::
753
- this parameter defines Ruby version that will be packaged (optional, defaults to
754
- `3.1.6`)
755
-
756
- `project-root`::
757
- a folder at the host source file system where project files are located
758
-
759
- `entry-point`::
760
- an executable file (binary executable or script) that shall be started when
761
- packaged file is called
762
-
763
- `output`::
764
- the output file name (optional, defaults to `<current folder>/<entry point base name>`)
765
-
766
- `log-level`::
767
- logging level for the Tebako built-in memory filesystem driver
768
- (optional, defaults to `error`)
769
-
770
- `cwd`::
771
- a folder within Tebako memfs where the packaged application will start. This folder should be specified relative to the memfs root.
772
- If not provided, the application will start within the current folder of the host (i.e., at $PWD).
773
- This option is required because it is not possible to change the directory to a memfs folder until the package is started, as opposed to any host folder
774
- that can be set as the current directory before Tebako package invocation. Tebako saves original working directory in a global Ruby variable `$tebako_original_pwd`.
775
-
776
- `devmode`:: flag that activates development mode, in which Tebako's cache and
777
- packaging consistency checks are relaxed.
778
-
779
- `patchelf`::
780
- flag that removal a reference to GLIBC_PRIVATE version of libpthread from tebako package. This allows Linux Gnu packages to run against versions of
781
- libpthread that differ from the version used for packaging. For example, package created at Ubuntu 20 system can be used on Ubuntu 22. This option makes
782
- sense and works on Gnu Linux only. The feature is exeprimental, we may consider other approach in the future.
783
-
784
- `tebafile`::
785
- the tebako configuration file (optional, defaults to `$PWD/.tebako.yml`).
786
- Please refer to the separate section below for tebafile description.
787
- +
788
- NOTES:
789
- * Development mode is *not intended for production use* and should only be used during development.
790
- * `entry-point` and `project-root-folder` are required parameters and may be provided either via command-line or in `tebafile`.
791
-
792
- [example]
793
- ====
794
- [source,sh]
795
- ----
796
- tebako press \
797
- --root='~/projects/myproject' \
798
- --entry=start.rb \
799
- --output=/temp/myproject.tebako
800
- ----
801
- ====
802
-
803
- ==== Setup
804
-
805
- This command sets up the Tebako packaging environment.
806
-
807
- Collects required packages, builds the and creates packaging environment. This
808
- is a lengthy task that can take significant time, up to 1 hour.
809
-
810
- Tebako supports several configurations at a single system given that their root
811
- directories differ and multiple Ruby versions within single configuration
812
-
813
- This command is optional, tebako creates packaging environment automatically
814
- upon the first invocation of press command.
815
-
816
- However, if you plan to use tebako in CI/CD environment with caching it is
817
- highly recommended to build cache based on `tebako setup` output. Building cache
818
- based on `tebako press` may create inconsistent environment upon restore.
819
-
820
- [source,sh]
821
- ----
822
- $ tebako setup \
823
- [-p|--prefix=<tebako-root-folder>] \
824
- [-R|--Ruby=<ruby-version>] \
825
- [-D|--devmode] \
826
- [-t|--tebafile=<path-to-tebafile>]
827
- ----
828
-
829
- Where:
830
-
831
- `<tebako-root-folder>`:: the Tebako root folder (see details in the Tebako Root Folder Selection section)
832
-
833
- `Ruby`:: parameter defines Ruby version that will be packaged (optional, defaults to 3.1.6)
834
-
835
- `tebafile`::
836
- the tebako configuration file (optional, defaults to `$PWD/.tebako.yml`).
837
- Please refer to the separate section below for tebafile description.
838
-
839
- `devmode`:: flag activates development mode, in which Tebako's cache and packaging consistency checks are relaxed.
840
- Please note that this mode is not intended for production use and should only be used during development.
841
-
842
- ==== Clean
843
-
844
- This command cleans up all Tebako artifacts in the specified prefix directory.
845
-
846
- NOTE: These artifacts are created by the `setup` and `press` commands.
847
- Normally you do not need to do it since tebako packager optimizes artifacts lifecycle on its own.
848
-
849
- [source,sh]
850
- ----
851
- $ tebako clean \
852
- [-p|--prefix=<tebako-root-folder>] \
853
- [-t|--tebafile=<path-to-tebafile>]
854
- ----
855
-
856
- Where:
857
-
858
- `<tebako-root-folder>`:: the Tebako root folder (see details in the Tebako Root Folder Selection section)
859
-
860
- `tebafile`::
861
- the tebako configuration file (optional, defaults to `$PWD/.tebako.yml`).
862
- Please refer to the separate section below for tebafile description.
863
-
864
- [example]
865
- ====
866
- [source,sh]
867
- ----
868
- tebako clean --prefix='~/.tebako'
869
- ----
870
- ====
871
-
872
-
873
- ==== Clean Ruby
874
-
875
- This command cleans up only the Ruby artifacts from the specified prefix
876
- directory.
877
-
878
- NOTE: These artifacts are created by the `setup` and `press` commands.
879
- Normally you do not need to do it, since Tebako packager optimizes artifacts
880
- lifecycle on its own.
881
-
882
- NOTE: Compiled DwarFS libraries are not cleaned.
883
-
884
- [source,sh]
885
- ----
886
- $ tebako clean_ruby
887
- [-p|--prefix=<tebako-root-folder>] \
888
- [-R|--Ruby=<ruby-version>] \
889
- [-t|--tebafile=<path-to-tebafile>]
890
-
891
- ----
892
-
893
- Where:
894
-
895
- `<tebako-root-folder>`::
896
- the Tebako setup folder (optional, defaults to current folder)
897
-
898
- `Ruby`::
899
- defines Ruby version that will cleaned (optional, cleans all versions by default)
900
-
901
- `tebafile`::
902
- the tebako configuration file (optional, defaults to `$PWD/.tebako.yml`).
903
- Please refer to the separate section below for tebafile description.
904
-
905
- [example]
906
- ====
907
- [source,sh]
908
- ----
909
- tebako clean_ruby --prefix='~/.tebako'
910
- ----
911
- ====
912
-
913
- ==== Build script hash
914
-
915
- This command outputs a hash value for the Tebako build script, which can be used
916
- as a cache key in CI/CD pipelines.
917
-
918
- [source,sh]
919
- ----
920
- $ tebako hash
921
- ----
922
-
923
- === Tebako configuration file
924
-
925
- It is possible to provide all or some options for the `tebako setup/press/clean/clean_ruby` commands via Tebako configuration file ('tebafile').
926
- Tebafile is a YAML file with a single section 'options'. The options are the same as long names for the command line. For, example for the prefix option
927
-
928
- [source]
929
- ----
930
- -p|--prefix=<tebako-root-folder>
931
- ----
932
- the key in the YAML file would be 'prefix'.
933
-
934
- Below is an example tebafile that sets values for prefix and Ruby options
935
- [source,yaml]
936
- ----
937
- options:
938
- prefix: /tmp/tebako
939
- Ruby: 3.2.4
940
- ----
941
-
942
- Please note that the options provided on the command line have preference over tebafile settings.
943
-
944
- === Exit codes
945
-
946
- The Tebako CLI exits with different exit codes to indicate the status of the
947
- operation. The following table lists the possible exit codes and their meanings.
948
-
949
- .Tebako CLI exit codes
950
- [cols="a,a"]
951
- |===
952
- | Code | Condition
953
-
954
- | 0 | No error
955
- | 1 | Invalid command line
956
- | 101 | `tebako setup` failed at configuration step
957
- | 102 | `tebako setup` failed at build step
958
- | 103 | `tebako press` failed at configuration step
959
- | 104 | `tebako press` failed at build step
960
- | 253 | Unsupported Ruby version
961
- | 254 | Unsupported operating systems
962
- | 255 | Internal error
963
-
964
- |===
965
-
966
-
967
- == Packaging scenarios with Ruby
968
-
969
- Tebako for Ruby supports the following packaging scenarios.
970
-
971
- This is high-level description of the Tebako Ruby packaging mechanism.
972
-
973
- NOTE: These scenarios were inspired by the `ruby-packer` approach.
974
-
975
- NOTE: Tebako Ruby is created independently from `ruby-packer`, no line of code
976
- was copied from `ruby-packer`.
977
-
978
- Depending on the configuration files that are present in the root project folder, the Tebako Ruby packager supports different packaging scenarios.
979
-
980
- These scenarios differ in what files are packaged and where the entry point is located.
981
-
982
- Here is a summary of the scenarios:
983
-
984
- [cols="a,2a,4a,3a,a,a,a"]
985
- |===
986
- | Scenario | Description | Packaging | Entry point | `*.gemspec` | `Gemfile` | `*.gem`
987
-
988
- | 1
989
- | Simple ruby script
990
- | Copy `<project-root>` with all sub-folders to packaged filesystem
991
- | `<mount_point>/local/<entry_point base name>`
992
- | No
993
- | No
994
- | No
995
-
996
-
997
- | 2
998
- | Packaged gem
999
- | Install the gem with `gem install` to packaged filesystem
1000
- | `<mount_point>/bin/<entry_point base name>` (i.e., binstub is expected)
1001
- | No
1002
- | No
1003
- | One
1004
-
1005
-
1006
- | 3
1007
- | Gem source, no `bundler`
1008
- |
1009
- . Build the gem using `gem build` command at the host
1010
- . Install it with `gem install` to packaged filesystem
1011
-
1012
- | `<mount_point>/bin/<entry_point base name>` (i.e., binstub is expected)
1013
- | One
1014
- | No
1015
- | Any
1016
-
1017
-
1018
- | 4
1019
- | Gem source, `bundler`
1020
- |
1021
- . Collect dependencies at the host with `bundle install`
1022
- . Build the gem using `gem build` command
1023
- . Install it with `gem install` to packaged file system
1024
-
1025
- | `<mount_point>/bin/<entry_point base name>` (i.e., binstub is expected)
1026
- | One
1027
- | One
1028
- | Any
1029
-
1030
-
1031
- | 5
1032
- | Rails project
1033
- | Deploy project to packaged filesystem using `bundle install`
1034
- | `<mount_point>/local/<entry_point base name>`
1035
- | No
1036
- | One
1037
- | Any
1038
-
1039
-
1040
- | Error
1041
- | Error: Two or more `*.gem` files present
1042
- | -
1043
- | -
1044
- | No
1045
- | No
1046
- | Two or more
1047
-
1048
-
1049
- | Error
1050
- | Error: Two or more `*.gemspec` files present
1051
- | -
1052
- | -
1053
- | Two or more
1054
- | Any
1055
- | Any
1056
-
1057
- |===
1058
-
1059
- These scenarios determine how the project is packaged and where the entry point is located within the packaged filesystem.
1060
-
1061
- == Run-time options
1062
-
1063
- Generally Tebako package passes command line options to the packaged application
1064
-
1065
- [example]
1066
- ====
1067
- For example, if the package was created with the following command
1068
-
1069
- [source,sh]
1070
- ----
1071
- tebako press \
1072
- --root='~/projects/myproject' \
1073
- --entry=start.rb \
1074
- --output=/temp/myproject.tebako
1075
- ----
1076
- running
1077
-
1078
- [source,sh]
1079
- ----
1080
- /temp/myproject.tebako --option --parameter value
1081
- ----
1082
-
1083
- will be translated by Tebako bootstrap code to
1084
-
1085
- [source,sh]
1086
- ----
1087
- myproject --option --parameter value
1088
- ----
1089
- ====
1090
-
1091
- However there are several command-line parameters that are intercepted processed by Tebako bootstrap code as follows
1092
-
1093
- === Image extraction (--tebako-extract option)
1094
-
1095
- Tebako provides an option to an extract its DwarFS filesystem from a package to
1096
- a local folder for verification or execution.
1097
-
1098
- [source,sh]
1099
- ----
1100
- $ <tebako-packaged-executable> --tebako-extract [<root folder for extracted filesystem>]
1101
- ----
1102
-
1103
- Where,
1104
-
1105
- `<root folder for extracted filesystem>`::
1106
- The root folder for the extracted filesystem (optional, defaults to `source_filesystem`)
1107
-
1108
- [example]
1109
- ====
1110
- Extracting Tebako content from the `metanorma` package:
1111
-
1112
- [source,sh]
1113
- ----
1114
- metanorma --tebako-extract temp-image
1115
- ----
1116
- ====
1117
-
1118
- The `--tebako-extract` option actually runs the following Ruby script:
1119
-
1120
- [source,ruby]
1121
- ----
1122
- require 'fileutils'
1123
- FileUtils.copy_entry '<in-memory filesystem root>', ARGV[2] || 'source_filesystem'
1124
- ----
1125
-
1126
- === Mounting Host Folder to Tebako Memfs (`--tebako-mount` option)
1127
-
1128
- Some programs unconditionally use folders located under the application root, and when processed by Tebako
1129
- or similar tools, these folders are included in the packaging.
1130
-
1131
- For example, there is no configuration option to change where Rails expects the `tmp` folder to be.
1132
- The location is hardcoded in multiple places within the Rails codebase, residing under the application root,
1133
- and as a result, it gets included in the read-only Tebako memfs. Although patches have been proposed
1134
- (e.g., https://github.com/rails/rails/issues/39583), there is currently no way to change the paths for
1135
- temporary files, caches, and sockets.
1136
-
1137
- To address this limitation in Rails and similar issues in other applications, Tebako provides an option
1138
- to mount a host folder to the memfs tree.
1139
-
1140
- When using Tebako, consider the packaging scenario mentioned above, as it defines the layout of the application
1141
- tree. The `--tebako-extract` option may be useful for understanding the placement of files and folders.
1142
-
1143
- [example]
1144
- ====
1145
- The following command starts a `rails.tebako` package with `$PWD/tmp` mounted as `local/tmp` in the memfs.
1146
- Any remaining command-line parameters are passed to the application.
1147
- [source,sh]
1148
- ----
1149
- rails.tebako --tebako-mount local/tmp:$PWD/tmp server
1150
- ----
1151
- ====
1152
-
1153
- The `--tebako-mount` option has the following syntax:
1154
- [source,sh]
1155
- ----
1156
- --tebako-mount <memfs path>:<host path>
1157
- ----
1158
-
1159
- The `--tebako-mount` option can be repeated multiple times to mount more than one object. The `memfs path`
1160
- is relative to the memfs root, and it is recommended to use absolute paths for host objects. Both directories
1161
- and files can be mounted in this way. Tebako allows overlaying existing memfs objects, so there are no significant
1162
- limitations.
1163
-
1164
- == Trivia: origin of name
1165
-
1166
- "tamatebako" (玉手箱) is the treasure box given to Urashima Taro in the Ryugu,
1167
- for which he was asked not to open if he wished to return. He opened the box
1168
- upon the shock from his return that three hundred years has passed. Apparently
1169
- what was stored in the box was his age.
1170
-
1171
- This packager was made to store Ruby and its gems, and therefore named after
1172
- the said treasure box (storing gems inside a treasure box).
1173
-
1174
- Since "tamatebako" is rather long for the non-Japanese speaker, we use "tebako"
1175
- (手箱, also "tehako") instead, the generic term for a personal box.
1176
-
1177
- == Contributing
1178
-
1179
- We welcome contributions! Please see our contributing guidelines for more
1180
- information.
1181
-
1182
- == License
1183
-
1184
- Copyright Ribose. All rights reserved.
1185
-
1186
- Tebako is released under the BSD 2-Clause License. See the LICENSE file for details.
1
+ = Tebako: An advanced image packager for interpretive languages
2
+
3
+ Platform tests on GitHub:
4
+ image:https://github.com/tamatebako/tebako/actions/workflows/ubuntu.yml/badge.svg["Ubuntu amd64", link="https://github.com/tamatebako/tebako/actions/workflows/ubuntu.yml"]
5
+ image:https://github.com/tamatebako/tebako/actions/workflows/alpine.yml/badge.svg["Alpine", link="https://github.com/tamatebako/tebako/actions/workflows/alpine.yml"]
6
+ image:https://github.com/tamatebako/tebako/actions/workflows/macos.yml/badge.svg["macOS amd64", link="https://github.com/tamatebako/tebako/actions/workflows/macos.yml"]
7
+ image:https://github.com/tamatebako/tebako/actions/workflows/windows-msys.yml/badge.svg["Windows msys", link="https://github.com/tamatebako/tebako/actions/workflows/windows-msys.yml"]
8
+
9
+ Platform tests on Cirrus:
10
+ image:https://api.cirrus-ci.com/github/tamatebako/tebako.svg?branch=main&task=ubuntu-aarch64["Ubuntu aarch64", link="https://cirrus-ci.com/github/tamatebako/tebako"]
11
+
12
+ Tools tests on GitHub:
13
+ image:https://github.com/tamatebako/tebako-ci-containers/actions/workflows/build-containers.yml/badge.svg["Tebako cobtainers", link="https://github.com/tamatebako/tebako-ci-containers/actions/workflows/build-containers.yml"]
14
+
15
+ Quality:
16
+ image:https://github.com/tamatebako/tebako/actions/workflows/lint-and-rspec.yml/badge.svg["lint and rspec", link="https://github.com/tamatebako/tebako/actions/workflows/lint-and-rspec.yml"]
17
+ image:https://codecov.io/gh/tamatebako/tebako/graph/badge.svg?token=XD3emQ5qsY["Tebako cli rspec coverage", link="https://codecov.io/gh/tamatebako/tebako"]
18
+
19
+ == Purpose
20
+
21
+ Tebako is an advanced executable packager designed for applications written in
22
+ interpretive languages.
23
+
24
+ It simplifies distribution and deployment by packaging your entire project with
25
+ a bundled runtime into a single, performant, executable binary.
26
+
27
+ == Architecture
28
+
29
+ A Tebako-packaged binary is effectively a self-executing container-in-a-file.
30
+
31
+ The packaged binary contains the following components:
32
+
33
+ * An on-file filesystem (OFFS) containing all the project files and
34
+ dependencies in DwarFS format.
35
+
36
+ * A runtime environment that includes the necessary libraries and interpreters,
37
+ with patched filesystem calls that redirect access of project files to the
38
+ on-file filesystem.
39
+
40
+ * An executable loader that loads the on-file filesystem in memory and executes
41
+ the project.
42
+
43
+
44
+ == Supported runtimes, platforms and architectures
45
+
46
+ Tebako artifacts can be built and executed on the following platforms and
47
+ architectures.
48
+
49
+ .Supported platforms and architectures
50
+ [cols="3", options="header"]
51
+ |===
52
+ | Platform and version | Architectures | Build system
53
+
54
+ 3+| **Linux**
55
+ | Ubuntu 20.04 | amd64, aarch64 | gcc/g+\+: 10; clang/clang++: 12
56
+ | Alpine 3.17 | amd64 | gcc/g+\+: default; clang/clang++: default
57
+
58
+ 3+| **macOS**
59
+ | macOS 13 (Ventura) | amd64, arm64 | tested agains xcode: [14.3.1]
60
+ | macOS 14 (Sonoma) | amd64, arm64 | tested agains xcode: [15.0.1, 15.4]
61
+ | macOS 15 (Sequoia) | amd64, arm64 | tested agains xcode: [16.1]
62
+
63
+ 3+| **Windows**
64
+ | Windows 10 | amd64 | MinGW ucrt64
65
+ | Windows 11 | amd64 | MinGW ucrt64
66
+ | Windows Server 2019 | amd64 | MinGW ucrt64
67
+ | Windows Server 2022 | amd64 | MinGW ucrt64
68
+
69
+ |===
70
+
71
+ [NOTE]
72
+ ====
73
+ Windows build caveats:
74
+
75
+ * Tebako may face errors related to CMake path length limitations (https://gitlab.kitware.com/cmake/cmake/-/issues/25936).
76
+ This error may affect not tebako itself but the gems that need to be package and use CMake to build native extensions.
77
+ There is no workaround for this issue as it looks like is a limitation of the manifest used to build CMake executable.
78
+
79
+ * MSys strip utility creates broken executable when tebako image is processed. Linking with '-s' flag produces unusable
80
+ executables as well.
81
+ Until this issue (https://github.com/tamatebako/tebako/issues/172) is resolved we plan to produce an Windows executable
82
+ with debug information unstripped. You can opt to run 'strip -S' manually, it most cases it works.
83
+
84
+ MacOS build caveats:
85
+
86
+ * We saw clang compiler segmentaion fault when during packaging of very large projects with XCode 14.3.1
87
+ This issue is not reproducible with XCode 15.0.1 or higher.
88
+ ====
89
+
90
+
91
+ .Supported Ruby versions
92
+ [cols="2", options="header"]
93
+ |===
94
+ | Ruby version | Supported platforms
95
+
96
+ | 2.7.8 | Linux, macOS
97
+ | 3.0.7 | Linux, macOS
98
+ | 3.1.6 | Linux, macOS, Windows
99
+ | 3.2.{4,5} | Linux, macOS, Windows
100
+ | 3.3.{3,4,5} | Linux, macOS, Windows
101
+
102
+ |===
103
+
104
+ NOTE: Our goal is to support all maintained Ruby releases, including minor versions.
105
+
106
+
107
+ == Package portability
108
+
109
+ === General
110
+
111
+ Tebako packages are designed to be "forward portable" across different operating
112
+ systems and architectures to allow for easy distribution and deployment.
113
+
114
+ Forward portability means that a package created on a specific platform can be
115
+ executed on a newer version of the same platform.
116
+
117
+ === macOS
118
+
119
+ macOS packages are forward portable across different macOS versions.
120
+
121
+ [example]
122
+ A Tebako executable package built on macOS 13 (Ventura) can be executed on
123
+ macOS 14 (Sonoma), but not vice versa.
124
+
125
+ `x86_64` macOS packages can be run on Apple M (ARM) systems.
126
+
127
+
128
+ === Linux distributions using `musl`
129
+
130
+ Packages built for the
131
+ https://musl.libc.org[`musl` implementation of the C standard library]
132
+ (such as https://alpinelinux.org[Alpine Linux]) are forward portable.
133
+
134
+ [example]
135
+ A Tebako executable package built on Alpine 3.17 can be executed on Alpine 3.19.
136
+
137
+ Usage of the
138
+ https://github.com/tamatebako/tebako-ci-containers[Tebako Docker containers] for
139
+ packaging is encouraged since it eliminates the effort needed for toolchain
140
+ setup and configuration.
141
+
142
+
143
+ === Linux distributions using `glibc`
144
+
145
+ Packages built for the
146
+ https://sourceware.org/glibc[`glibc` implementation of the C standard library]
147
+ are forward portable if the `--patchelf` experimental option is enabled.
148
+
149
+ The `--patchelf` option allows these packages to be portable to Linux GNU
150
+ distributions with GLIBC version 2.31 and above.
151
+
152
+ [example]
153
+ A Tebako executable package built on Ubuntu 20.04 with `--patchelf` option can
154
+ be executed on Rocky Linux 9.
155
+
156
+ Usage of the
157
+ https://github.com/tamatebako/tebako-ci-containers[Tebako Docker containers] for
158
+ packaging is encouraged since it eliminates the effort needed for toolchain
159
+ setup and configuration.
160
+
161
+
162
+ .Minimum versions of GLIBC Linux distributions that support Tebako packages with forward portability
163
+ [cols="3", options="header"]
164
+ |===
165
+ | Distribution | Minimal supported version | GLIBC version
166
+
167
+ | Ubuntu | 20.04 (Focal Fossa) | GLIBC 2.31
168
+ | Debian | 11 (Bullseye) | GLIBC 2.31
169
+ | Rocky Linux | 9 | GLIBC 2.34
170
+ | Fedora | 33 | GLIBC 2.32
171
+ | CentOS | 9 | GLIBC 2.34
172
+ | Red Hat Enterprise Linux (RHEL) | 9 | GLIBC 2.34
173
+ | Oracle Linux | 9 | GLIBC 2.34
174
+
175
+ |===
176
+
177
+
178
+ == Future plans
179
+
180
+ * Downloading new DwarFS images to be stored in the local home directory
181
+ * Allowing loading multiple DwarFS images in a stacked way
182
+ * Supporting a COW mechanism that the newly written files are stored
183
+ in a separate image that can be loaded on top of the read-only file systems.
184
+
185
+ == FAQ
186
+
187
+ === Why use Tebako?
188
+
189
+ Tebako is particularly useful for developers who need to:
190
+
191
+ * Distribute applications without requiring users to have specific runtimes installed.
192
+ * Simplify the deployment process by packaging all dependencies into one binary.
193
+ * Ensure consistency across different environments by using a single executable.
194
+ * Flexibility to support different runtime versions on the user's machine.
195
+
196
+
197
+ === How do I know I need Tebako?
198
+
199
+ You might need Tebako if you:
200
+
201
+ * Want to package your application into a single, self-contained binary.
202
+ * Want to avoid the complexities of managing runtime environments on target machines.
203
+ * Distribute software to environments where installing runtimes and their dependencies is challenging.
204
+ * Require a streamlined way to deliver applications to end-users.
205
+ * Need to ensure that your application runs consistently across different environments and architectures.
206
+
207
+
208
+ === What is DwarFS?
209
+
210
+ https://github.com/mhx/dwarfs[DwarFS] is a fast, high compression read-only
211
+ user-land file system designed for efficient storage and access of large
212
+ collections of files.
213
+
214
+ It is used by Tebako to package applications into a compact and efficient format.
215
+
216
+ Tebako uses https://github.com/tamatebako/libdwarfs[libdwarfs], the library
217
+ form of https://github.com/mhx/dwarfs[DwarFS], developed for the Tebako project.
218
+
219
+ === When is Tebako better than comparable solutions?
220
+
221
+ Tebako offers several advantages over comparable solutions for supported
222
+ interpretive languages.
223
+
224
+ They are listed in order of the degree of virtualization below.
225
+
226
+ Tebako stands out by providing a lightweight runtime bundling approach that
227
+ simplifies distribution and deployment while offering flexibility and
228
+ efficiency.
229
+
230
+ It eliminates the need for users to have specific runtimes installed and ensures
231
+ consistency across different environments.
232
+
233
+ With Tebako, you can package your entire project with a bundled runtime into a
234
+ single, performant, executable binary.
235
+
236
+ [cols="a,3a,3a"]
237
+ |===
238
+ | Solution | Pros | Cons
239
+
240
+ | Virtual machines (VMs)
241
+ |
242
+ - Provides full isolation and compatibility across environments
243
+ |
244
+ - Requires a separate VM installation for each application
245
+ - Heavy resource consumption for virtualization
246
+
247
+ | Docker
248
+ |
249
+ - Provides portable containers
250
+ - Isolates entire applications and their dependencies
251
+ - Supports easy deployment and scalability
252
+ |
253
+ - Requires Docker installation and management
254
+ - Requires administrative rights on machine
255
+ - Containerization overhead
256
+
257
+ | *Tebako*
258
+ |
259
+ - Packages all files and dependencies into a single binary
260
+ - Supports multiple operating systems and architectures
261
+ - Provides efficient packaging and execution with DwarFS
262
+ - Offers security features like signing on macOS
263
+ - Simplifies distribution and deployment
264
+ - Native running speed
265
+ |
266
+ - Initial packaging time longer than Ruby gems
267
+ - Minor runtime overhead
268
+
269
+ | Ruby Gems
270
+ |
271
+ - Easy installation of Ruby libraries
272
+ - Provides user-side version control and dependency management
273
+ |
274
+ - Requires Ruby installation and gem management
275
+ - Runtime execution dependent on the user's installed Ruby version and gems
276
+
277
+ |===
278
+
279
+
280
+ == Usage
281
+
282
+ === Command-line interface
283
+
284
+ Tebako works by packaging your project into a single executable binary that
285
+ includes all the necessary dependencies.
286
+
287
+ The way to work with Tebako is through its command-line interface (CLI).
288
+ It provides the following commands:
289
+
290
+ `setup`::
291
+ Prepares the Tebako packaging environment.
292
+
293
+ `press`::
294
+ Packages a project into a single executable binary.
295
+
296
+ `clean`::
297
+ Removes Tebako artifacts.
298
+
299
+ `clean_ruby`::
300
+ Removes Tebako Ruby artifacts.
301
+
302
+ `hash`::
303
+ Calculates the Tebako script hash for use as a cache key in CI/CD environments.
304
+
305
+ `extract`::
306
+ Extracts the filesystem from a Tebako package.
307
+
308
+ `version`::
309
+ Displays the Tebako version.
310
+
311
+ `help`::
312
+ Displays the help message.
313
+
314
+
315
+ == Usage
316
+
317
+ === General
318
+
319
+ Tebako can be used in two ways:
320
+
321
+ * Through the Tebako container
322
+ * Local installation
323
+
324
+ Please refer to the <<installation>> section on how to install Tebako.
325
+
326
+
327
+ [[installation]]
328
+ == Installation
329
+
330
+ === General
331
+
332
+ Installation of Tebako is only needed in order to package an application.
333
+
334
+ There is no need to install anything for users who run the packaged application.
335
+
336
+
337
+ === Using Docker
338
+
339
+ ==== General
340
+
341
+ If you have Docker installed and available, the easiest way to run Tebako is
342
+ through the official Docker containers.
343
+
344
+ Docker containers with preinstalled Tebako packaging environments for Ubuntu and
345
+ Alpine Linux are available at
346
+ https://github.com/tamatebako/tebako-ci-containers[tebako-ci-containers].
347
+
348
+
349
+ ==== Pull the container
350
+
351
+ Pull the Tebako container image.
352
+
353
+ [source,sh]
354
+ ----
355
+ docker pull ghcr.io/tamatebako/tebako-<container_tag>:latest
356
+ ----
357
+
358
+ `<container_tag>`:: is the desired image tag (e.g., `ubuntu-20.04` or `alpine-3.17`).
359
+
360
+
361
+ ==== Running Tebako commands in the container
362
+
363
+ Simply prefix the Tebako command with `docker run` and the container image.
364
+
365
+ [source,sh]
366
+ ----
367
+ docker run -v <application_folder>:/mnt/w \
368
+ -t ghcr.io/tamatebako/tebako-<container_tag>:latest \
369
+ tebako {command} {parameters}
370
+ ----
371
+
372
+ ==== Packaging from outside the container
373
+
374
+ To package your application from outside the container, just run a single Docker
375
+ command.
376
+
377
+ This command mounts the application folder into the container and runs the
378
+ `tebako press` command, specifying the application root, entry point, output
379
+ location, and Ruby version.
380
+
381
+ [source,sh]
382
+ ----
383
+ docker run -v <application_folder>:/mnt/w \
384
+ -t ghcr.io/tamatebako/tebako-<container_tag>:latest \
385
+ tebako press <tebako-press-parameters>
386
+ ----
387
+
388
+ `<application_folder>`:: is the path to your application folder.
389
+
390
+ `<container_tag>`:: is the desired image tag (e.g., `ubuntu-20.04` or `alpine-3.17`).
391
+
392
+
393
+ [example]
394
+ ====
395
+ Assume that you have a Ruby application in the `fontist` folder of the current
396
+ directory.
397
+
398
+ You can package it to `./fontist-package` using the following command:
399
+
400
+ [source,sh]
401
+ ----
402
+ docker run -v $PWD:/mnt/w \
403
+ -t ghcr.io/tamatebako/tebako-ubuntu-20.04:latest \
404
+ tebako press --root=/mnt/w/fontist --entry-point=fontist --output=/mnt/w/fontist-package --Ruby=3.2.4
405
+ ----
406
+ ====
407
+
408
+ ==== Packaging from inside the container
409
+
410
+ It is also possible to package an application from inside the Tebako container.
411
+
412
+ Start and enter the container interactively.
413
+
414
+ [source,sh]
415
+ ----
416
+ docker run -it --rm -v <application_folder>:/mnt/w \
417
+ ghcr.io/tamatebako/tebako-<container_tag>:latest bash
418
+ ----
419
+
420
+ `<application_folder>`:: is the path to your application folder.
421
+
422
+ `<container_tag>`:: is the desired image tag (e.g., `ubuntu-20.04` or `alpine-3.17`).
423
+
424
+
425
+ Once inside, run the `tebako press` command:
426
+
427
+ [source,sh]
428
+ ----
429
+ tebako press <tebako press parameters>
430
+ ----
431
+
432
+ [example]
433
+ ====
434
+ Assume that you have a Ruby application in the `fontist` folder of the current
435
+ directory.
436
+
437
+ You can package it to `./fontist-package` using the following command:
438
+
439
+ [source,sh]
440
+ ----
441
+ $ docker run -it --rm -v $PWD:/mnt/w ghcr.io/tamatebako/tebako-<container_tag>:latest bash
442
+
443
+ # Inside the container:
444
+ $ tebako press --root=/mnt/w/fontist --entry-point=fontist --output=/mnt/w/fontist-package --Ruby=3.2.4
445
+ ----
446
+ ====
447
+
448
+
449
+ === Local installation
450
+
451
+ ==== General
452
+
453
+ There are cases where Docker may not be suitable for your needs, such as:
454
+
455
+ . Admin privileges: Running Docker requires administrative privileges, which
456
+ means Docker may not be available to users on their machines.
457
+
458
+ . Performance penalty: Docker introduces a performance penalty due to the
459
+ overhead of running containers. This can be a concern when packaging complex
460
+ applications that require heavy memory usage.
461
+
462
+ In such cases, you can choose to install Tebako locally.
463
+
464
+ Tebako is distributed as a Ruby gem. A Ruby environment is necessary.
465
+
466
+
467
+ [source,sh]
468
+ ----
469
+ $ gem install tebako
470
+ ----
471
+
472
+
473
+ ==== Prerequisites
474
+
475
+ These prerequisites are needed only for users who want to install Tebako on
476
+ their machine and build all Tebako components locally.
477
+
478
+ If you use Docker, there is no need to set up these prerequisites.
479
+
480
+ ===== Ubuntu 20.04
481
+
482
+ ====== General
483
+
484
+ There are several prerequisites that need to be installed on Ubuntu 20.04 for
485
+ Tebako to work correctly.
486
+
487
+
488
+ ====== GNU C/C++ 10+ or Clang C/C++ 12+
489
+
490
+ [source,sh]
491
+ ----
492
+ apt install -y gcc-10 g++-10
493
+ update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-10 10
494
+ update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-10 10
495
+ ----
496
+
497
+ or
498
+
499
+ [source,sh]
500
+ ----
501
+ apt install -y clang-12
502
+ update-alternatives --install /usr/bin/clang clang /usr/bin/clang-12 150
503
+ update-alternatives --install /usr/bin/clang++ clang++ /usr/bin/clang++-12 150
504
+ ----
505
+
506
+ ====== CMake version 3.20+
507
+
508
+ Tebako requires CMake at a version of at least 3.20+.
509
+
510
+ If such CMake version is not available as a default package, set it up as
511
+ follows.
512
+
513
+ .Installing CMake 3.20+
514
+ [source,sh]
515
+ ----
516
+ apt-get remove --purge --auto-remove cmake
517
+ apt-get update
518
+ apt-get install -y software-properties-common lsb-release curl
519
+ apt-get clean all
520
+ curl https://apt.kitware.com/kitware-archive.sh | bash
521
+ apt-get install cmake
522
+ ----
523
+
524
+ ====== Other development tools and libraries
525
+
526
+ [source,sh]
527
+ ----
528
+ apt-get -y install sudo git curl build-essential pkg-config bison flex autoconf \
529
+ binutils-dev libevent-dev acl-dev libfmt-dev libjemalloc-dev libiberty-dev \
530
+ libdouble-conversion-dev liblz4-dev liblzma-dev libssl-dev libunwind-dev \
531
+ libboost-filesystem-dev libboost-program-options-dev libboost-system-dev \
532
+ libboost-iostreams-dev libboost-date-time-dev libboost-context-dev \
533
+ libboost-regex-dev libboost-thread-dev libbrotli-dev libdwarf-dev libelf-dev \
534
+ libgoogle-glog-dev libffi-dev libgdbm-dev libyaml-dev libncurses-dev \
535
+ libreadline-dev libncurses-dev libreadline-dev ruby-dev ruby-bundler \
536
+ libutfcpp-dev
537
+ ----
538
+
539
+ ===== Alpine 3.17
540
+
541
+ ====== General
542
+
543
+ There are several prerequisites that need to be installed on Alpine 3.17 for
544
+ Tebako to work correctly.
545
+
546
+ ====== APK packages
547
+
548
+ Run the following command to install all prerequisites.
549
+
550
+ [source,sh]
551
+ ----
552
+ apk --no-cache --upgrade add build-base cmake git bash autoconf boost-static \
553
+ boost-dev flex-dev bison make binutils-dev libevent-dev acl-dev sed python3 \
554
+ pkgconfig lz4-dev openssl-dev zlib-dev xz ninja zip unzip curl libdwarf-dev \
555
+ libunwind-dev gflags-dev elfutils-dev libevent-static openssl-libs-static \
556
+ lz4-static xz-dev zlib-static libunwind-static acl-static tar libffi-dev \
557
+ gdbm-dev yaml-dev yaml-static ncurses-dev ncurses-static readline-dev \
558
+ readline-static p7zip ruby-dev gcompat gettext-dev gperf brotli-dev \
559
+ brotli-static jemalloc-dev fmt-dev xz-static
560
+ ----
561
+
562
+ ===== macOS
563
+
564
+ ====== General
565
+
566
+ There are several prerequisites that need to be installed on macOS for Tebako to work correctly.
567
+
568
+ The following instructions work for:
569
+
570
+ * macOS 13 (Ventura) through macOS 15 (Sequoia)
571
+
572
+
573
+ ====== Homebrew packages
574
+
575
+ We use Homebrew to install the necessary packages on macOS.
576
+
577
+ [source,sh]
578
+ ----
579
+ brew update
580
+ brew install gnu-sed bash pkg-config bison flex binutils libffi gdbm zlib \
581
+ ncurses double-conversion boost jemalloc fmt glog libevent libsodium lz4 xz \
582
+ libyaml openssl@3
583
+ brew bundle
584
+ ----
585
+
586
+ Additionaly tebako repository includes `Brewfile` that can be used with
587
+ `brew bundle` command.
588
+
589
+ [source,sh]
590
+ ----
591
+ brew bundle
592
+ ----
593
+
594
+ ====== Bison 3+
595
+
596
+ Tebako requires Bison 3+.
597
+
598
+ On macOS 14, the default Bison version is 2.3, and the Homebrew formula is keg-only,
599
+ which means that the full path to the Bison binary must be used to utilize the
600
+ correct version.
601
+
602
+ Run the following command prior to using Tebako, or add it into your shell
603
+ profile.
604
+
605
+ ====== jemalloc Library Build
606
+
607
+ The `libdwarfs` build script creates an additional jemalloc installation on macOS. This is done to satisfy the magic applied by folly during linking but uses a static library.
608
+ If the library is created in an emulated environment (QEMU, Rosetta, etc.), there are known issues (link:https://github.com/jemalloc/jemalloc/issues/1997[jemalloc issue #1997]) where jemalloc incorrectly defines the number of significant virtual address bits (lg-vaddr parameter).
609
+
610
+ These issues can be fixed by explicitly setting the `--with-lg-vaddr` parameter for the jemalloc build. We decided not to automate this since we do not feel that we can provide reasonable test coverage. Instead, our build script accepts the `LG_VADDR` environment variable and passes it to the jemalloc build as `--with-lg-vaddr=${LG_VADDR}`.
611
+
612
+ The `LG_VADDR` parameter specifies the number of significant virtual address bits, which can vary based on the CPU architecture and emulation status.
613
+
614
+ Simple script to set `LG_VADDR`. Please note that it is provided for illustration only.
615
+
616
+ [source,sh]
617
+ ----
618
+ #!/bin/bash
619
+
620
+ # Check the CPU architecture
621
+ ARCH=$(uname -m)
622
+
623
+ # Check if running under Rosetta 2 emulation
624
+ if [[ "$ARCH" == "x86_64" && $(sysctl -n sysctl.proc_translated) == "1" ]]; then
625
+ echo "Running on Apple Silicon under Rosetta 2 emulation"
626
+ export LG_VADDR=39
627
+ elif [[ "$ARCH" == "arm64" ]]; then
628
+ echo "Running on Apple Silicon"
629
+ export LG_VADDR=39
630
+ else
631
+ echo "Running on Intel Silicon"
632
+ export LG_VADDR=48
633
+ fi
634
+
635
+ echo "Setting lg-vaddr to $LG_VADDR"
636
+ ----
637
+
638
+
639
+ [source,sh]
640
+ ----
641
+ export PATH="$(brew --prefix bison)/bin:$PATH"
642
+ ----
643
+
644
+ ===== Windows
645
+
646
+ ====== General
647
+
648
+ The following instructions work for:
649
+
650
+ * Windows 10, 11
651
+ * Windows Server 2019, 2022
652
+
653
+ ====== Ruby
654
+
655
+ To run Tebako you need to have Ruby installed.
656
+ It is simplest to use the Ruby development environment provided by
657
+ https://rubyinstaller.org[RubyInstaller].
658
+
659
+ For example, Ruby+Devkit 3.1.4-1.
660
+
661
+ ====== MinGW ucrt64
662
+
663
+ Enable MinGW ucrt64 and install the necessary packages.
664
+
665
+ The `ridk` command originates from the RubyInstaller installation.
666
+
667
+ [source,sh]
668
+ ----
669
+ $ ridk enable ucrt64
670
+ $ pacman -S git tar bison flex toolchain make cmake
671
+ boost diffutils libevent double-conversion
672
+ fmt glog dlfcn gtest autotools ncurses libyaml
673
+ ----
674
+
675
+
676
+
677
+ == Packaging
678
+
679
+ === Tebako root folder (aka prefix) selection
680
+
681
+ The Tebako prefix determines the base directory for the Tebako setup.
682
+
683
+ It is an essential part of configuring how Tebako operates within your system.
684
+
685
+ The selection of the Tebako prefix follows a specific order of precedence to
686
+ ensure flexibility and ease of use:
687
+
688
+ . *User-specified prefix*:
689
+ The most direct way to set the root folder is by specifying it through a
690
+ command-line argument.
691
+
692
+ . *Current Working Directory (PWD)*:
693
+ If the prefix option is explicitly set to `PWD`, Tebako uses the current working
694
+ directory as Tebako root folder.
695
+
696
+ . *Environment variable (`TEBAKO_PREFIX`)*:
697
+ In the absence of a user-specified option, Tebako looks for an environment
698
+ variable named `TEBAKO_PREFIX`. If found, its value is used as the root folder.
699
+
700
+ . *Default value*:
701
+ If no prefix is specified and the `TEBAKO_DIR` environment variable is not set,
702
+ Tebako defaults to using a directory named `.tebako` in the user's home
703
+ directory.
704
+
705
+
706
+ Path Expansion: Regardless of the method used to set the Tebako prefix, Tebako
707
+ expands the provided path to an absolute path. This expansion includes resolving
708
+ relative paths based on the current working directory and expanding user
709
+ directory shortcuts like `~`.
710
+
711
+
712
+ === Commands
713
+
714
+ Tebako provides several commands to manage the packaging and deployment process.
715
+
716
+ ==== Press
717
+
718
+ This command "presses" a Ruby project using the Tebako components built in the Tebako
719
+ root folder (`<tebako-root-folder>`).
720
+
721
+
722
+ [NOTE]
723
+ ====
724
+ The first invocation of the `press` command can take up to an hour as it sets up
725
+ the packaging environment and collects the required dependencies. Subsequent
726
+ invocations are much faster.
727
+ ====
728
+
729
+ Upon the next invocation tebako will use previously created packaging
730
+ environment. The press process itself takes minutes.
731
+
732
+ You can manage setup of packaging environment manually; please refer to
733
+ description of setup and clean commands below.
734
+
735
+ [source,sh]
736
+ ----
737
+ tebako press \
738
+ -e|--entry-point=<entry-point> \
739
+ -r|--root=<project-root-folder> \
740
+ [-p|--prefix=<tebako-root-folder>] \
741
+ [-R|--Ruby=<ruby-version>] \
742
+ [-o|--output=<packaged-file-name>] \
743
+ [-l|--log-level=<error|warn|debug|trace>] \
744
+ [-c|--cwd=<package current working directory>]
745
+ [-D|--devmode] \
746
+ [-P|--patchelf] \
747
+ [-t|--tebafile=<path-to-tebafile>]
748
+ ----
749
+
750
+ Where:
751
+
752
+ `<tebako-root-folder>`::
753
+ the Tebako root folder (see details in the Tebako Root Folder Selection section)
754
+
755
+ `Ruby`::
756
+ this parameter defines Ruby version that will be packaged (optional, defaults to
757
+ `3.1.6`)
758
+
759
+ `project-root`::
760
+ a folder at the host source file system where project files are located
761
+
762
+ `entry-point`::
763
+ an executable file (binary executable or script) that shall be started when
764
+ packaged file is called
765
+
766
+ `output`::
767
+ the output file name (optional, defaults to `<current folder>/<entry point base name>`)
768
+
769
+ `log-level`::
770
+ logging level for the Tebako built-in memory filesystem driver
771
+ (optional, defaults to `error`)
772
+
773
+ `cwd`::
774
+ a folder within Tebako memfs where the packaged application will start. This folder should be specified relative to the memfs root.
775
+ If not provided, the application will start within the current folder of the host (i.e., at $PWD).
776
+ This option is required because it is not possible to change the directory to a memfs folder until the package is started, as opposed to any host folder
777
+ that can be set as the current directory before Tebako package invocation. Tebako saves original working directory in a global Ruby variable `$tebako_original_pwd`.
778
+
779
+ `devmode`:: flag that activates development mode, in which Tebako's cache and
780
+ packaging consistency checks are relaxed.
781
+
782
+ `patchelf`::
783
+ flag that removal a reference to GLIBC_PRIVATE version of libpthread from tebako package. This allows Linux Gnu packages to run against versions of
784
+ libpthread that differ from the version used for packaging. For example, package created at Ubuntu 20 system can be used on Ubuntu 22. This option makes
785
+ sense and works on Gnu Linux only. The feature is exeprimental, we may consider other approach in the future.
786
+
787
+ `tebafile`::
788
+ the tebako configuration file (optional, defaults to `$PWD/.tebako.yml`).
789
+ Please refer to the separate section below for tebafile description.
790
+ +
791
+ NOTES:
792
+ * Development mode is *not intended for production use* and should only be used during development.
793
+ * `entry-point` and `project-root-folder` are required parameters and may be provided either via command-line or in `tebafile`.
794
+
795
+ [example]
796
+ ====
797
+ [source,sh]
798
+ ----
799
+ tebako press \
800
+ --root='~/projects/myproject' \
801
+ --entry=start.rb \
802
+ --output=/temp/myproject.tebako
803
+ ----
804
+ ====
805
+
806
+ ==== Setup
807
+
808
+ This command sets up the Tebako packaging environment.
809
+
810
+ Collects required packages, builds the and creates packaging environment. This
811
+ is a lengthy task that can take significant time, up to 1 hour.
812
+
813
+ Tebako supports several configurations at a single system given that their root
814
+ directories differ and multiple Ruby versions within single configuration
815
+
816
+ This command is optional, tebako creates packaging environment automatically
817
+ upon the first invocation of press command.
818
+
819
+ However, if you plan to use tebako in CI/CD environment with caching it is
820
+ highly recommended to build cache based on `tebako setup` output. Building cache
821
+ based on `tebako press` may create inconsistent environment upon restore.
822
+
823
+ [source,sh]
824
+ ----
825
+ $ tebako setup \
826
+ [-p|--prefix=<tebako-root-folder>] \
827
+ [-R|--Ruby=<ruby-version>] \
828
+ [-D|--devmode] \
829
+ [-t|--tebafile=<path-to-tebafile>]
830
+ ----
831
+
832
+ Where:
833
+
834
+ `<tebako-root-folder>`:: the Tebako root folder (see details in the Tebako Root Folder Selection section)
835
+
836
+ `Ruby`:: parameter defines Ruby version that will be packaged (optional, defaults to 3.1.6)
837
+
838
+ `tebafile`::
839
+ the tebako configuration file (optional, defaults to `$PWD/.tebako.yml`).
840
+ Please refer to the separate section below for tebafile description.
841
+
842
+ `devmode`:: flag activates development mode, in which Tebako's cache and packaging consistency checks are relaxed.
843
+ Please note that this mode is not intended for production use and should only be used during development.
844
+
845
+ ==== Clean
846
+
847
+ This command cleans up all Tebako artifacts in the specified prefix directory.
848
+
849
+ NOTE: These artifacts are created by the `setup` and `press` commands.
850
+ Normally you do not need to do it since tebako packager optimizes artifacts lifecycle on its own.
851
+
852
+ [source,sh]
853
+ ----
854
+ $ tebako clean \
855
+ [-p|--prefix=<tebako-root-folder>] \
856
+ [-t|--tebafile=<path-to-tebafile>]
857
+ ----
858
+
859
+ Where:
860
+
861
+ `<tebako-root-folder>`:: the Tebako root folder (see details in the Tebako Root Folder Selection section)
862
+
863
+ `tebafile`::
864
+ the tebako configuration file (optional, defaults to `$PWD/.tebako.yml`).
865
+ Please refer to the separate section below for tebafile description.
866
+
867
+ [example]
868
+ ====
869
+ [source,sh]
870
+ ----
871
+ tebako clean --prefix='~/.tebako'
872
+ ----
873
+ ====
874
+
875
+
876
+ ==== Clean Ruby
877
+
878
+ This command cleans up only the Ruby artifacts from the specified prefix
879
+ directory.
880
+
881
+ NOTE: These artifacts are created by the `setup` and `press` commands.
882
+ Normally you do not need to do it, since Tebako packager optimizes artifacts
883
+ lifecycle on its own.
884
+
885
+ NOTE: Compiled DwarFS libraries are not cleaned.
886
+
887
+ [source,sh]
888
+ ----
889
+ $ tebako clean_ruby
890
+ [-p|--prefix=<tebako-root-folder>] \
891
+ [-R|--Ruby=<ruby-version>] \
892
+ [-t|--tebafile=<path-to-tebafile>]
893
+
894
+ ----
895
+
896
+ Where:
897
+
898
+ `<tebako-root-folder>`::
899
+ the Tebako setup folder (optional, defaults to current folder)
900
+
901
+ `Ruby`::
902
+ defines Ruby version that will cleaned (optional, cleans all versions by default)
903
+
904
+ `tebafile`::
905
+ the tebako configuration file (optional, defaults to `$PWD/.tebako.yml`).
906
+ Please refer to the separate section below for tebafile description.
907
+
908
+ [example]
909
+ ====
910
+ [source,sh]
911
+ ----
912
+ tebako clean_ruby --prefix='~/.tebako'
913
+ ----
914
+ ====
915
+
916
+ ==== Build script hash
917
+
918
+ This command outputs a hash value for the Tebako build script, which can be used
919
+ as a cache key in CI/CD pipelines.
920
+
921
+ [source,sh]
922
+ ----
923
+ $ tebako hash
924
+ ----
925
+
926
+ === Tebako configuration file
927
+
928
+ It is possible to provide all or some options for the `tebako setup/press/clean/clean_ruby` commands via Tebako configuration file ('tebafile').
929
+ Tebafile is a YAML file with a single section 'options'. The options are the same as long names for the command line. For, example for the prefix option
930
+
931
+ [source]
932
+ ----
933
+ -p|--prefix=<tebako-root-folder>
934
+ ----
935
+ the key in the YAML file would be 'prefix'.
936
+
937
+ Below is an example tebafile that sets values for prefix and Ruby options
938
+ [source,yaml]
939
+ ----
940
+ options:
941
+ prefix: /tmp/tebako
942
+ Ruby: 3.2.4
943
+ ----
944
+
945
+ Please note that the options provided on the command line have preference over tebafile settings.
946
+
947
+ === Exit codes
948
+
949
+ The Tebako CLI exits with different exit codes to indicate the status of the
950
+ operation. The following table lists the possible exit codes and their meanings.
951
+
952
+ .Tebako CLI exit codes
953
+ [cols="a,a"]
954
+ |===
955
+ | Code | Condition
956
+
957
+ | 0 | No error
958
+ | 1 | Invalid command line
959
+ | 101 | `tebako setup` failed at configuration step
960
+ | 102 | `tebako setup` failed at build step
961
+ | 103 | `tebako press` failed at configuration step
962
+ | 104 | `tebako press` failed at build step
963
+ | 253 | Unsupported Ruby version
964
+ | 254 | Unsupported operating systems
965
+ | 255 | Internal error
966
+
967
+ |===
968
+
969
+
970
+ == Packaging scenarios with Ruby
971
+
972
+ Tebako for Ruby supports the following packaging scenarios.
973
+
974
+ This is high-level description of the Tebako Ruby packaging mechanism.
975
+
976
+ NOTE: These scenarios were inspired by the `ruby-packer` approach.
977
+
978
+ NOTE: Tebako Ruby is created independently from `ruby-packer`, no line of code
979
+ was copied from `ruby-packer`.
980
+
981
+ Depending on the configuration files that are present in the root project folder, the Tebako Ruby packager supports different packaging scenarios.
982
+
983
+ These scenarios differ in what files are packaged and where the entry point is located.
984
+
985
+ Here is a summary of the scenarios:
986
+
987
+ [cols="a,2a,4a,3a,a,a,a"]
988
+ |===
989
+ | Scenario | Description | Packaging | Entry point | `*.gemspec` | `Gemfile` | `*.gem`
990
+
991
+ | 1
992
+ | Simple ruby script
993
+ | Copy `<project-root>` with all sub-folders to packaged filesystem
994
+ | `<mount_point>/local/<entry_point base name>`
995
+ | No
996
+ | No
997
+ | No
998
+
999
+
1000
+ | 2
1001
+ | Packaged gem
1002
+ | Install the gem with `gem install` to packaged filesystem
1003
+ | `<mount_point>/bin/<entry_point base name>` (i.e., binstub is expected)
1004
+ | No
1005
+ | No
1006
+ | One
1007
+
1008
+
1009
+ | 3
1010
+ | Gem source, no `bundler`
1011
+ |
1012
+ . Build the gem using `gem build` command at the host
1013
+ . Install it with `gem install` to packaged filesystem
1014
+
1015
+ | `<mount_point>/bin/<entry_point base name>` (i.e., binstub is expected)
1016
+ | One
1017
+ | No
1018
+ | Any
1019
+
1020
+
1021
+ | 4
1022
+ | Gem source, `bundler`
1023
+ |
1024
+ . Collect dependencies at the host with `bundle install`
1025
+ . Build the gem using `gem build` command
1026
+ . Install it with `gem install` to packaged file system
1027
+
1028
+ | `<mount_point>/bin/<entry_point base name>` (i.e., binstub is expected)
1029
+ | One
1030
+ | One
1031
+ | Any
1032
+
1033
+
1034
+ | 5
1035
+ | Rails project
1036
+ | Deploy project to packaged filesystem using `bundle install`
1037
+ | `<mount_point>/local/<entry_point base name>`
1038
+ | No
1039
+ | One
1040
+ | Any
1041
+
1042
+
1043
+ | Error
1044
+ | Error: Two or more `*.gem` files present
1045
+ | -
1046
+ | -
1047
+ | No
1048
+ | No
1049
+ | Two or more
1050
+
1051
+
1052
+ | Error
1053
+ | Error: Two or more `*.gemspec` files present
1054
+ | -
1055
+ | -
1056
+ | Two or more
1057
+ | Any
1058
+ | Any
1059
+
1060
+ |===
1061
+
1062
+ These scenarios determine how the project is packaged and where the entry point is located within the packaged filesystem.
1063
+
1064
+ == Run-time options
1065
+
1066
+ Generally Tebako package passes command line options to the packaged application
1067
+
1068
+ [example]
1069
+ ====
1070
+ For example, if the package was created with the following command
1071
+
1072
+ [source,sh]
1073
+ ----
1074
+ tebako press \
1075
+ --root='~/projects/myproject' \
1076
+ --entry=start.rb \
1077
+ --output=/temp/myproject.tebako
1078
+ ----
1079
+ running
1080
+
1081
+ [source,sh]
1082
+ ----
1083
+ /temp/myproject.tebako --option --parameter value
1084
+ ----
1085
+
1086
+ will be translated by Tebako bootstrap code to
1087
+
1088
+ [source,sh]
1089
+ ----
1090
+ myproject --option --parameter value
1091
+ ----
1092
+ ====
1093
+
1094
+ However there are several command-line parameters that are intercepted processed by Tebako bootstrap code as follows
1095
+
1096
+ === Image extraction (--tebako-extract option)
1097
+
1098
+ Tebako provides an option to an extract its DwarFS filesystem from a package to
1099
+ a local folder for verification or execution.
1100
+
1101
+ [source,sh]
1102
+ ----
1103
+ $ <tebako-packaged-executable> --tebako-extract [<root folder for extracted filesystem>]
1104
+ ----
1105
+
1106
+ Where,
1107
+
1108
+ `<root folder for extracted filesystem>`::
1109
+ The root folder for the extracted filesystem (optional, defaults to `source_filesystem`)
1110
+
1111
+ [example]
1112
+ ====
1113
+ Extracting Tebako content from the `metanorma` package:
1114
+
1115
+ [source,sh]
1116
+ ----
1117
+ metanorma --tebako-extract temp-image
1118
+ ----
1119
+ ====
1120
+
1121
+ The `--tebako-extract` option actually runs the following Ruby script:
1122
+
1123
+ [source,ruby]
1124
+ ----
1125
+ require 'fileutils'
1126
+ FileUtils.copy_entry '<in-memory filesystem root>', ARGV[2] || 'source_filesystem'
1127
+ ----
1128
+
1129
+ === Mounting Host Folder to Tebako Memfs (`--tebako-mount` option)
1130
+
1131
+ Some programs unconditionally use folders located under the application root, and when processed by Tebako
1132
+ or similar tools, these folders are included in the packaging.
1133
+
1134
+ For example, there is no configuration option to change where Rails expects the `tmp` folder to be.
1135
+ The location is hardcoded in multiple places within the Rails codebase, residing under the application root,
1136
+ and as a result, it gets included in the read-only Tebako memfs. Although patches have been proposed
1137
+ (e.g., https://github.com/rails/rails/issues/39583), there is currently no way to change the paths for
1138
+ temporary files, caches, and sockets.
1139
+
1140
+ To address this limitation in Rails and similar issues in other applications, Tebako provides an option
1141
+ to mount a host folder to the memfs tree.
1142
+
1143
+ When using Tebako, consider the packaging scenario mentioned above, as it defines the layout of the application
1144
+ tree. The `--tebako-extract` option may be useful for understanding the placement of files and folders.
1145
+
1146
+ [example]
1147
+ ====
1148
+ The following command starts a `rails.tebako` package with `$PWD/tmp` mounted as `local/tmp` in the memfs.
1149
+ Any remaining command-line parameters are passed to the application.
1150
+ [source,sh]
1151
+ ----
1152
+ rails.tebako --tebako-mount local/tmp:$PWD/tmp server
1153
+ ----
1154
+ ====
1155
+
1156
+ The `--tebako-mount` option has the following syntax:
1157
+ [source,sh]
1158
+ ----
1159
+ --tebako-mount <memfs path>:<host path>
1160
+ ----
1161
+
1162
+ The `--tebako-mount` option can be repeated multiple times to mount more than one object. The `memfs path`
1163
+ is relative to the memfs root, and it is recommended to use absolute paths for host objects. Both directories
1164
+ and files can be mounted in this way. Tebako allows overlaying existing memfs objects, so there are no significant
1165
+ limitations.
1166
+
1167
+ == Trivia: origin of name
1168
+
1169
+ "tamatebako" (玉手箱) is the treasure box given to Urashima Taro in the Ryugu,
1170
+ for which he was asked not to open if he wished to return. He opened the box
1171
+ upon the shock from his return that three hundred years has passed. Apparently
1172
+ what was stored in the box was his age.
1173
+
1174
+ This packager was made to store Ruby and its gems, and therefore named after
1175
+ the said treasure box (storing gems inside a treasure box).
1176
+
1177
+ Since "tamatebako" is rather long for the non-Japanese speaker, we use "tebako"
1178
+ (手箱, also "tehako") instead, the generic term for a personal box.
1179
+
1180
+ == Contributing
1181
+
1182
+ We welcome contributions! Please see our contributing guidelines for more
1183
+ information.
1184
+
1185
+ == License
1186
+
1187
+ Copyright Ribose. All rights reserved.
1188
+
1189
+ Tebako is released under the BSD 2-Clause License. See the LICENSE file for details.