tebako 0.9.3 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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.