-
Notifications
You must be signed in to change notification settings - Fork 14
/
Copy pathdue
executable file
·1602 lines (1417 loc) · 55.4 KB
/
due
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
#!/bin/bash
# SCRIPT_PURPOSE: Dedicated User Environment CLI
# Copyright 2021-2024 NVIDIA Corporation. All rights reserved.
# Copyright 2019,2020 Cumulus Networks, Inc. All rights reserved.
#
# SPDX-License-Identifier: MIT
###################################################################
#
# SHELLCHECK
# Checked with shellcheck -s bash -x $0
#
###################################################################
# If a piped operation fails, die on the first error.
set -o pipefail
INSTALLED_DUE_PATH="/usr/bin/due"
INSTALLED_DUE_DIR="/usr/share/due"
LIBRARY_FILE="/usr/lib/libdue"
IMAGE_PATCH_DIR="/usr/share/due/image-patches"
# Set user's default home directory
DUE_ENV_DEFAULT_HOMEDIR="$HOME"
DUE_CONFIG_SOURCING_SUMMARY=""
if [ "$0" != "$INSTALLED_DUE_PATH" ];then
if [ -e ./libdue ] && [ -e ./due ];then
# If both files are in the same directory,
# it is probably running from a source checkout
# should use the library from the current
# directory, rather than the installed one.
TOP_LEVEL_DIR=$(pwd)
LIBRARY_FILE="${TOP_LEVEL_DIR}/libdue"
IMAGE_PATCH_DIR="${TOP_LEVEL_DIR}/image-patches"
# Let the user know they're using the local copy.
DUE_CONFIG_SOURCING_SUMMARY="\n==== Sourcing DUE files from: [ $TOP_LEVEL_DIR ]"
DUE_CONFIG_SOURCING_SUMMARY+="\n==== due: [ $0 ]"
DUE_CONFIG_SOURCING_SUMMARY+="\n==== libdue: [ $LIBRARY_FILE ]"
DUE_CONFIG_SOURCING_SUMMARY+="\n"
#echo "==== Sourcing DUE files from: [ $TOP_LEVEL_DIR ]"
else
echo "ERROR! Cannot run $0. Missing files. Exiting."
exit 1
fi
fi
if [ ! -e "$LIBRARY_FILE" ];then
echo "ERROR! Failed to find [ $LIBRARY_FILE ]. Exiting."
exit 1
fi
# Source the installed or checked out version of libdue
# If running shellcheck, point it to the checked out version.
# shellcheck source=./libdue
. "$LIBRARY_FILE"
# Verbosity level. 0 is terse.
VERBOSITY_LEVEL=0
DUE_NAME=$( basename "$0" )
# DUE has two pathing modes
# 1 - using system installed copy
# 2 - using a checkout or build environment locally.
#
# If 2 - then all paths are local to the current directory, assuming
# the user is doing development and wants the local to override the
# currently installed version.
#
# TOP_LEVEL_DIR will be set appropriately.
# Short description of the code
function fxnHelpAbout()
{
# print how to get to this help
if [ "$1" = "invocation" ];then
echo "$DUE_NAME --help-about Overview of what DUE does."
return
fi
echo ""
echo " About DUE:"
echo ""
echo " DUE (Dedicated User Environment) is a collection of Bash functions to simplify"
echo " the process of creating a Docker Image that can be used for software development"
echo " for any Linux that has supplied an image."
echo " If you are new to Docker:"
echo " Image = effectively a configured file system in a file on disk."
echo " Container = a running instance of an Image."
echo ""
}
# Top level help
function fxnHelp ()
{
# print how to get to this help
if [ "$1" = "invocation" ];then
echo "$DUE_NAME --help Top level help."
return
fi
echo ""
echo " Usage: $DUE_NAME [ option ]"
echo ""
echo " DUE is a wrapper application that uses Docker containers as build environments."
echo ""
echo " -c | --create Build an image using configuration from DIR"
echo " --delete <term> Generate a script to delete all images containing <term> "
echo " -r | --run Select image to run from a menu."
echo " --build Shortcut to run the container's duebuild script."
echo " --duebuild Same as --build but takes --help to print a container's duebuild help."
echo " -m | --manage Manage existing images and containers."
echo " -v | --verbose Print extra information when running."
echo " --version Print version of DUE."
echo ""
echo " -h | --help Top level help (this message)."
echo " --help <command> Command level help if command is one of:"
echo " [--build|--manage|--create|--run]"
echo " --help-examples Specific examples of use when used with the arguments above."
echo " --help-topics Summary of all help sections, with access instructions."
echo " --help-about A description of what DUE can do."
echo " --help-env-vars Bash environment variables DUE will use."
echo " --help-all Print ALL THE HELP!"
echo ""
}
#
# A top level help examples to go with top level help.
#
function fxnHelpExamples()
{
echo "############################################################################"
echo "#"
echo "# DUE examples:"
echo "#"
echo "############################################################################"
echo""
echo "Build from a source directory, using a container's duebuild script."
echo " $0 --build"
echo ""
echo " Log into a running container:"
echo " $0 --login"
echo ""
echo " Run a commands in a specific container:"
echo " $0 --run-image due-pkg-sid:pkg-sid --command ls -l \; cat /etc/os-release "
echo ""
echo " Print a container's duebuild help:"
echo " $0 --help --duebuild "
echo ""
echo "See topic specific help for topic specific examples."
echo " Ex: $0 --help-examples --build"
echo ""
echo " Debug a failed container build through running it."
echo " $0 --run --debug --all --login-shell /bin/bash --login"
echo ""
echo " Run a non-DUE container interactively to debug it."
echo " $0 --run --debug "
echo ""
echo " Create a DUE image from a menu."
echo " $0 --create --menu "
echo ""
echo " Create a DUE image from a menu that has been filtered to show only debian."
echo " $0 --create --menu --filter debian "
echo ""
}
# Help with managing existing images, containers, templates
function fxnHelpManage()
{
if [ "$1" = "invocation" ];then
echo "$DUE_NAME --manage --help Utility functions for container management."
return
fi
echo "############################################################################"
echo "#"
echo "# Help for: --manage "
echo "#"
echo "############################################################################"
echo " Utility functions to make development and use of DUE easier."
echo ""
echo " Usage: $DUE_NAME --manage [ option ]"
echo ""
echo " -l | --list-images List images created by DUE."
echo " --export-container <name> Save a running container as a Docker image named [name]"
echo " --export-image <name> Export a docker image as a file. [name] is optional."
echo " --import-image <name> Import Docker image file named [name]"
echo ""
echo " --browse <registry > Browse a docker registry. Ex: due --manage --browse localhost:5000"
echo ""
echo " --copy-config Create a personal DUE configuration file in ~/.config/due/due.config"
echo " --make-dev-dir <dir> Populate a local directory for DUE container development."
echo " --list-templates List available templates."
echo " --docker-clean Run 'docker system prune ; docker image prune' to reclaim disk space."
echo ""
echo " --stop <match> Stop a running container. Optional pattern <match>"
echo " --delete-matched [term] Delete images that contain this term. USE WITH CAUTION!"
echo ""
echo " --help This help."
echo " --help-examples Examples of using management options."
echo ""
}
# Example usage of management commands
function fxnHelpManageExamples()
{
if [ "$1" = "invocation" ];then
echo "$DUE_NAME --manage --help-examples Management use cases."
return
fi
echo "############################################################################"
echo "#"
echo "# Help: example commands for: --manage "
echo "#"
echo "############################################################################"
echo ""
echo " To delete containers that failed to create:"
echo " $DUE_NAME --manage --delete-matched none "
echo " Safety tip: don't put 'none' in your container names!"
echo ""
echo " Stop containers you left running:"
echo " $DUE_NAME --manage --stop "
echo ""
echo " Stop all my package build containers with a script:"
echo " $DUE_NAME --manage --stop pkg "
echo ""
echo " Save the current state of a container as an image on disk."
echo " $DUE_NAME --manage --export-container myNewImage "
echo ""
echo " Export a Docker image to disk."
echo " $DUE_NAME --manage --export-image imageFile "
echo ""
echo " Import a Docker image."
echo " $DUE_NAME --manage --import-image imageFile "
echo ""
echo " Clean the image build area "
echo " $DUE_NAME --manage --clean"
echo ''
}
# Help with creating containers, images, directories
# TAKES:
# invocation - help just on running
# or argument to filter examples with
function fxnHelpCreate()
{
local exampleFilter
exampleFilter="$1"
if [ "$exampleFilter" = "invocation" ];then
echo "$DUE_NAME --create --help Make new containers and configuration directories."
return
fi
# Lots of examples can be generated - allow a filter term
exampleFilter="$1"
echo "############################################################################"
echo "#"
echo "# Help for: --create "
echo "#"
echo "############################################################################"
echo " Create or delete Docker images used to build for particular targets"
echo " or different Linux releases, provided you can find a container for it."
echo ""
echo " Usage: $DUE_NAME --create [ option ]"
echo ""
echo " Image management options:"
echo ""
echo " Use the example menu to create a particular image."
echo " --menu Choose from the creation examples in the README.md files under the templates directory."
echo ""
echo " OR"
echo ""
echo " 1 - Configure an image build directory under due-build-merge named from --name"
echo " Mandatory:"
echo " --from <name:tag> Pull name:tag from registry to use as starting point for the image."
echo " --use-template <role> Use files from templates/<role> to generate the config directory."
echo " --description \"desc\" Quoted string to describe the container on login."
echo " --name <name> Name for resulting image and config directory."
echo " Ex: debian-stretch-build, ubuntu-18.04-build, etc"
echo " Optional:"
echo " --platform <os/arch> Specify that the image has architecture different from host."
echo " Ex: linux/aarch64"
echo " --prompt <prompt> Set in container prompt to <prompt> to provide user context"
echo " --image-patch <path> Apply files under $IMAGE_PATCH_DIR/<path> to the image build before "
echo " template code runs. Useful for fixing older containers."
echo " --no-image Allow build directory to be created. Do not build the image."
echo ""
echo " 2 - Build a Docker image from the image build directory."
echo ""
echo " --build-dir <dirname> Build using an existing configuration directory."
echo " --dockerarg <arg> Pass <arg> to the Docker build invocation."
echo " Use multiple times for multiple args, or pass one long quoted string."
echo ""
echo " --clean Remove due-build-merge directory."
echo " --help This help."
echo " --filter <term> With --help, filter output to contain <term>"
echo " --create --help-examples Examples of using create."
echo ""
echo ""
# show local image creation configurations
fxnListContainersForCreation 'standard' "$exampleFilter"
echo ""
}
function fxnHelpCreateExamples()
{
if [ "$1" = "invocation" ];then
echo "$DUE_NAME --create --help-examples Container and config use cases."
return
fi
echo "############################################################################"
echo "#"
echo "# Help: example commands for: --create"
echo "#"
echo "############################################################################"
# show local image creation configurations
fxnListContainersForCreation 'standard' "$exampleFilter"
echo ""
echo " Ex: clean container creation work area."
echo " $0 --create --clean"
echo ""
echo " Ex: filter creation examples to only show those containing 'foo' "
echo " $0 --create --help --filter foo"
echo ""
echo " Ex: pass proxy arguments to Docker build, using --create and --dockerarg:"
echo " $0 --create --from debian:10 --description 'Debian 10 example' --name example-debian-10 \\ "
echo " --prompt Ex --tag example-debian-10 --use-template example \\ "
echo " --dockerarg '--build-arg HTTP_PROXY=http://10.20.30.2:1234' \\ "
echo " --dockerarg ' --build-arg FTP_PROXY=http://40.50.60.5:4567' \\ "
echo ""
echo " Ex: Create a Debian 9 image and apply container patches"
echo " $0 --create --platform linux/amd64 --name test-debian-9 \\ "
echo " --prompt test-9 --tag test --use-template debian-package \\ "
echo " --from debian:stretch --description 'test Debian 9' \\ "
echo " --image-patch debian/9/filesystem/"
echo ""
echo " Ex: Create an image using the --menu option and filter for fedora only"
echo " $0 --create --menu --filter fedora \\ "
echo ""
}
# Image management options
#
# help with running the containers you've already created
#
function fxnHelpRun()
{
if [ "$1" = "invocation" ];then
echo "$DUE_NAME --run --help Running the images you created."
return
fi
echo "############################################################################"
echo "#"
echo "# Help for: --run "
echo "#"
echo "############################################################################"
echo ""
echo " Usage: $DUE_NAME --run [ option ]"
echo " If no option is supplied, a menu of images to run will be provided."
echo ""
echo " Specify how to run an image or log into an existing container."
echo ""
echo " Run time options:"
echo ""
echo " Image selection:"
echo " <default> Select image to run from a menu."
echo " --all Do not filter list of available containers."
echo " --ignore-type Treat container as if it was not made by DUE."
echo " --debug Debug partially built container. Defaults to setting:"
echo " --any --username root --userid 0"
echo " -i | --run-image <filter> Restrict shown images to those that match *filter*."
echo " If only one image matches a line from due --list-images"
echo " it will be run automatically."
echo " --entrypoint <shell> Override container's ENTRYPOINT. Defaults to create user if no shell path passed."
echo ""
echo " Image commands:"
echo " -c | --command <cmd> <cmd> will be executed by --login-shell in the container"
echo " NOTE: this must be the last argument, as everything after"
echo " --command will be interpreted as the command."
echo " NOTE2: Quote \"\" your arguments if using multiple commands!"
echo " NOTE3: \ any ; so everything after the ; goes to DUE"
echo " --build Invoke container's /usr/local/bin/duebuild script"
echo " (if present in container) in current directory."
echo " --duebuild Same as --build, but appending --help will run"
echo " 'duebuild --help' in the container you select."
echo " --container-name <n> Change the name of the container to <n>"
echo ""
echo " Pass commands to Docker/Podman:"
echo " --dockerarg <arg> <arg> will be applied directly to the Docker invocation."
echo " use multiple times for multiple args."
echo ""
echo " Host directories to mount in the container:"
echo " --home-dir < path> Absolute path on host system to mount as container user home directory"
echo " Default: $DUE_ENV_DEFAULT_HOMEDIR"
echo " Pass 'container' as path to use home dir that comes with the container."
echo " --mount-dir <hp:cp> Mount absolute path to host directory hp at location cp in container."
echo " Ex: mount host /tmp in container /var/build: --mount-dir /tmp:/var/build "
echo ""
echo " Log in to an active container:"
echo " -l | --login Choose existing running container to log in to."
echo " -a | --all Log into any container as root using sh"
echo ""
echo " Log in as a particular user:"
echo " --username <username> Name to use when logging in. Default: $USER_NAME"
echo " --userid <id#> User ID to use when logging in. Default: $USER_ID"
echo " --groupname <groupname> Container user's default group Default: $USER_GROUP_NAME"
echo " --groupid <id#> ID of container user's group Default: $USER_GROUP_ID"
echo " --login-shell <path> Program to use as login Default: $LOGIN_SHELL"
echo ""
echo ""
echo " Help:"
echo " --help --run This message."
echo " --run --help-examples Show examples of use."
echo ""
}
#
# Examples of run time use
#
function fxnHelpRunExamples()
{
if [ "$1" = "invocation" ];then
echo "$DUE_NAME --run --help-examples Container run time use cases."
return
fi
echo "############################################################################"
echo "#"
echo "# Help: example commands for: --run "
echo "#"
echo "############################################################################"
echo ""
echo " Log into a container as current user: "
echo " ...with host home directory mounted as home directory in the container."
echo " $DUE_NAME --run "
echo ""
echo " ...with /var/lib/build as home directory."
echo " $DUE_NAME --run --home-dir /var/lib/build "
echo ""
echo " ...mount additional host system directory 'work-dir' in the container at /build"
echo " $DUE_NAME --run --mount-dir /home/$(whoami)/work-dir/:/build"
echo ""
echo " Log into a container as user ufoo"
echo " ...and use the container home dir "
echo " $DUE_NAME --run --username ufoo --home-dir container"
echo ""
echo " Log into a container that is already running:"
echo " $DUE_NAME --login <select from menu>"
echo ""
echo " Run a command in a container, where anything after --command is "
echo " passed to a shell in the container."
echo " Ex: print current directory, and list contents"
echo " $DUE_NAME --run --command pwd \; ls -l /"
echo ""
echo " Get help for the duebuild script in a container you will choose."
echo " $DUE_NAME --duebuild --help"
echo ""
echo " Run the following without logging in to the container:"
echo " - Image due-package-debian-10:latest. "
echo " - Debian package build program duebuild."
echo " - Mount build directory /home/username/mypackage in the container at /build."
echo " - Set a development version string of ~789 in the version."
echo " - ...and build source packages too."
echo " $DUE_NAME --run --run-image due-package-debian-10:latest --command duebuild \\"
echo " --use-directory /home/username/mypackage/ \\"
echo " --build --dev-version ~789 --source"
echo ""
echo " Build an RPM from source without logging in to the container."
echo " $DUE_NAME --build --cbuild foo.src.rpm"
echo ""
echo " Override a container's entrypoint:"
echo " - For interactive login as host user in the container."
echo " $0 --run --entrypoint"
echo " - To debug a container."
echo " $0 --run --debug --entrypoint /bin/sh "
echo ""
echo ""
}
#
# As additional environment configuration files are added, update them here.
#
function fxnHelpEnvironmentVariables()
{
if [ "$1" = "invocation" ];then
echo "$DUE_NAME --help-env-vars Environment variables DUE will use."
return
fi
echo " DUE will use the following Bash environment variables:"
echo "--------------------------------------------------------"
echo "DUE_ENV_DEFAULT_HOMEDIR Set to host path to use for user's container home directory."
echo ""
}
#
# print every help function
# Takes: If $1 = invocation, then each help topic will just print
# a summary and how to invoke it.
#
function fxnPrintAllHelp()
{
fxnHeader " All help topics."
if [ "$1" = "invocation" ];then
echo "$DUE_NAME --help-all Print all help."
fi
fxnHelp "$1"
fxnHelpAbout "$1"
fxnHelpEnvironmentVariables "$1"
# Print headers to break up large blocks of text if
# a summary is NOT being printed
if [ "$1" != "invocation" ];then
fxnHeader " --manage help topics "
echo ""
fi
fxnHelpManage "$1"
fxnHelpManageExamples "$1"
if [ "$1" != "invocation" ];then
fxnHeader " --create help topics "
echo ""
fi
fxnHelpCreate "$1"
fxnHelpCreateExamples "$1"
if [ "$1" != "invocation" ];then
fxnHeader " --run help topics "
echo ""
fi
fxnHelpRun "$1"
fxnHelpRunExamples "$1"
echo ""
}
# Takes - a string that may be a command option.
# Check if the term passed data, rather than a command option.
# Since argument parsing functions default to assuming arguments are --options,
# this function looks for exceptions and returns TRUE if found, as returning
# TRUE or FALSE answers 'argument is data?'
function fxnArgIsData()
{
if [ "$1" = "" ];then
# No argument = not data
echo "FALSE"
elif [[ "$1" = --* ]];then
# if it starts with --, it is an option.
echo "FALSE"
else
# Whatever is left is considered data.
echo "TRUE"
fi
}
# Takes - rest of command line after --create
function fxnParseCreateArgs()
{
while [[ $# -gt 0 ]]
do
term="$1"
case $term in
# Parse any help requests first, as they'll result in exit
--help-examples | help-examples)
# Command use to create containers
DO_CREATE_EXAMPLES="TRUE"
;;
--help | -h | help )
DO_CREATE_HELP="TRUE"
;;
-c | --create )
# If the local directory has been created, just build it.
# name of local directory. Its easy to
# auto complete the path, just strip any '/' to go from
# path to image name
if [ "$2" = "" ];then
DO_CREATE_HELP="TRUE"
fi
;;
-m | --menu )
# Create an image from examples pulled from README.md files
DO_MENU_CREATION='TRUE'
# Fall through to create
DO_CREATE_NEW_IMAGE='TRUE'
;;
--clean | clean )
# remove the build directory
DO_CREATE_CLEAN="TRUE"
# nothing else to parse after this
break
;;
#
# use a directory that has already been generated
#
--build-dir )
if [ ! -d "$2" ];then
fxnHelpCreate
fxnERR "Configuration [ $2 ] does not exist. See ./due --create --help-examples. Exiting."
echo "Current configuration directories:"
fxnListContainersForCreation 'JustDirs'
exit 1
fi
BASE_NAME=$( basename "$2" )
# Sanitize the image name to not contain illegal characters
NEW_IMAGE_NAME="$( echo "$BASE_NAME" | tr -d '/')"
FROM_IMAGE_TYPE=$( grep "FROM" "$2"/Dockerfile.create | sed -e 's/FROM //g' | tr ":" "-" | tr "/" "-" )
DO_CREATE_NEW_IMAGE="TRUE"
shift
;;
--image-patch )
# Add files to the image before the template code does.
# This allows for patching broken source images
# An example of this is the apt/sources.list file for Debian 9 images where the package
# repositories have been archived, and the sources.list has become invalid.
if [ ! -e "${IMAGE_PATCH_DIR}/$2" ];then
fxnERR "--image-patch directory [ $2 ] does not exist under [ ${IMAGE_PATCH_DIR} ]. Exiting."
exit 1
fi
IMAGE_PATCH_PATH="$(realpath "${IMAGE_PATCH_DIR}/$2")"
shift
;;
--no-image )
# Do not run the Dockerfile create, but generate all directories up to
# that point.
DO_CREATE_IMAGE_NOW="FALSE"
;;
--from )
# If the local directory has not been created, then do all
# this other stuff.
if [ "$2" = "" ];then
echo "Possible source images:"
echo "$KNOWN_IMAGES"
exit
fi
FROM_IMAGE_TYPE="$2"
if [ "$IMAGE_DESCRIPTION" = "" ];then
IMAGE_DESCRIPTION="$2 Image"
fi
DO_CREATE_DIRECTORY="TRUE"
shift
;;
--description )
# String to describe the image being created
IMAGE_DESCRIPTION="$2"
shift
;;
--name )
# Name of this new image ( stretch-build, etc )
NEW_IMAGE_NAME="$2"
if [[ $NEW_IMAGE_NAME =~ [A-Z] ]];then
fxnERR "--name Docker image name [ $NEW_IMAGE_NAME ] must be lower case only."
exit 1
fi
shift
;;
--prompt )
# Set the in container prompt to have this to provide the
# user with some context.
NEW_PROMPT="$2"
shift
;;
--platform )
# Specify an image os/architecture different from the host system.
# Ex: linux/aarch64 to get an ARMV8 version of a container.
PLATFORM="$2"
shift
;;
--tag )
# optional version tag for image
DOCKER_IMAGE_TAG="$2"
if [[ $DOCKER_IMAGE_TAG =~ [A-Z] ]];then
fxnERR "--tag Docker image tag [ $DOCKER_IMAGE_TAG ]must be lower case only."
exit 1
fi
shift
;;
--dockerarg )
# Append additional argument to pass through to docker build
# $2 should be passed as a quoted string
DOCKER_SPECIFIC_BUILD_ARGS+=" $2 "
shift
;;
--use-template )
if [ "$2" = "" ];then
echo ""
echo " --use-template "
echo " ...will take one of the following from $SPECIFIC_TEMPLATE_PATH"
echo ""
fxnEC cd "$SPECIFIC_TEMPLATE_PATH" || exit 1
# list directories and strip ./ to just print as strings that would be passed.
find ./* -maxdepth 0 -type d | sed -e 's#./##g'
echo ""
exit 1
fi
# use this template directory to create the container config
MERGE_IN_TEMPLATE_PATH="$2"
# The whole path is acceptable
if [ ! -e "$2" ];then
# or prepend the templates to the path.
if [ -e "${SPECIFIC_TEMPLATE_PATH}"/"$2" ];then
MERGE_IN_TEMPLATE_PATH="${SPECIFIC_TEMPLATE_PATH}/$2"
fxnPP "Setting --use-template path to $MERGE_IN_TEMPLATE_PATH"
else
# The target may be nested under /sub-type/ directories, in
# which case the merged template will be the contents of a
# series of sub-type directories merged together.
MERGE_IN_TEMPLATE_PATH="$( find "$SPECIFIC_TEMPLATE_PATH" -name "$MERGE_IN_TEMPLATE_PATH" )"
if [ ! -e "$MERGE_IN_TEMPLATE_PATH" ];then
fxnERR "Failed to find template directory [ $2 ] or [ $SPECIFIC_TEMPLATE_PATH ]. Exiting."
echo "Possible choices:"
# give them a hint
ls -1 "$SPECIFIC_TEMPLATE_PATH"
echo ""
exit 1
else
echo "Found $MERGE_IN_TEMPLATE_PATH"
fi
fi
fi
shift
;;
-f | --filter )
# Take term to filter example output with
HELP_EXAMPLE_FILTER+="$2"
shift
;;
* )
fxnHelpCreate
if [ "$term" != "" ];then
# Flag bad arguments
echo "Unrecognized --create argument [ $term ]"
fi
exit 1
;;
esac
# next argument
shift
done
if [ "$DO_CREATE_HELP" = "TRUE" ];then
fxnHelpCreate "$HELP_EXAMPLE_FILTER"
exit
fi
if [ "$DO_CREATE_EXAMPLES" = "TRUE" ];then
fxnHelpCreateExamples "$HELP_EXAMPLE_FILTER"
exit
fi
}
#
# Run time commands
#
#
# Run the help command for the duebuild script in a container that the
# user will select.
function fxnDueBuildHelp()
{
theHelp="$1"
fxnPP "Select a container to run 'duebuild --help' in:"
due --run --command duebuild "$theHelp"
}
function fxnParseRunArgs()
{
# If TRUE, the argument does not start with -- and it is data
local nextArgIsData
while [[ $# -gt 0 ]]
do
term="$1"
# Expect TRUE or FALSE here
nextArgIsData=$( fxnArgIsData "$2")
case $term in
# Parse any help requests first, as they'll result in exit
-h | --help | help )
if [ "$2" = "--duebuild" ];then
# looking for a container's duebuild script help
fxnDueBuildHelp "--help"
else
fxnHelpRun
fi
exit
;;
--help-examples | help-examples )
if [ "$2" = "--duebuild" ];then
# looking for a container's duebuild script help
fxnDueBuildHelp "--help-examples"
else
fxnHelpRunExamples
fi
exit
;;
-r | --run )
# run an image that has already been configured.
# select via a menu
DO_RUN_IMAGE="TRUE"
;;
-i | --image | --run-image )
# run an image that has already been configured
# Second parameter is the name of the image to use
DO_RUN_IMAGE="TRUE"
USE_IMAGE_NAME="$2"
# if an image is being specified, there is no need
# to filter further
FILTER_SHOW_ONLY_DUE="FALSE"
shift
;;
--entrypoint )
# Override a container's ENTRYPOINT for interactive login.
# Note that if $2 is anything other than a shell it probably won't
# work well.
if [ "$nextArgIsData" = "TRUE" ];then
OVERRIDE_ENTRYPOINT+=" --entrypoint $2 "
shift
else
# Force entry point to be the container-create-user.sh script.
OVERRIDE_ENTRYPOINT+=" --entrypoint /usr/local/bin/container-create-user.sh "
fi
;;
-a | --all | --any )
# Run any downloaded image
#and log in as root
FILTER_SHOW_ONLY_DUE="FALSE"
;;
-c | --command )
# Run a command in the container.
# Skip over --command
shift
# Take the rest of the line as the command
COMMAND_LIST="$*"
DO_RUN_IMAGE="TRUE"
# Note current directory to recreate its path
# in the container, and to cd to for context.
CURRENT_WORKING_DIRECTORY="$(pwd)"
# Default to mounting and replicating the path of pwd
# in the container.
MOUNT_CURRENT_WORKING_DIRECTORY="$CURRENT_WORKING_DIRECTORY"
# Break here. Done parsing after command.
break
;;
--debug )
# Settings to debug a failed container creation.
# Default to root account,
# Show containers not labeled as created by DUE
# Bash may not be installed, so /bin/sh should be safe.
USER_NAME="root"
USER_ID="0"
FILTER_SHOW_ONLY_DUE="FALSE"
DEBUG_LOGIN="TRUE"
LOGIN_SHELL="/bin/sh"
;;
-b | --build | --duebuild )
# execute /usr/local/bin/duebuild
if [ "$term" = "--duebuild" ];then
# if the request is specifically due --help --duebuild, run
# the container to get duebuild --help in it.
if [ "$2" = "--help" ];then
fxnDueBuildHelp
exit 0
fi
fi
# Take the rest of the line as the command, so any arguments
# passed to the build should follow this.
if [ "$2" != "" ];then
# Seems the run help would be useful here.
case $2 in
--home-dir )
USE_HOMEDIR="$3"
if [ ! -e "$USE_HOMEDIR" ];then
fxnERR "Failed to find --home-dir [ $USE_HOMEDIR ]. Exiting."
exit 1
fi
# Shift these args out of the command line passed to duebuild
shift
shift
;;
-h | --help | help )
fxnHelpRun
exit
;;
esac
# skip over --build
shift
COMMAND_LIST="$*"
fi
DO_RUN_IMAGE="TRUE"
# Note current directory to recreate its path
# in the container, and to cd to for context.
CURRENT_WORKING_DIRECTORY="$(pwd)"
# Default to mounting and replicating the path of pwd
# in the container.
MOUNT_CURRENT_WORKING_DIRECTORY="$CURRENT_WORKING_DIRECTORY"
# Break here. Done parsing after command.
DEFAULT_BUILD_SCRIPT="/usr/local/bin/duebuild"
if [ "$COMMAND_LIST" = "" ];then
# No arguments? Do whatever the container's default build is
COMMAND_LIST="$DEFAULT_BUILD_SCRIPT --default"
else
# User is responsible for passing coherent arguments to the
# build in COMMAND_LIST
COMMAND_LIST="$DEFAULT_BUILD_SCRIPT $COMMAND_LIST"
fi
# Nothing left to process. The default build script, if present
# in the container will be passed the commands
break
;;
--dockerarg )
# Tack additional arguments on to this
DOCKER_SPECIFIC_ARGS+=" $2 "
shift
;;
--container-name )
# Change the default name of the running container
# Note if 'due' is not part of the name, it will be automatically filtered
# when DUE lists running containers unless '--all' is also supplied.
# This may or may not be desirable behavior.
SET_CONTAINER_NAME="$2"
shift
;;
#
# username, user id, group name, group id all default
# to the current user's settings. These are override options
#
-n|--username )
# Username to use in container
USER_NAME="$2"
shift
;;
--userid )
# User id to use in container
USER_ID="$2"
shift
;;
--groupid )