diff --git a/README.md b/README.md index 2d4450d..902a6d0 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,36 @@ -juju +JuJu ==== +**JuJu**: the portable GNU/Linux distribution. + +Description +----------- +**JuJu** is a small and portable GNU/Linux distribution based on ArchLinux. + +JuJu can be used inside another GNU/Linx OS via chroot. It only contains the package manager (called pacman) in order to access to a wide range of packages from ArchLinux repositories. + +The main advantage of using JuJu is because you have an isolated environment in which you can install +packages without affecting a production system. Another advantage is that with JuJu +you can access to a really wide range of packages inside GNU/Linux systems that contains +limited repositories (such as CentOS and RedHat). + +Quickstart +---------- +After installing JuJu (See next section) just run the main juju script: +```bash +juju +``` +The first time you execute it, the script will download the JuJu image and place it +to the default directory ~/.juju. +You will need root privileges in order to acces to the chroot. + +Installation +------------ +Just clone JuJu somewhere (for example in ~/juju): + +```bash +git clone git://github.com/fsquillace/juju ~/juju +export PATH=~/juju/bin:$PATH +``` + +JuJu can only works on GNU/Linux OS with kernel version greater or equal +2.6.32 in 32 or 64 bit. diff --git a/bin/.juju.swp b/bin/.juju.swp new file mode 100644 index 0000000..f0bb305 Binary files /dev/null and b/bin/.juju.swp differ diff --git a/bin/arch-chroot b/bin/arch-chroot new file mode 100755 index 0000000..d2a87da --- /dev/null +++ b/bin/arch-chroot @@ -0,0 +1,198 @@ +#!/bin/bash + +shopt -s extglob + +# generated from util-linux source: libmount/src/utils.c +declare -A pseudofs_types=([anon_inodefs]=1 + [autofs]=1 + [bdev]=1 + [binfmt_misc]=1 + [cgroup]=1 + [configfs]=1 + [cpuset]=1 + [debugfs]=1 + [devfs]=1 + [devpts]=1 + [devtmpfs]=1 + [dlmfs]=1 + [fuse.gvfs-fuse-daemon]=1 + [fusectl]=1 + [hugetlbfs]=1 + [mqueue]=1 + [nfsd]=1 + [none]=1 + [pipefs]=1 + [proc]=1 + [pstore]=1 + [ramfs]=1 + [rootfs]=1 + [rpc_pipefs]=1 + [securityfs]=1 + [sockfs]=1 + [spufs]=1 + [sysfs]=1 + [tmpfs]=1) + +# generated from: pkgfile -vbr '/fsck\..+' | awk -F. '{ print $NF }' | sort +declare -A fsck_types=([cramfs]=1 + [exfat]=1 + [ext2]=1 + [ext3]=1 + [ext4]=1 + [ext4dev]=1 + [jfs]=1 + [minix]=1 + [msdos]=1 + [reiserfs]=1 + [vfat]=1 + [xfs]=1) + +out() { printf "$1 $2\n" "${@:3}"; } +error() { out "==> ERROR:" "$@"; } >&2 +msg() { out "==>" "$@"; } +msg2() { out " ->" "$@";} +die() { error "$@"; exit 1; } + +ignore_error() { + "$@" 2>/dev/null + return 0 +} + +in_array() { + local i + for i in "${@:2}"; do + [[ $1 = "$i" ]] && return + done +} + +track_mount() { + if [[ -z $CHROOT_ACTIVE_MOUNTS ]]; then + CHROOT_ACTIVE_MOUNTS=() + trap 'chroot_umount' EXIT + fi + + mount "$@" && CHROOT_ACTIVE_MOUNTS=("$2" "${CHROOT_ACTIVE_MOUNTS[@]}") +} + +mount_conditionally() { + local cond=$1; shift + if eval "$cond"; then + track_mount "$@" + fi +} + +api_fs_mount() { + mount_conditionally "! mountpoint -q '$1'" "$1" "$1" --bind && + track_mount proc "$1/proc" -t proc -o nosuid,noexec,nodev && + track_mount sys "$1/sys" -t sysfs -o nosuid,noexec,nodev,ro && + ignore_error mount_conditionally "[[ -d '$1/sys/firmware/efi/efivars' ]]" \ + efivarfs "$1/sys/firmware/efi/efivars" -t efivarfs -o nosuid,noexec,nodev && + track_mount udev "$1/dev" -t devtmpfs -o mode=0755,nosuid && + track_mount devpts "$1/dev/pts" -t devpts -o mode=0620,gid=5,nosuid,noexec && + track_mount shm "$1/dev/shm" -t tmpfs -o mode=1777,nosuid,nodev && + track_mount run "$1/run" -t tmpfs -o nosuid,nodev,mode=0755 && + track_mount tmp "$1/tmp" -t tmpfs -o mode=1777,strictatime,nodev,nosuid +} + +chroot_umount() { + umount "${CHROOT_ACTIVE_MOUNTS[@]}" +} + +valid_number_of_base() { + local base=$1 len=${#2} i= + + for (( i = 0; i < len; i++ )); do + { _=$(( $base#${2:i:1} )) || return 1; } 2>/dev/null + done + + return 0 +} + +mangle() { + local i= chr= out= + + unset {a..f} {A..F} + + for (( i = 0; i < ${#1}; i++ )); do + chr=${1:i:1} + case $chr in + [[:space:]\\]) + printf -v chr '%03o' "'$chr" + out+=\\ + ;; + esac + out+=$chr + done + + printf '%s' "$out" +} + +unmangle() { + local i= chr= out= len=$(( ${#1} - 4 )) + + unset {a..f} {A..F} + + for (( i = 0; i < len; i++ )); do + chr=${1:i:1} + case $chr in + \\) + if valid_number_of_base 8 "${1:i+1:3}" || + valid_number_of_base 16 "${1:i+1:3}"; then + printf -v chr '%b' "${1:i:4}" + (( i += 3 )) + fi + ;; + esac + out+=$chr + done + + printf '%s' "$out${1:i}" +} + +dm_name_for_devnode() { + read dm_name <"/sys/class/block/${1#/dev/}/dm/name" + if [[ $dm_name ]]; then + printf '/dev/mapper/%s' "$dm_name" + else + # don't leave the caller hanging, just print the original name + # along with the failure. + print '%s' "$1" + error 'Failed to resolve device mapper name for: %s' "$1" + fi +} + +fstype_is_pseudofs() { + (( pseudofs_types["$1"] )) +} + +fstype_has_fsck() { + (( fsck_types["$1"] )) +} + + +usage() { + cat <&2; } +function die(){ +# $@: msg (mandatory) - str: Message to print + error $@ + exit 1 +} +function error(){ +# $@: msg (mandatory) - str: Message to print + echoerr -e "\033[1;31m$@\033[0m" +} +function warn(){ +# $@: msg (mandatory) - str: Message to print + echoerr -e "\033[1;33m$@\033[0m" +} +function info(){ +# $@: msg (mandatory) - str: Message to print + echo -e "\033[1;37m$@\033[0m" +} + +if [ ! "$(ls -A $JUJU_HOME)" ] +then + setup_juju +fi + +run_juju + +