Monday, November 23, 2015

Creating RDBMS-Style Views on your Fs w/ROFS-Filtered

Sometimes its useful to abstract a segment of a filesystem for variety of reasons: some applications don't offer the luxury of filtering filetypes. Some do yet have no clue what you want, such as Music Players when there are multiple formats of the same song if you add the directory the multiply formatted songs are duplicated.
#!/bin/bash 

declare -r TEST_DIR="/tmp" 
 ## If you update the following var, update gen_rofs_inverted_rc 
 ## accordingly. 
declare -r TEST_DATA_DIR="/tmp/rofs_data" 
declare -r TEST_MNT_POINT="/tmp/mnt/rofs"
declare -r FILE_FILTER="jpg"
declare -r ROFS_RC="rofs_only_jpg.rc" 
declare    ROFL_FILTERED_DIR=${1:-$(pwd)} 
 ## Add the default build location for fetches, just in case. 
PATH="${PATH}:${ROFL_FILTERED_DIR}:${TEST_DIR}/rofs-filtered" 

function preliminary_checks() { 
 if ! which rofs-filtered &>/dev/null; then     
  echo -en "\nCommand rofs-filtered not found in current PATH, try passing in the \
  directory on the cmdline\nE.g. ${0##*/} /path/to/built/software\n\n"   
  fetch_and_build_rofs_filtered
 fi 
} 

function fetch_and_build_rofs_filtered() { 
 read -p "Enter f to fetch/build the latest rofs-filtered from git, anything else to continue:" -u 0 response 
 case ${response} in 
  f)   
    cd "${TEST_DIR}" 
    git clone https://github.com/gburca/rofs-filtered.git
    cd rofs-filtered 
    ./autogen.sh 
    ./configure
    make
    ROFL_FILTERED_DIR="${TEST_DIR}/rofs-filtered" 
    PATH="${PATH}:${ROFL_FILTERED_DIR}"    
    cd .. 
    ;;
  *)     
    echo "You need to find rofs-filtered and put in the current PATH." 
    ;;
 esac 
} 

function gen_test_data() { 
 cd "${TEST_DATA_DIR}"
 ls -f1 | grep -E 'jpg$|mp3$|mp4$' | xargs -I {} rm {}
 touch fav_media_{1..100}.jpg
 touch fav_media_{1..100}.mp3
 touch fav_media_{1..100}.mp4
 cd - &>/dev/null
} 
 
 ### Adjust this to reflect any change in the location of the 
 ### test data directory. 
function gen_rofs_inverted_rc() { 
cat <<EOF
\/\$
\/\.\$
\/\.\.\$

tmp\$
rofs_data\$
./.+\.${FILE_FILTER}\$

EOF
} 

function unmount_rofs() { 
 mount | grep -q "${TEST_MNT_POINT}" && sudo umount "${TEST_MNT_POINT}"  
}

function clean_up() { 
 unmount_rofs
 rm -rf "${TEST_DIR}/${ROFS_RC}"
 rmdir "${TEST_MNT_POINT}" 2>/dev/null 
} 

function test_ls() { 
 echo "ls ${TEST_MNT_POINT} ..."
 ls "${TEST_MNT_POINT}/${TEST_DATA_DIR}" | tail -10 
} 
 
function main() { 
gen_rofs_inverted_rc > "${TEST_DIR}/${ROFS_RC}"
mkdir -p "${TEST_MNT_POINT}" "${TEST_DATA_DIR}"
gen_test_data 
preliminary_checks
which rofs-filtered &>/dev/null || exit -1 
unmount_rofs
rofs-filtered "${TEST_MNT_POINT}" -o invert -o source=/ -o config="${TEST_DIR}/${ROFS_RC}"
test_ls
} 

function what_likely_happened() { 
cat <<EOF

Here is what *likely* just happened:  
 
 Test data directory (${TEST_DATA_DIR}) was created and 
 loaded with empty files. 
 
 The following files were generated: 

  ROFS Filtered configuration file was created: ${TEST_DIR}/${ROFS_RC}
  The data from the test data directory above is now mounted and filtered 
  at ${TEST_MNT_POINT}. 
  
  If you traverse to ${TEST_MNT_POINT}/${TEST_DATA_DIR} you should see 
  only files with the .$FILE_FILTER extension. 
  
  To clean it up, just run it with a second argument on the commandline. 
  E.g. ${0##*/} "/path/to/rofs-filtered/bin/dir" cleanupthismess
   
EOF
} 

main 
what_likely_happened 
 ## Any second argument attempts a cleanup. 
 ## If you put rofs-filtered in your path and don't want to pass it in to 
 ## clean it up just put $(which rofs-filtered). 
(($# > 1)) && echo "Cleaning up ... (except for /tmp/mnt)" && clean_up

exit 0 

No comments:

Post a Comment