VOL-415 Changes to improve dependencies and solve intermittent installer
failures.
Change-Id: I6f23f42398e0509a231008f4a83e60cb12759d52
diff --git a/install/ansible/roles/cluster-host/tasks/main.yml b/install/ansible/roles/cluster-host/tasks/main.yml
index 7872fa6..7358e6e 100644
--- a/install/ansible/roles/cluster-host/tasks/main.yml
+++ b/install/ansible/roles/cluster-host/tasks/main.yml
@@ -63,6 +63,31 @@
- deb_files
tags: [cluster-host]
+- name: Required configuration scripts are copied
+ synchronize:
+ src: "/home/vinstall/{{ item }}"
+ dest: "{{ target_voltha_home }}"
+ archive: no
+ owner: no
+ perms: no
+ recursive: no
+ links: yes
+ with_items:
+ - sort_packages.sh
+ - sort_packages.py
+ - install_packages.sh
+ tags: [cluster-host]
+
+- name: The installer scripts are made executable
+ file:
+ path: "{{target_voltha_home }}/{{ item }}"
+ mode: 0744
+ with_items:
+ - sort_packages.sh
+ - sort_packages.py
+ - install_packages.sh
+ tags: [installer]
+
- name: apt lists are up-to-date
synchronize:
src: "/var/lib/apt/lists"
@@ -102,8 +127,8 @@
tags: [cluster_host]
- name: Dependent software is installed (this can take about 10 Min, DONT'T PANIC, go for coffee instead)
- command: dpkg -R -i "{{ target_voltha_home }}/deb_files"
-# ignore_errors: true
+ command: "{{ target_voltha_home }}/install_packages.sh"
+# command: dpkg -R -i "{{ target_voltha_home }}/deb_files"
when: target == "cluster"
tags: [cluster_host]
@@ -120,14 +145,20 @@
when: target == "cluster"
tags: [cluster_host]
-- name: Configuration directories are deleted
+# To debug package installation, comment this out so review temporary interim
+# files.
+- name: Configuration directories and files are deleted
file:
path: "{{ target_voltha_home }}/{{ item }}"
state: absent
with_items:
- docker-py
- netifaces
- - deb_files
+ - sort_packages.sh
+ - sort_packages.py
+ - install_packages.sh
+ - deb_files1
+ - deb_files2
when: target == "cluster"
tags: [cluster_host]
diff --git a/install/ansible/roles/installer/tasks/main.yml b/install/ansible/roles/installer/tasks/main.yml
index 0b1666e..52ccaf4 100644
--- a/install/ansible/roles/installer/tasks/main.yml
+++ b/install/ansible/roles/installer/tasks/main.yml
@@ -26,6 +26,9 @@
- install/voltha-swarm-stop.sh
- install/get-logs.sh
- install/get-host-logs.sh
+ - install/sort_packages.sh
+ - install/sort_packages.py
+ - install/install_packages.sh
- install/ansible
- compose
- consul_config/basic.json
@@ -43,10 +46,15 @@
dest: /home/vinstall
when: file.stat.exists
-- name: The installer is made executable
+- name: The installer scripts are made executable
file:
- path: /home/vinstall/installer.sh
+ path: "/home/vinstall/{{ item }}"
mode: 0744
+ with_items:
+ - installer.sh
+ - sort_packages.sh
+ - sort_packages.py
+ - install_packages.sh
tags: [installer]
- name: Python docker-py {{ docker_py_version }} package source is available
diff --git a/install/install_packages.sh b/install/install_packages.sh
new file mode 100644
index 0000000..b439c2c
--- /dev/null
+++ b/install/install_packages.sh
@@ -0,0 +1,29 @@
+#!/bin/bash
+
+pushd /home/voltha
+
+# Find all non-dpendency packages
+./sort_packages.sh
+
+# Split the package lists into those that have dependencies and those that don't
+mv deb_files{,2}
+mkdir deb_files1
+
+# Move all no-dependency packages into the phase 1 directory
+for i in `cat sortedDebs.txt`
+do
+ mv deb_files2/$i deb_files1
+done
+
+
+# Now install the phase 1 packages
+
+sudo dpkg -R -i deb_files1 2>&1 > install.log
+sudo apt-get -f install 2>&1 >> install.log
+sudo dpkg -R -i deb_files2 2>&1 >> install.log
+sudo apt-get -f install 2>&1 >> install.log
+
+rm -f sortedDebs.txt
+
+popd
+exit 0
diff --git a/install/sort_packages.py b/install/sort_packages.py
new file mode 100755
index 0000000..47bcbd6
--- /dev/null
+++ b/install/sort_packages.py
@@ -0,0 +1,66 @@
+#!/usr/bin/env python
+
+# Load the deb_info.txt file into a dictionary for further processing.
+deps = dict()
+pkgList = list()
+sort_list = list()
+
+with open("deb_info.txt") as f:
+ for line in f:
+ line = line.rstrip("\n")
+ linfo=line.split(":")
+ pkgList.append(linfo[0])
+ deps[linfo[0]]={}
+ deps[linfo[0]]["deb_file"] = linfo[1]
+ deps[linfo[0]]["deps"] = linfo[2].split(",")
+
+
+# First extract all packages that don't have any dependencies
+# at all with the current set of packages
+for key in deps:
+ hasDep=False
+ #print(key, " has dependencies ", deps[key]["deps"])
+ for dep in deps[key]["deps"]:
+ if dep in pkgList:
+ hasDep=True
+ if hasDep == False:
+ #print(key, " has no dependencies")
+ sort_list.append(key)
+ pkgList.remove(key)
+
+for pkg in sort_list:
+ print(deps[pkg]["deb_file"])
+
+exit(0)
+
+# The rest is for future layering of updates and
+# isn't currently used.
+
+# Now scan iterate over the remaining items and
+# add them to the sort_list if they have their
+# dependencies satisfied in the sort list.
+# Continue until the pkgList is empty
+lastLen = 0
+while len(pkgList) > 0:
+ p = pkgList
+ curLen = len(pkgList)
+ if lastLen == curLen:
+ for pkg in p:
+ sort_list.append(pkg)
+ pkgList.remove(pkg)
+ else:
+ lastLen = curLen
+ for pkg in p:
+ missingDep=False
+ for dep in deps[pkg]["deps"]:
+ if dep not in sort_list and dep in pkgList:
+ missingDep=True
+ if missingDep == False:
+ sort_list.append(pkg)
+ pkgList.remove(pkg)
+
+# Now write the packages out in the sorted order
+# this should ensure that dependent packages are
+# installed first.
+for pkg in sort_list:
+ print(deps[pkg]["deb_file"])
diff --git a/install/sort_packages.sh b/install/sort_packages.sh
new file mode 100755
index 0000000..b2d8dd8
--- /dev/null
+++ b/install/sort_packages.sh
@@ -0,0 +1,29 @@
+#!/bin/bash
+
+debDir="deb_files"
+
+rm -f deb_info.txt
+rm -f debFiles.txt
+rm -f sortedDebs.txt
+
+# Create the paackage information file for further processing by Python
+ls $debDir/*.deb | sed -e 's~deb_files/~~' > debFiles.txt
+
+
+for i in `cat debFiles.txt`
+do
+ pkgName=""
+ deps=""
+ pkgName=`dpkg -I $debDir/$i | egrep "^[ ]*Package:" | sed -e 's/Package://' | sed -e 's/\([ ]\+\)\|\([ ]\+$\)//'`
+ deps=`dpkg -I $debDir/$i | grep Depends: | sed -e 's/Depends://' | sed -e 's/\([ ]\+\)\|\([ ]\+$\)//'`
+ deps=`echo $deps | sed -e 's/|/,/g' | sed -e 's/([^)]\+)//g' | sed -e 's/:any//g' | sed -e 's/,//g'`
+ deps=`echo $deps | sed -e 's/[ ]\+/ /g' | sed -e 's/\(^[ ]\+\)\|\([ ]\+$\)//' | sed -e 's/ /,/g'`
+ #deps=`echo $deps | sed -e 's/^\(.\)/"\1/' | sed -e 's/\(.\)$/\1"/' | sed -s 's/,/","/g'`
+ echo "${pkgName}:${i}:${deps}" >> deb_info.txt
+done
+rm -f debFiles.txt
+
+# Now launch the python scrip that sorts the files based on the dependencies.
+./sort_packages.py > sortedDebs.txt
+
+rm -f deb_info.txt