diff --git a/bin/dib-run-parts b/bin/dib-run-parts
deleted file mode 120000
index 055c8b3c0..000000000
--- a/bin/dib-run-parts
+++ /dev/null
@@ -1 +0,0 @@
-../elements/dib-run-parts/bin/dib-run-parts
\ No newline at end of file
diff --git a/elements/dib-run-parts/bin/dib-run-parts b/elements/dib-run-parts/bin/dib-run-parts
deleted file mode 100755
index 018da92b3..000000000
--- a/elements/dib-run-parts/bin/dib-run-parts
+++ /dev/null
@@ -1,112 +0,0 @@
-#!/bin/bash
-# Inspired by Debian and RedHat run-parts but portable and specific to di-b.
-#
-# Copyright 2012 Hewlett-Packard Development Company, L.P.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-allowed_regex=${RUN_PARTS_REGEX:-"^[0-9A-Za-z_-]+$"}
-show_list=
-
-set -ue
-set -o pipefail
-
-name=$(basename $0)
-
-usage() {
-    echo "Usage: $name [OPTION] scripts_directory"
-    echo "Option:"
-    echo "      --list  print names of all valid files"
-    echo
-    echo "Examples:"
-    echo "      dib-run-parts --list /opt/stack/os-config-refresh/configure.d/"
-    echo "      dib-run-parts /opt/stack/os-config-refresh/configure.d/"
-    exit 1
-} >&2
-
-output () {
-    echo $name $(date) $* >&2
-}
-
-if [ $# -lt 1 ] ; then
-    usage
-fi
-
-if [ "$1" == "--list" ] ; then
-    show_list="1"
-    shift
-fi
-
-target_dir="${1:-}"
-
-if ! [ -d "$target_dir" ] ; then
-    output "Scripts directory [$target_dir] must exist and be a directory"
-    usage
-fi
-
-# We specifically only want to sort *by the numbers*.
-# Lexical sorting is not guaranteed, and identical numbers may be
-# parallelized later
-# Note: -maxdepth 1 ensures only files in the target directory (but not
-# subdirectories) are run, which is the way run-parts behaves.
-targets=$(find $target_dir -maxdepth 1 -xtype f -executable -printf '%f\n' | grep -E "$allowed_regex" | LANG=C sort -n || echo "")
-
-if [ "$show_list" == "1" ] ; then
-    for target in $targets ; do
-        echo "${target_dir}/${target}"
-    done
-    exit 0
-fi
-
-PROFILE_DIR=$(mktemp -d /tmp/profiledir.XXXXXX)
-
-ENVIRONMENT_D_DIR=$target_dir/../environment.d
-
-if [ -d $ENVIRONMENT_D_DIR ] ; then
-    env_files=$(find $ENVIRONMENT_D_DIR -maxdepth 1 -xtype f | \
-        grep -E "/[0-9A-Za-z_\.-]+$" | \
-        LANG=C sort -n)
-    for env_file in $env_files ; do
-        source $env_file
-    done
-fi
-
-for target in $targets ; do
-    output "Running $target_dir/$target"
-    target_tag=${target//\//_}
-    date +%s.%N > $PROFILE_DIR/start_$target_tag
-    $target_dir/$target
-    target_tag=${target//\//_}
-    date +%s.%N > $PROFILE_DIR/stop_$target_tag
-    output "$target completed"
-done
-
-echo "----------------------- PROFILING -----------------------"
-echo ""
-echo "Target: $(basename $target_dir)"
-echo ""
-printf "%-40s %9s\n" Script Seconds
-printf "%-40s %9s\n" --------------------------------------- ----------
-echo ""
-pushd $PROFILE_DIR > /dev/null
-for target in $(find . -name 'start_*' -printf '%f\n') ; do
-    stop_file=stop_${target##start_}
-    start_seconds=$(cat $target)
-    stop_seconds=$(cat $stop_file)
-    duration=$(python -c "print($stop_seconds - $start_seconds)")
-    LC_NUMERIC=C LC_ALL=C printf "%-40s %10.3f\n" ${target##start_} $duration
-done
-popd > /dev/null
-rm -rf $PROFILE_DIR
-echo ""
-echo "--------------------- END PROFILING ---------------------"
diff --git a/elements/dib-run-parts/root.d/90-base-dib-run-parts b/elements/dib-run-parts/root.d/90-base-dib-run-parts
index 98d52b9bd..27819e6c2 100755
--- a/elements/dib-run-parts/root.d/90-base-dib-run-parts
+++ b/elements/dib-run-parts/root.d/90-base-dib-run-parts
@@ -3,7 +3,6 @@
 set -eu
 set -o pipefail
 
-home=$(dirname $0)
 exec sudo install -m 0755 -o root -g root -D \
-    $home/../bin/dib-run-parts \
+    $(which dib-run-parts) \
     $TARGET_ROOT/usr/local/bin/dib-run-parts
diff --git a/lib/common-functions b/lib/common-functions
index f00ae0777..9189634c3 100644
--- a/lib/common-functions
+++ b/lib/common-functions
@@ -197,7 +197,7 @@ function run_d() {
     check_element
     check_break before-$1 bash
     if [ -d ${TMP_HOOKS_PATH}/$1.d ] ; then
-      ${SCRIPT_HOME}/dib-run-parts ${TMP_HOOKS_PATH}/$1.d
+      dib-run-parts ${TMP_HOOKS_PATH}/$1.d
     fi
     check_break after-$1 bash
 }
diff --git a/requirements.txt b/requirements.txt
index 6242a0612..62da03b4d 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,2 +1,3 @@
 Babel>=1.3
 argparse
+dib-utils
diff --git a/setup.cfg b/setup.cfg
index bc253ef75..23dc7a5fd 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -18,11 +18,10 @@ classifier =
 packages =
     diskimage_builder
 
-# dib-run-parts and ramdisk-image-create are symlinks which become
-# real files on install; see lp bug #1212482
+# ramdisk-image-create is a symlink which becomes a
+# real file on install; see lp bug #1212482
 scripts =
     bin/dib-lint
-    bin/dib-run-parts
     bin/disk-image-create
     bin/disk-image-get-kernel
     bin/element-info