]> git.proxmox.com Git - mirror_ifupdown2.git/commitdiff
debian: sync debian files with from upstream debian repo
authorRoopa Prabhu <roopa@cumulusnetworks.com>
Tue, 15 Dec 2015 00:26:31 +0000 (16:26 -0800)
committerRoopa Prabhu <roopa@cumulusnetworks.com>
Mon, 21 Dec 2015 07:06:12 +0000 (23:06 -0800)
These include changes that were done to move ifupdown2
to use pybuild and some debian policy fixes

Signed-off-by: Roopa Prabhu <roopa@cumulusnetworks.com>
27 files changed:
README.rst [deleted file]
debian/changelog [new file with mode: 0644]
debian/clean [new file with mode: 0644]
debian/compat [new file with mode: 0644]
debian/control [new file with mode: 0644]
debian/copyright
debian/ifupdown2.bash-completion [new file with mode: 0644]
debian/ifupdown2.dirs [new file with mode: 0644]
debian/ifupdown2.docs [new file with mode: 0644]
debian/ifupdown2.examples [new file with mode: 0644]
debian/ifupdown2.install [new file with mode: 0644]
debian/ifupdown2.links [new file with mode: 0644]
debian/ifupdown2.manpages [new file with mode: 0644]
debian/ifupdown2.networking.service [new file with mode: 0644]
debian/ifupdown2.postinst [new file with mode: 0644]
debian/ifupdown2.postrm [new file with mode: 0644]
debian/networking.default [new file with mode: 0644]
debian/networking.init [new file with mode: 0644]
debian/python-ifupdown2.postinst [deleted file]
debian/python-ifupdown2.postrm [deleted file]
debian/python-ifupdown2.preinst [deleted file]
debian/rules [new file with mode: 0755]
debian/source/format [new file with mode: 0644]
docs/README.rst [new file with mode: 0644]
sbin/ifupdown [deleted file]
sbin/ifupdown2 [new file with mode: 0755]
setup.py

diff --git a/README.rst b/README.rst
deleted file mode 100644 (file)
index 8ab8252..0000000
+++ /dev/null
@@ -1,78 +0,0 @@
-python-ifupdown2
-================
-
-This package is a replacement for the debian ifupdown package.
-It is ifupdown re-written in python. It maintains the original ifupdown
-pluggable architecture and extends it further.
-
-The python-ifupdown2 package provides the infrastructure for
-parsing /etc/network/interfaces file, loading, scheduling and state
-management of interfaces.
-
-It dynamically loads python modules from /usr/share/ifupdownmodules (provided
- by the python-ifupdown2-addons package). To remain compatible with other
-packages that depend on ifupdown, it also executes scripts under /etc/network/.
-To make the transition smoother, a python module under
-/usr/share/ifupdownmodules will override a script by the same name under
-/etc/network/.
-
-It publishes an interface object which is passed to all loadble python
-modules. For more details on adding a addon module, see the section on
-adding python modules.
-
-
-pluggable python modules:
-=========================
-Unlike original ifupdown, all interface configuration is moved to external
-python modules. That includes inet, inet6 and dhcp configurations.
-
-A set of default modules are provided by the python-ifupdown2-addons deb.
-
-python-ifupdown2 expects a few things from the pluggable modules:
-- the module should implement a class by the same name
-- the interface object (class iface) and the operation to be performed is
-  passed to the modules
-- the python addon class should provide a few methods:
-       - run() : method to configure the interface.
-       - get_ops() : must return a list of operations it supports.
-               eg: 'pre-up', 'post-down'
-       - get_dependent_ifacenames() : must return a list of interfaces the
-         interface is dependent on. This is used to build the dependency list
-         for sorting and executing interfaces in dependency order.
-       - if the module supports -r option to ifquery, ie ability to construct the
-      ifaceobj from running state, it can optionally implement the
-      get_dependent_ifacenames_running() method, to return the list of
-      dependent interfaces derived from running state of the interface.
-      This is different from get_dependent_ifacenames() where the dependent
-      interfaces are derived from the interfaces config file (provided by the
-      user).
-
-Example: Address handling module /usr/share/ifupdownaddons/address.py
-
-
-build
-=====
-- get source
-
-- install build dependencies:
-    apt-get install python-stdeb
-    apt-get install python-docutils
-
-- cd <python-ifupdown2 sourcedir> && ./build.sh
-
-  (generates python-ifupdown2-<ver>.deb)
-
-install
-=======
-
-- remove existing ifupdown package
-  dpkg -r ifupdown
-
-- install python-ifupdown2 using `dpkg -i`
-
-- or install from deb
-    dpkg -i python-ifupdown2-<ver>.deb
-
-- note that python-ifupdown2 requires python-ifupdown2-addons package to
-  function. And python-ifupdown2-addons deb has an install dependency on
-  python-ifupdown2
diff --git a/debian/changelog b/debian/changelog
new file mode 100644 (file)
index 0000000..8b5f0dd
--- /dev/null
@@ -0,0 +1,5 @@
+ifupdown2 (1.1) unstable; urgency=low
+
+  * Initial release.
+
+ -- Roopa Prabhu <roopa@cumulusnetworks.com>  Thu, 20 Aug 2015 06:14:24 -0700
diff --git a/debian/clean b/debian/clean
new file mode 100644 (file)
index 0000000..0723a0c
--- /dev/null
@@ -0,0 +1,4 @@
+man/ifquery.8
+man/ifreload.8
+man/ifup.8
+man/ifupdown-addons-interfaces.5
diff --git a/debian/compat b/debian/compat
new file mode 100644 (file)
index 0000000..ec63514
--- /dev/null
@@ -0,0 +1 @@
+9
diff --git a/debian/control b/debian/control
new file mode 100644 (file)
index 0000000..b84fbdf
--- /dev/null
@@ -0,0 +1,31 @@
+Source: ifupdown2
+Section: admin
+Priority: optional
+Maintainer: Roopa Prabhu <roopa@cumulusnetworks.com>
+Standards-Version: 3.9.6
+Build-Depends: python-setuptools, dh-python, python-all (>= 2.6.6-3), debhelper (>= 9~), python-docutils, dh-systemd
+Homepage: https://github.com/CumulusNetworks/ifupdown2
+X-Python-Version: >= 2.6
+
+Package: ifupdown2
+Architecture: all
+Suggests: python-gvgen, python-mako 
+Replaces: ifupdown
+Conflicts: ifupdown
+Provides: ifupdown
+Depends: ${python:Depends}, ${misc:Depends}, python-argcomplete, python-ipaddr
+Description: Network Interface Management tool similar to ifupdown
+ ifupdown2 is ifupdown re-written in Python. It replaces ifupdown and provides
+ the same user interface as ifupdown for network interface configuration.
+ Like ifupdown, ifupdown2 is a high level tool to configure (or, respectively
+ deconfigure) network interfaces based on interface definitions in
+ /etc/network/interfaces. It is capable of detecting network interface
+ dependencies and comes with several new features which are available as
+ new command options to ifup/ifdown/ifquery commands. It also comes with a new
+ command ifreload to reload interface configuration with minimum
+ disruption. Most commands are also capable of input and output in JSON format.
+ It is backward compatible with ifupdown /etc/network/interfaces format and
+ supports newer simplified format. It also supports interface templates with
+ python-mako for large scale interface deployments. See
+ /usr/share/doc/ifupdown2/README.rst for details about ifupdown2. Examples
+ are available under /usr/share/doc/ifupdown2/examples.
index f560d805f2ace656b82a42db44e099c2d1d01ee5..d4d78eaf1d8bf611331638c37fa3e16a3174ff0b 100644 (file)
@@ -1,13 +1,16 @@
 Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
 Upstream-Name: ifupdown2
+Upstream-Contact: Roopa Prabhu <roopa@cumulusnetworks.com>, Sam Tannous <stannous@cumulusnetworks.com>
 Source: http://www.cumulusnetworks.com
 
 Files: *
-Copyright: 2013 Cumulus Networks
+Copyright: 2014 Cumulus Networks
 License: GPL-2
 
 Files: debian/*
-Copyright: 2013 Cumulus Networks
+Copyright: 2014 Cumulus Networks
+License: GPL-2
+
 License: GPL-2
  This package is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
@@ -23,8 +26,3 @@ License: GPL-2
  .
  On Debian systems, the complete text of the GNU General
  Public License version 2 can be found in "/usr/share/common-licenses/GPL-2".
-
-# Please also look if there are files or directories which have a
-# different copyright/license attached and list them here.
-# Please avoid to pick license terms that are more restrictive than the
-# packaged work, as it may make Debian's contributions unacceptable upstream.
diff --git a/debian/ifupdown2.bash-completion b/debian/ifupdown2.bash-completion
new file mode 100644 (file)
index 0000000..cf6dbfb
--- /dev/null
@@ -0,0 +1 @@
+completion/ifup
diff --git a/debian/ifupdown2.dirs b/debian/ifupdown2.dirs
new file mode 100644 (file)
index 0000000..e7493b1
--- /dev/null
@@ -0,0 +1 @@
+/etc/network/interfaces.d/
diff --git a/debian/ifupdown2.docs b/debian/ifupdown2.docs
new file mode 100644 (file)
index 0000000..5c86fa8
--- /dev/null
@@ -0,0 +1 @@
+docs/README.rst
diff --git a/debian/ifupdown2.examples b/debian/ifupdown2.examples
new file mode 100644 (file)
index 0000000..684a743
--- /dev/null
@@ -0,0 +1 @@
+docs/examples/*
diff --git a/debian/ifupdown2.install b/debian/ifupdown2.install
new file mode 100644 (file)
index 0000000..cffd8b9
--- /dev/null
@@ -0,0 +1,2 @@
+sbin/ifupdown2 /usr/share/ifupdown2/
+debian/networking.default /etc/default/networking
diff --git a/debian/ifupdown2.links b/debian/ifupdown2.links
new file mode 100644 (file)
index 0000000..177c9d5
--- /dev/null
@@ -0,0 +1,6 @@
+usr/share/ifupdown2/ifupdown2 sbin/ifup
+usr/share/ifupdown2/ifupdown2 sbin/ifdown
+usr/share/ifupdown2/ifupdown2 sbin/ifquery
+usr/share/ifupdown2/ifupdown2 sbin/ifreload
+usr/share/man/man8/ifup.8.gz usr/share/man/man8/ifdown.8.gz
+
diff --git a/debian/ifupdown2.manpages b/debian/ifupdown2.manpages
new file mode 100644 (file)
index 0000000..b7d0fab
--- /dev/null
@@ -0,0 +1,5 @@
+man/ifup.8
+man/ifquery.8
+man/ifreload.8
+man/ifupdown-addons-interfaces.5
+man/interfaces.5
diff --git a/debian/ifupdown2.networking.service b/debian/ifupdown2.networking.service
new file mode 100644 (file)
index 0000000..4bcc1ae
--- /dev/null
@@ -0,0 +1,10 @@
+[Unit]
+Description=ifupdown2 init script
+
+[Service]
+Type=oneshot
+ExecStart=/sbin/ifup -a
+ExecStop=/sbin/ifdown -a
+
+[Install]
+WantedBy=multi-user.target
diff --git a/debian/ifupdown2.postinst b/debian/ifupdown2.postinst
new file mode 100644 (file)
index 0000000..e1df311
--- /dev/null
@@ -0,0 +1,76 @@
+#!/bin/sh
+# postinst script for ifupdown2
+#
+# see: dh_installdeb(1)
+
+set -e
+
+# summary of how this script can be called:
+#        * <postinst> `configure' <most-recently-configured-version>
+#        * <old-postinst> `abort-upgrade' <new version>
+#        * <conflictor's-postinst> `abort-remove' `in-favour' <package>
+#          <new-version>
+#        * <postinst> `abort-remove'
+#        * <deconfigured's-postinst> `abort-deconfigure' `in-favour'
+#          <failed-install-package> <version> `removing'
+#          <conflicting-package> <version>
+# for details, see http://www.debian.org/doc/debian-policy/ or
+# the debian-policy package
+
+process_udev()
+{
+    # override default udev bridge and hotplug rules because they interfere with
+    # networking init script
+    udev_user_rulesdir=/etc/udev/rules.d/
+    udev_sys_rulesdir=/lib/udev/rules.d/
+    if [ -e $udev_user_rulesdir ]; then
+        udev_ifupdown2_overrides="80-networking.rules
+        60-bridge-network-interface.rules"
+        for u in ${udev_ifupdown2_overrides}
+        do
+            if [ -e ${udev_sys_rulesdir}/$u -a ! -e ${udev_user_rulesdir}/$u ]; then
+                (cd ${udev_user_rulesdir} && ln -sf /dev/null $u)
+            fi
+        done
+    fi
+}
+
+MYNAME="${0##*/}"
+
+report() { echo "${MYNAME}: $*" ; }
+report_warn() { report "Warning: $*" >&2 ; }
+report_err() { report "Error: $*" >&2 ; }
+
+case "$1" in
+    configure)
+
+        # Generic stuff done on all configurations
+        if [ -f /etc/network/interfaces ] ; then
+            if ! grep -q "^[[:space:]]*iface[[:space:]]\+lo0\?[[:space:]]\+inet[[:space:]]\+loopback\>" /etc/network/interfaces ; then
+                report_warn "No 'iface lo' definition found in /etc/network/interfaces"
+            fi
+
+            if ! grep -q "^[[:space:]]*\(allow-\|\)auto[[:space:]]\+\(.*[[:space:]]\+\|\)lo0\?\([[:space:]]\+\|$\)" /etc/network/interfaces ; then
+                report_warn "No 'auto lo' statement found in /etc/network/interfaces"
+            fi
+        else  # ! -f /etc/network/interfaces
+            if [ -z "$2" ]; then
+                echo "Creating /etc/network/interfaces."
+                echo "# interfaces(5) file used by ifup(8) and ifdown(8)" > /etc/network/interfaces
+                echo "auto lo" >> /etc/network/interfaces
+                    echo "iface lo inet loopback" >> /etc/network/interfaces
+            else
+                    report_warn "/etc/network/interfaces does not exist"
+            fi
+        fi
+
+        process_udev
+        ;;
+
+  purge)
+    ;;
+esac
+
+#DEBHELPER#
+
+exit 0
diff --git a/debian/ifupdown2.postrm b/debian/ifupdown2.postrm
new file mode 100644 (file)
index 0000000..e7bb6a2
--- /dev/null
@@ -0,0 +1,69 @@
+#!/bin/sh
+# postrm script for ifupdown2
+#
+# see: dh_installdeb(1)
+
+set -e
+
+# summary of how this script can be called:
+#        * <postrm> `remove'
+#        * <postrm> `purge'
+#        * <old-postrm> `upgrade' <new-version>
+#        * <new-postrm> `failed-upgrade' <old-version>
+#        * <new-postrm> `abort-install'
+#        * <new-postrm> `abort-install' <old-version>
+#        * <new-postrm> `abort-upgrade' <old-version>
+#        * <disappearer's-postrm> `disappear' <overwriter>
+#          <overwriter-version>
+# for details, see http://www.debian.org/doc/debian-policy/ or
+# the debian-policy package
+
+process_udev()
+{
+    if [ -e /etc/udev/rules.d/80-networking.rules ]; then
+        udevlink=$(readlink /etc/udev/rules.d/80-networking.rules 2>/dev/null || true)
+        [ -n "$udevlink" -a "$udevlink" = "/dev/null" ] && rm -f /etc/udev/rules.d/80-networking.rules
+    fi
+
+    if  [ -e /etc/udev/rules.d/60-bridge-network-interface.rules ]; then
+        udevlink=$(readlink /etc/udev/rules.d/60-bridge-network-interface.rules 2>/dev/null || true)
+        [ -n "$udevlink" -a "$udevlink" = "/dev/null" ] && rm -f /etc/udev/rules.d/60-bridge-network-interface.rules
+    fi
+}
+
+postrm_remove()
+{
+    process_udev
+}
+
+# Note: We don't remove /etc/network/interfaces
+postrm_purge()
+{
+       rm -f /run/network/ifstatenew
+}
+
+case "$1" in
+       purge)
+               postrm_purge
+       ;;
+
+       remove)
+               postrm_remove
+       ;;
+
+
+       upgrade|disappear|failed-upgrade|abort-install|abort-upgrade)
+       ;;
+
+       *)
+               echo "postrm called with unknown argument \`$1'" >&2
+               exit 1
+       ;;
+esac
+
+# dh_installdeb will replace this with shell code automatically
+# generated by other debhelper scripts.
+
+#DEBHELPER#
+
+exit 0
diff --git a/debian/networking.default b/debian/networking.default
new file mode 100644 (file)
index 0000000..8b0474c
--- /dev/null
@@ -0,0 +1,17 @@
+#
+#
+# Parameters for the /etc/init.d/networking script
+#
+#
+
+# Change the below to yes if you want verbose logging to be enabled
+VERBOSE="no"
+
+# Change the below to yes if you want debug logging to be enabled
+DEBUG="no"
+
+# Change the below to yes if you want logging to go to syslog
+SYSLOG="no"
+
+# Exclude interfaces
+EXCLUDE_INTERFACES=
diff --git a/debian/networking.init b/debian/networking.init
new file mode 100644 (file)
index 0000000..286102a
--- /dev/null
@@ -0,0 +1,186 @@
+#!/bin/bash
+### BEGIN INIT INFO
+# Provides:          networking ifupdown
+# Required-Start:    mountkernfs $local_fs urandom
+# Required-Stop:     $local_fs
+# Default-Start:     S
+# Default-Stop:      0 1 6
+# Short-Description: Raise network interfaces.
+# Description:       Prepare /run/network directory, ifstate file and raise network interfaces, or take them down.
+### END INIT INFO
+
+PATH="/sbin:/bin"
+RUN_DIR="/run/network"
+IFSTATE="$RUN_DIR/ifstate"
+
+NAME=networking
+SCRIPTNAME=/etc/init.d/$NAME
+
+[ -x /sbin/ifup ] || exit 0
+[ -x /sbin/ifdown ] || exit 0
+
+. /lib/lsb/init-functions
+
+CONFIGURE_INTERFACES=yes
+
+EXTRA_ARGS=
+
+[ -f /etc/default/networking ] && . /etc/default/networking
+
+[ "$VERBOSE" = yes ] && EXTRA_ARGS=-v
+[ "$DEBUG" = yes ] && EXTRA_ARGS="$EXTRA_ARGS -d"
+[ "$SYSLOG" = yes ] && EXTRA_ARGS="$EXTRA_ARGS --syslog"
+
+perf_options() {
+    # At bootup lets set perfmode
+    [ -f /var/tmp/network/ifstatenew ] && echo -n "" && return
+
+    echo -n "--perfmode"
+}
+
+process_exclusions() {
+    set -- $EXCLUDE_INTERFACES
+    exclusions=""
+    for d
+    do
+       exclusions="-X $d $exclusions"
+    done
+    echo $exclusions
+}
+
+check_network_file_systems() {
+    [ -e /proc/mounts ] || return 0
+
+    if [ -e /etc/iscsi/iscsi.initramfs ]; then
+       log_warning_msg "not deconfiguring network interfaces: iSCSI root is mounted."
+       exit 0
+    fi
+
+    while read DEV MTPT FSTYPE REST; do
+       case $DEV in
+       /dev/nbd*|/dev/nd[a-z]*|/dev/etherd/e*)
+           log_warning_msg "not deconfiguring network interfaces: network devices still mounted."
+           exit 0
+           ;;
+       esac
+       case $FSTYPE in
+       nfs|nfs4|smbfs|ncp|ncpfs|cifs|coda|ocfs2|gfs|pvfs|pvfs2|fuse.httpfs|fuse.curlftpfs)
+           log_warning_msg "not deconfiguring network interfaces: network file systems still mounted."
+           exit 0
+           ;;
+       esac
+    done < /proc/mounts
+}
+
+check_network_swap() {
+    [ -e /proc/swaps ] || return 0
+
+    while read DEV MTPT FSTYPE REST; do
+       case $DEV in
+       /dev/nbd*|/dev/nd[a-z]*|/dev/etherd/e*)
+           log_warning_msg "not deconfiguring network interfaces: network swap still mounted."
+           exit 0
+           ;;
+       esac
+    done < /proc/swaps
+}
+
+ifup_hotplug () {
+    if [ -d /sys/class/net ]
+    then
+           ifaces=$(for iface in $(ifquery --list --allow=hotplug 2>/dev/null)
+                           do
+                                   link=${iface##:*}
+                                   link=${link##.*}
+                                   if [ -e "/sys/class/net/$link" ] && [ "$(cat /sys/class/net/$link/operstate)" = up ]
+                                   then
+                                           echo "$iface"
+                                   fi
+                           done)
+           if [ -n "$ifaces" ]
+           then
+               ifup $ifaces "$@" || true
+           fi
+    fi
+}
+
+ifupdown_init() {
+       [ ! -e /run/network ] && mkdir -p /run/network &>/dev/null
+       [ ! -e /etc/network/run ] && \
+               ln -sf /run/network /etc/network/run &>/dev/null
+}
+
+case "$1" in
+start)
+       ifupdown_init
+       if [ "$CONFIGURE_INTERFACES" = no ]
+       then
+           log_action_msg "Not configuring network interfaces, see /etc/default/networking"
+           exit 0
+       fi
+       set -f
+       exclusions=$(process_exclusions)
+       perfoptions=$(perf_options)
+       log_action_begin_msg "Configuring network interfaces"
+       ifup -a $EXTRA_ARGS $exclusions $perfoptions 
+       log_action_end_msg $?
+       ;;
+
+stop)
+       ifupdown_init
+       check_network_file_systems
+       check_network_swap
+       exclusions=$(process_exclusions)
+
+       log_action_begin_msg "Deconfiguring network interfaces"
+       ifdown -a $EXTRA_ARGS $exclusions
+       log_action_end_msg $?
+       ;;
+
+reload)
+
+       ifupdown_init
+       log_action_begin_msg "Reloading network interfaces configuration"
+
+       ifreload -a $EXTRA_ARGS
+       log_action_end_msg $?
+       ;;
+
+reload-currently-up)
+
+       ifupdown_init
+       log_action_begin_msg "Reloading currently up network interfaces configuration"
+
+       ifreload --currently-up $EXTRA_ARGS
+       log_action_end_msg $?
+       ;;
+
+force-reload)
+
+       ifupdown_init
+
+       log_action_begin_msg "Reloading network interfaces configuration"
+       ifreload -f -a $EXTRA_ARGS
+       log_action_end_msg $?
+       ;;
+
+restart)
+       ifupdown_init
+
+       set -f
+       exclusions=$(process_exclusions)
+       log_action_begin_msg "Reconfiguring network interfaces"
+       ifdown -a $EXTRA_ARGS $exclusions || true
+       ifup -a $EXTRA_ARGS $exclusions
+       log_action_end_msg $?
+       ;;
+
+*)
+       echo "Usage: /etc/init.d/networking {start|stop|reload|restart|force-reload}"
+       exit 1
+       ;;
+esac
+
+exit 0
+
+# vim: noet ts=8
diff --git a/debian/python-ifupdown2.postinst b/debian/python-ifupdown2.postinst
deleted file mode 100644 (file)
index cf61919..0000000
+++ /dev/null
@@ -1,114 +0,0 @@
-#!/bin/sh
-# postinst script for ifupdown2
-#
-# see: dh_installdeb(1)
-
-set -e
-
-# summary of how this script can be called:
-#        * <postinst> `configure' <most-recently-configured-version>
-#        * <old-postinst> `abort-upgrade' <new version>
-#        * <conflictor's-postinst> `abort-remove' `in-favour' <package>
-#          <new-version>
-#        * <postinst> `abort-remove'
-#        * <deconfigured's-postinst> `abort-deconfigure' `in-favour'
-#          <failed-install-package> <version> `removing'
-#          <conflicting-package> <version>
-# for details, see http://www.debian.org/doc/debian-policy/ or
-# the debian-policy package
-
-process_udev()
-{
-    # override default udev bridge and hotplug rules because they interfere with
-    # networking init script
-    udev_user_rulesdir=/etc/udev/rules.d/
-    udev_sys_rulesdir=/lib/udev/rules.d/
-    if [ -e $udev_user_rulesdir ]; then
-        udev_ifupdown2_overrides="80-networking.rules
-        60-bridge-network-interface.rules"
-        for u in ${udev_ifupdown2_overrides}
-        do
-            if [ -e ${udev_sys_rulesdir}/$u -a ! -e ${udev_user_rulesdir}/$u ]; then
-                (cd ${udev_user_rulesdir} && ln -sf /dev/null $u)
-            fi
-        done
-    fi
-}
-
-MYNAME="${0##*/}"
-
-report() { echo "${MYNAME}: $*" ; }
-report_warn() { report "Warning: $*" >&2 ; }
-report_err() { report "Error: $*" >&2 ; }
-
-case "$1" in
-    configure)
-        # Create /etc/network/run
-        [ -d /run/network ] || mkdir -p /run/network
-
-        # for backward compatibility
-        if [ ! -f /etc/network/run ]; then
-            ln -sf /run/network /etc/network/run
-        fi
-
-        ln -sf /usr/share/python-ifupdown2/generate_interfaces.py \
-            /usr/share/doc/python-ifupdown2/examples/generate_interfaces.py
-
-        [ -d /etc/network/if-pre-up.d ] || mkdir -p /etc/network/if-pre-up.d
-        [ -d /etc/network/if-up.d ] || mkdir -p /etc/network/if-up.d
-        [ -d /etc/network/if-post-up.d ] || mkdir -p /etc/network/if-post-up.d
-
-        [ -d /etc/network/if-pre-down.d ] || mkdir -p /etc/network/if-pre-down.d
-        [ -d /etc/network/if-down.d ] || mkdir -p /etc/network/if-down.d
-        [ -d /etc/network/if-post-down.d ] || mkdir -p /etc/network/if-post-down.d
-
-
-        # Generic stuff done on all configurations
-        if [ -f /etc/network/interfaces ] ; then
-            # TODO: This should be handled with debconf and the script
-            # could introduce the line there directly
-            if ! grep -q "^[[:space:]]*iface[[:space:]]\+lo0\?[[:space:]]\+inet[[:space:]]\+loopback\>" /etc/network/interfaces ; then
-                report_warn "No 'iface lo' definition found in /etc/network/interfaces"
-            fi
-
-            if ! grep -q "^[[:space:]]*\(allow-\|\)auto[[:space:]]\+\(.*[[:space:]]\+\|\)lo0\?\([[:space:]]\+\|$\)" /etc/network/interfaces ; then
-                report_warn "No 'auto lo' statement found in /etc/network/interfaces"
-            fi
-        else  # ! -f /etc/network/interfaces
-            if [ -z "$2" ]; then
-                echo "Creating /etc/network/interfaces."
-                echo "# interfaces(5) file used by ifup(8) and ifdown(8)" > /etc/network/interfaces
-                echo "auto lo" >> /etc/network/interfaces
-                    echo "iface lo inet loopback" >> /etc/network/interfaces
-            else
-                    report_warn "/etc/network/interfaces does not exist"
-            fi
-        fi
-
-        [ -e /sbin/ifup ] || ln -sf /sbin/ifupdown /sbin/ifup
-        [ -e /sbin/ifdown ] || ln -sf /sbin/ifupdown /sbin/ifdown
-        [ -e /sbin/ifquery ] || ln -sf /sbin/ifupdown /sbin/ifquery
-        [ -e /sbin/ifreload ] || ln -sf /sbin/ifupdown /sbin/ifreload
-
-        (cd /usr/share/man/man8/ && ln -sf /usr/share/man/man8/ifup.8.gz ifdown.8.gz)
-
-        mkdir -p /etc/network/interfaces.d/
-        process_udev
-        update-rc.d networking start 40 S . start 35 0 6 . >/dev/null
-        ;;
-
-    abort-upgrade|abort-remove|abort-deconfigure)
-        ;;
-
-    *)
-        echo "postinst called with unknown argument \`$1'" >&2
-        exit 1
-        ;;
-esac
-
-# dh_installdeb will replace this with shell code automatically
-# generated by other debhelper scripts.
-
-#DEBHELPER#
-
-exit 0
diff --git a/debian/python-ifupdown2.postrm b/debian/python-ifupdown2.postrm
deleted file mode 100644 (file)
index 6e6ab05..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-#!/bin/sh
-# postrm script for ifupdown2
-#
-# see: dh_installdeb(1)
-
-set -e
-
-# summary of how this script can be called:
-#        * <postrm> `remove'
-#        * <postrm> `purge'
-#        * <old-postrm> `upgrade' <new-version>
-#        * <new-postrm> `failed-upgrade' <old-version>
-#        * <new-postrm> `abort-install'
-#        * <new-postrm> `abort-install' <old-version>
-#        * <new-postrm> `abort-upgrade' <old-version>
-#        * <disappearer's-postrm> `disappear' <overwriter>
-#          <overwriter-version>
-# for details, see http://www.debian.org/doc/debian-policy/ or
-# the debian-policy package
-
-process_udev()
-{
-    udevlink=$(readlink /etc/udev/rules.d/80-networking.rules 2>/dev/null || true)
-    [ -n "$udevlink" -a "$udevlink" = "/dev/null" ] && rm -f /etc/udev/rules.d/80-networking.rules
-    udevlink=$(readlink /etc/udev/rules.d/60-bridge-network-interface.rules 2>/dev/null || true)
-    [ -n "$udevlink" -a "$udevlink" = "/dev/null" ] && rm -f /etc/udev/rules.d/60-bridge-network-interface.rules
-}
-
-postrm_remove()
-{
-       rm -f /sbin/ifup /sbin/ifdown /sbin/ifquery
-    process_udev
-       update-rc.d networking remove >/dev/null
-}
-
-# Note: We don't remove /etc/network/interfaces
-postrm_purge()
-{
-       rm -f /var/tmp/network/ifstatenew
-       if [ -L /etc/network/run ] ; then
-               rm -f /etc/network/run
-       elif [ -d /etc/network/run ] ; then
-               rmdir --ignore-fail-on-non-empty /etc/network/run
-       fi
-}
-
-case "$1" in
-       purge)
-               postrm_purge
-       ;;
-
-       remove)
-               postrm_remove
-       ;;
-
-
-       upgrade|disappear|failed-upgrade|abort-install|abort-upgrade)
-       ;;
-
-       *)
-               echo "postrm called with unknown argument \`$1'" >&2
-               exit 1
-       ;;
-esac
-
-# dh_installdeb will replace this with shell code automatically
-# generated by other debhelper scripts.
-
-#DEBHELPER#
-
-exit 0
diff --git a/debian/python-ifupdown2.preinst b/debian/python-ifupdown2.preinst
deleted file mode 100755 (executable)
index 3fcaed1..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-#!/bin/sh
-# preinst script for newpkg
-#
-# see: dh_installdeb(1)
-
-set -e
-
-# summary of how this script can be called:
-#        * <new-preinst> `install'
-#        * <new-preinst> `install' <old-version>
-#        * <new-preinst> `upgrade' <old-version>
-#        * <old-preinst> `abort-upgrade' <new-version>
-# for details, see http://www.debian.org/doc/debian-policy/ or
-# the debian-policy package
-
-preinst_upgrade()
-{
-       local oldver="$1"
-       local udev_user_rulesdir="/etc/udev/rules.d"
-
-       # we have to fixup the filesystem here as previous packages of
-       # ifupdown2 introduced a bug in the postrm script that require
-       # these files to exist, otherwise the postrm script will always
-       # fail.
-       local badver="0.1-cl2.5+2"
-       if dpkg --compare-versions "${oldver}" "lt" "${badver}"; then
-               local files="${udev_user_rulesdir}/80-networking.rules
-                       ${udev_user_rulesdir}/60-bridge-network-interface.rules"
-               for f in ${files}; do
-                       echo "touching udev rule: ${f}"
-                       test ! -e "${f}" && ln -s /dev/null "${f}" || \
-                               /bin/echo -e "\tudev rule exists leaving"
-               done
-       fi
-}
-
-case "$1" in
-       install|upgrade)
-               preinst_upgrade "$2"
-       ;;
-
-       abort-upgrade)
-       ;;
-
-       *)
-               echo "preinst called with unknown argument \`$1'" >&2
-               exit 1
-       ;;
-esac
-
-# dh_installdeb will replace this with shell code automatically
-# generated by other debhelper scripts.
-
-#DEBHELPER#
-
-exit 0
diff --git a/debian/rules b/debian/rules
new file mode 100755 (executable)
index 0000000..25a747d
--- /dev/null
@@ -0,0 +1,16 @@
+#!/usr/bin/make -f
+
+#export DH_VERBOSE=1
+export PYBUILD_NAME=ifupdown2
+export PYBUILD_INSTALL_ARGS=--install-lib=/usr/share/ifupdown2 --install-scripts=/usr/share/ifupdown2
+
+%:
+       dh $@ --with python2 --buildsystem=pybuild
+
+override_dh_installman:
+       ./scripts/genmanpages.sh ./man.rst ./man
+       dh_installman
+
+override_dh_installinit:
+       dh_systemd_enable --name=networking
+       dh_installinit --name=networking --no-start
diff --git a/debian/source/format b/debian/source/format
new file mode 100644 (file)
index 0000000..89ae9db
--- /dev/null
@@ -0,0 +1 @@
+3.0 (native)
diff --git a/docs/README.rst b/docs/README.rst
new file mode 100644 (file)
index 0000000..8ab8252
--- /dev/null
@@ -0,0 +1,78 @@
+python-ifupdown2
+================
+
+This package is a replacement for the debian ifupdown package.
+It is ifupdown re-written in python. It maintains the original ifupdown
+pluggable architecture and extends it further.
+
+The python-ifupdown2 package provides the infrastructure for
+parsing /etc/network/interfaces file, loading, scheduling and state
+management of interfaces.
+
+It dynamically loads python modules from /usr/share/ifupdownmodules (provided
+ by the python-ifupdown2-addons package). To remain compatible with other
+packages that depend on ifupdown, it also executes scripts under /etc/network/.
+To make the transition smoother, a python module under
+/usr/share/ifupdownmodules will override a script by the same name under
+/etc/network/.
+
+It publishes an interface object which is passed to all loadble python
+modules. For more details on adding a addon module, see the section on
+adding python modules.
+
+
+pluggable python modules:
+=========================
+Unlike original ifupdown, all interface configuration is moved to external
+python modules. That includes inet, inet6 and dhcp configurations.
+
+A set of default modules are provided by the python-ifupdown2-addons deb.
+
+python-ifupdown2 expects a few things from the pluggable modules:
+- the module should implement a class by the same name
+- the interface object (class iface) and the operation to be performed is
+  passed to the modules
+- the python addon class should provide a few methods:
+       - run() : method to configure the interface.
+       - get_ops() : must return a list of operations it supports.
+               eg: 'pre-up', 'post-down'
+       - get_dependent_ifacenames() : must return a list of interfaces the
+         interface is dependent on. This is used to build the dependency list
+         for sorting and executing interfaces in dependency order.
+       - if the module supports -r option to ifquery, ie ability to construct the
+      ifaceobj from running state, it can optionally implement the
+      get_dependent_ifacenames_running() method, to return the list of
+      dependent interfaces derived from running state of the interface.
+      This is different from get_dependent_ifacenames() where the dependent
+      interfaces are derived from the interfaces config file (provided by the
+      user).
+
+Example: Address handling module /usr/share/ifupdownaddons/address.py
+
+
+build
+=====
+- get source
+
+- install build dependencies:
+    apt-get install python-stdeb
+    apt-get install python-docutils
+
+- cd <python-ifupdown2 sourcedir> && ./build.sh
+
+  (generates python-ifupdown2-<ver>.deb)
+
+install
+=======
+
+- remove existing ifupdown package
+  dpkg -r ifupdown
+
+- install python-ifupdown2 using `dpkg -i`
+
+- or install from deb
+    dpkg -i python-ifupdown2-<ver>.deb
+
+- note that python-ifupdown2 requires python-ifupdown2-addons package to
+  function. And python-ifupdown2-addons deb has an install dependency on
+  python-ifupdown2
diff --git a/sbin/ifupdown b/sbin/ifupdown
deleted file mode 100755 (executable)
index b3415b8..0000000
+++ /dev/null
@@ -1,522 +0,0 @@
-#!/usr/bin/python
-#
-# Copyright 2014 Cumulus Networks, Inc. All rights reserved.
-# Author: Roopa Prabhu, roopa@cumulusnetworks.com
-#
-# ifupdown --
-#    tool to configure network interfaces
-#
-import sys
-import os
-import argcomplete
-import argparse
-import ConfigParser
-import StringIO
-import logging
-import logging.handlers
-import resource
-from ifupdown.ifupdownmain import *
-from ifupdown.utils import *
-
-lockfile="/run/network/.lock"
-configfile="/etc/network/ifupdown2/ifupdown2.conf"
-configmap_g=None
-logger = None
-interfacesfileiobuf=None
-interfacesfilename=None
-ENVPATH = "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
-
-def run_up(args):
-    logger.debug('args = %s' %str(args))
-
-    try:
-        iflist = args.iflist
-        if len(args.iflist) == 0:
-            iflist = None
-        logger.debug('creating ifupdown object ..')
-        cachearg=(False if (iflist or args.nocache or
-                            args.perfmode or args.noact)
-                            else True)
-        ifupdown_handle = ifupdownMain(config=configmap_g,
-                                       force=args.force,
-                                       withdepends=args.withdepends,
-                                       perfmode=args.perfmode,
-                                       dryrun=args.noact,
-                                       cache=cachearg,
-                                       addons_enable=not args.noaddons,
-                                       statemanager_enable=not args.noaddons,
-                                       interfacesfile=interfacesfilename,
-                                       interfacesfileiobuf=interfacesfileiobuf,
-                                       interfacesfileformat=args.interfacesfileformat)
-        if args.noaddons:
-            ifupdown_handle.up(['up'], args.all, args.CLASS, iflist,
-                               excludepats=args.excludepats,
-                               printdependency=args.printdependency,
-                               syntaxcheck=args.syntaxcheck, type=args.type,
-                               skipupperifaces=args.skipupperifaces)
-        else:
-            ifupdown_handle.up(['pre-up', 'up', 'post-up'],
-                               args.all, args.CLASS, iflist,
-                               excludepats=args.excludepats,
-                               printdependency=args.printdependency,
-                               syntaxcheck=args.syntaxcheck, type=args.type,
-                               skipupperifaces=args.skipupperifaces)
-    except:
-        raise
-
-def run_down(args):
-    logger.debug('args = %s' %str(args))
-
-    try:
-        iflist = args.iflist
-        logger.debug('creating ifupdown object ..')
-        ifupdown_handle = ifupdownMain(config=configmap_g, force=args.force,
-                                       withdepends=args.withdepends,
-                                       perfmode=args.perfmode,
-                                       dryrun=args.noact,
-                                       addons_enable=not args.noaddons,
-                                       statemanager_enable=not args.noaddons,
-                                       interfacesfile=interfacesfilename,
-                                       interfacesfileiobuf=interfacesfileiobuf,
-                                       interfacesfileformat=args.interfacesfileformat)
-
-        ifupdown_handle.down(['pre-down', 'down', 'post-down'],
-                             args.all, args.CLASS, iflist,
-                             excludepats=args.excludepats,
-                             printdependency=args.printdependency,
-                             usecurrentconfig=args.usecurrentconfig,
-                             type=args.type)
-    except:
-        raise
-
-def run_query(args):
-    logger.debug('args = %s' %str(args))
-
-    try:
-        iflist = args.iflist
-        if args.checkcurr:
-            qop='query-checkcurr'
-        elif args.running:
-            qop='query-running'
-        elif args.raw:
-            qop='query-raw'
-        elif args.syntaxhelp:
-            qop = 'query-syntax'
-        elif args.printdependency:
-            qop = 'query-dependency'
-        elif args.printsavedstate:
-            qop = 'query-savedstate'
-        else:
-            qop='query'
-        cachearg=(False if (iflist or args.nocache or
-                            args.perfmode or args.syntaxhelp or
-                            (qop != 'query-checkcurr' and
-                            qop != 'query-running')) else True)
-        if not iflist and qop == 'query-running':
-            iflist = [i for i in os.listdir('/sys/class/net/')
-                        if os.path.isdir('/sys/class/net/%s' %i)]
-        logger.debug('creating ifupdown object ..')
-        ifupdown_handle = ifupdownMain(config=configmap_g,
-                                       withdepends=args.withdepends,
-                                       perfmode=args.perfmode,
-                                       cache=cachearg,
-                                       interfacesfile=interfacesfilename,
-                                       interfacesfileiobuf=interfacesfileiobuf,
-                                       interfacesfileformat=args.interfacesfileformat)
-
-        ifupdown_handle.query([qop], args.all, args.CLASS, iflist,
-                              excludepats=args.excludepats,
-                              printdependency=args.printdependency,
-                              format=args.format, type=args.type)
-    except:
-        raise
-
-def run_reload(args):
-    logger.debug('args = %s' %str(args))
-
-    try:
-        logger.debug('creating ifupdown object ..')
-        ifupdown_handle = ifupdownMain(config=configmap_g,
-                                       interfacesfile=interfacesfilename,
-                                       withdepends=args.withdepends,
-                                       perfmode=args.perfmode)
-        ifupdown_handle.reload(['pre-up', 'up', 'post-up'],
-                               ['pre-down', 'down', 'post-down'],
-                               auto=args.all, allow=args.CLASS, ifacenames=None,
-                               excludepats=args.excludepats,
-                               usecurrentconfig=args.usecurrentconfig,
-                               syntaxcheck=args.syntaxcheck,
-                               currentlyup=args.currentlyup)
-    except:
-        raise
-
-def init(args):
-    global logger
-    global interfacesfileiobuf
-    global interfacesfilename
-
-    log_level = logging.WARNING
-    if args.verbose:
-        log_level = logging.INFO
-    if args.debug:
-        log_level = logging.DEBUG
-
-    try:
-        if hasattr(args, 'syslog') and args.syslog:
-            root_logger = logging.getLogger()
-            syslog_handler = logging.handlers.SysLogHandler(address='/dev/log',
-                             facility=logging.handlers.SysLogHandler.LOG_DAEMON)
-            logging.addLevelName(logging.ERROR, 'error')
-            logging.addLevelName(logging.WARNING, 'warning')
-            logging.addLevelName(logging.DEBUG, 'debug')
-            logging.addLevelName(logging.INFO, 'info')
-            root_logger.setLevel(log_level)
-            syslog_handler.setFormatter(logging.Formatter(
-                '%(name)s: %(levelname)s: %(message)s'))
-            root_logger.addHandler(syslog_handler)
-            logger = logging.getLogger('ifupdown')
-        else:
-            logging.basicConfig(level=log_level,
-                format='%(levelname)s: %(message)s')
-            logging.addLevelName(logging.ERROR, 'error')
-            logging.addLevelName(logging.WARNING, 'warning')
-            logging.addLevelName(logging.DEBUG, 'debug')
-            logging.addLevelName(logging.INFO, 'info')
-            logger = logging.getLogger('ifupdown')
-    except:
-        raise
-
-    if hasattr(args, 'interfacesfile') and args.interfacesfile != None:
-        # Check to see if -i option is allowed by config file
-        # But for ifquery, we will not check this
-        if (not sys.argv[0].endswith('ifquery') and
-                configmap_g.get('disable_cli_interfacesfile','0') == '1'):
-            logger.error('disable_cli_interfacesfile is set so users '
-                         'not allowed to specify interfaces file on cli.')
-            exit(1)
-        if args.interfacesfile == '-':
-            # If interfaces file is stdin, read
-            interfacesfileiobuf = sys.stdin.read()
-        else:
-            interfacesfilename = args.interfacesfile
-    else:
-        # if the ifupdown2 config file does not have it, default to standard
-        interfacesfilename = configmap_g.get('default_interfaces_configfile',
-                                             '/etc/network/interfaces')
-
-
-
-
-def deinit():
-    {}
-
-def update_argparser(argparser):
-    """ base parser, common to all commands """
-
-    argparser.add_argument('-a', '--all', action='store_true', required=False,
-                help='process all interfaces marked \"auto\"')
-    argparser.add_argument('iflist', metavar='IFACE',
-                nargs='*', help='interface list separated by spaces. ' +
-                'IFACE list is mutually exclusive with -a option.')
-    argparser.add_argument('-v', '--verbose', dest='verbose',
-                action='store_true', help='verbose')
-    argparser.add_argument('-d', '--debug', dest='debug',
-                action='store_true',
-                help='output debug info')
-    argparser.add_argument('-q', '--quiet', dest='quiet',
-                action='store_true',
-                help=argparse.SUPPRESS)
-    argparser.add_argument('--allow', dest='CLASS', 
-                help='ignore non-\"allow-CLASS\" interfaces')
-    argparser.add_argument('-w', '--with-depends', dest='withdepends',
-                action='store_true', help='run with all dependent interfaces.'+
-                ' This option is redundant when \'-a\' is specified. With ' +
-                '\'-a\' interfaces are always executed in dependency order')
-    argparser.add_argument('--perfmode', dest='perfmode',
-                action='store_true', help=argparse.SUPPRESS)
-    #argparser.add_argument('-j', '--jobs', dest='jobs', type=int,
-    #            default=-1, choices=range(1,12), help=argparse.SUPPRESS)
-    argparser.add_argument('--nocache', dest='nocache', action='store_true',
-                help=argparse.SUPPRESS)
-    argparser.add_argument('-X', '--exclude', dest='excludepats',
-                action='append',
-                help='Exclude interfaces from the list of interfaces' +
-                ' to operate on. Can be specified multiple times.')
-    argparser.add_argument('-i', '--interfaces', dest='interfacesfile',
-                default=None,
-                help='Specify interfaces file instead of file defined ' +
-                'in ifupdown2.conf file')
-    argparser.add_argument('-t', '--interfaces-format',
-                dest='interfacesfileformat',
-                default='native',
-                choices=['native', 'json'],
-                help='interfaces file format')
-    argparser.add_argument('-T', '--type',
-                dest='type',
-                default=None,
-                choices=['iface', 'vlan'],
-                help='type of interface entry (iface or vlan).' +
-                     'This option can be used in case of ambiguity between ' +
-                     'a vlan interface and an iface interface of the same name')
-
-def update_ifupdown_argparser(argparser):
-    """ common arg parser for ifup and ifdown """
-    argparser.add_argument('-f', '--force', dest='force',
-                action='store_true',
-                help='force run all operations')
-    argparser.add_argument('-l', '--syslog', dest='syslog',
-                action='store_true',
-                help=argparse.SUPPRESS)
-    group = argparser.add_mutually_exclusive_group(required=False)
-    group.add_argument('-n', '--no-act', dest='noact',
-                action='store_true', help='print out what would happen,' +
-                'but don\'t do it')
-    group.add_argument('-p', '--print-dependency',
-                dest='printdependency', choices=['list', 'dot'],
-                help='print iface dependency')
-    group.add_argument('--no-scripts', '--admin-state',
-                dest='noaddons',  action='store_true',
-                help='dont run any addon modules/scripts. Only bring the ' +
-                    'interface administratively up/down')
-
-def update_ifup_argparser(argparser):
-    argparser.add_argument('-s', '--syntax-check', dest='syntaxcheck',
-                action='store_true',
-                help='Only run the interfaces file parser')
-    argparser.add_argument('-k', '--skip-upperifaces', dest='skipupperifaces',
-                action='store_true',
-                help='ifup by default tries to add newly created interfaces' +
-                ' into its upper/parent interfaces. Eg. if a bridge port is' +
-                ' created as a result of ifup on the port, ifup automatically' +
-                ' adds the port to the bridge. This option can be used to ' +
-                'disable this default behaviour')
-    update_ifupdown_argparser(argparser)
-
-def update_ifdown_argparser(argparser):
-    update_ifupdown_argparser(argparser)
-    argparser.add_argument('-u', '--use-current-config',
-                dest='usecurrentconfig',  action='store_true',
-                help='By default ifdown looks at the saved state for ' +
-                'interfaces to bring down. This option allows ifdown to ' +
-                'look at the current interfaces file. Useful when your ' +
-                'state file is corrupted or you want down to use the latest '
-                'from the interfaces file')
-
-def update_ifquery_argparser(argparser):
-    """ arg parser for ifquery options """
-
-    # -l is same as '-a', only here for backward compatibility
-    argparser.add_argument('-l', '--list', action='store_true', dest='all',
-                help=argparse.SUPPRESS)
-    group = argparser.add_mutually_exclusive_group(required=False)
-    group.add_argument('-r', '--running', dest='running',
-                       action='store_true',
-                       help='query running state of an interface')
-    group.add_argument('-c', '--check', dest='checkcurr',
-                       action='store_true',
-                       help='check interface file contents against ' +
-                       'running state of an interface')
-    group.add_argument('-x', '--raw', action='store_true', dest='raw',
-                       help='print raw config file entries')
-    group.add_argument('--print-savedstate', action='store_true',
-                       dest='printsavedstate',
-                       help=argparse.SUPPRESS)
-    argparser.add_argument('-o', '--format', dest='format', default='native',
-                           choices=['native', 'json'],
-                           help='interface display format')
-    argparser.add_argument('-p', '--print-dependency',
-                           dest='printdependency', choices=['list', 'dot'],
-                           help='print interface dependency')
-    argparser.add_argument('-s', '--syntax-help', action='store_true',
-                           dest='syntaxhelp',
-                           help='print supported interface config syntax')
-
-def update_ifreload_argparser(argparser):
-    """ parser for ifreload """
-    group = argparser.add_mutually_exclusive_group(required=True)
-    group.add_argument('-a', '--all', action='store_true',
-                help='process all interfaces marked \"auto\"')
-    group.add_argument('-c', '--currently-up', dest='currentlyup',
-                action='store_true',
-                help='only reload auto and other interfaces that are ' +
-                'currently up')
-    group.add_argument('--allow', dest='CLASS',
-                help='ignore non-\"allow-CLASS\" interfaces')
-    argparser.add_argument('iflist', metavar='IFACE',
-                nargs='*', help=argparse.SUPPRESS)
-    argparser.add_argument('-n', '--no-act', dest='noact',
-                action='store_true', help=argparse.SUPPRESS)
-    argparser.add_argument('-v', '--verbose', dest='verbose',
-                action='store_true', help='verbose')
-    argparser.add_argument('-d', '--debug', dest='debug',
-                action='store_true',
-                help='output debug info')
-    argparser.add_argument('-w', '--with-depends', dest='withdepends',
-                action='store_true', help=argparse.SUPPRESS)
-    argparser.add_argument('--perfmode', dest='perfmode',
-                action='store_true', help=argparse.SUPPRESS)
-    argparser.add_argument('--nocache', dest='nocache', action='store_true',
-                help=argparse.SUPPRESS)
-    argparser.add_argument('-X', '--exclude', dest='excludepats',
-                action='append',
-                help=argparse.SUPPRESS)
-    #argparser.add_argument('-j', '--jobs', dest='jobs', type=int,
-    #            default=-1, choices=range(1,12), help=argparse.SUPPRESS)
-    #argparser.add_argument('-i', '--interfaces', dest='interfacesfile',
-    #            default='/etc/network/interfaces',
-    #            help='use interfaces file instead of default ' +
-    #            '/etc/network/interfaces')
-    argparser.add_argument('-u', '--use-current-config',
-                dest='usecurrentconfig',  action='store_true',
-                help='By default ifreload looks at saved state for ' +
-                'interfaces to bring down. With this option ifreload will'
-                ' only look at the current interfaces file. Useful when your ' +
-                'state file is corrupted or you want down to use the latest '
-                'from the interfaces file')
-    argparser.add_argument('-l', '--syslog', dest='syslog',
-                action='store_true',
-                help=argparse.SUPPRESS)
-    argparser.add_argument('-f', '--force', dest='force',
-                action='store_true',
-                help='force run all operations')
-    argparser.add_argument('-s', '--syntax-check', dest='syntaxcheck',
-                action='store_true',
-                help='Only run the interfaces file parser')
-
-def parse_args(argsv, op):
-    if op == 'query':
-        descr = 'query interfaces (all or interface list)'
-    elif op == 'reload':
-        descr = 'reload interface configuration.'
-    else:
-        descr = 'interface management'
-    argparser = argparse.ArgumentParser(description=descr)
-    if op == 'reload':
-        update_ifreload_argparser(argparser)
-    else:
-        update_argparser(argparser)
-        if op == 'up':
-            update_ifup_argparser(argparser)
-        elif op == 'down':
-            update_ifdown_argparser(argparser)
-        elif op == 'query':
-            update_ifquery_argparser(argparser)
-        elif op == 'reload':
-            update_ifreload_argparser(argparser)
-    argcomplete.autocomplete(argparser)
-    return argparser.parse_args(argsv)
-
-handlers = {'up' : run_up,
-            'down' : run_down,
-            'query' : run_query,
-            'reload' : run_reload }
-
-def validate_args(op, args):
-    #if op == 'up' and args.syntaxcheck:
-    #    if args.iflist or args.all:
-    #        print 'ignoring interface options ..'
-    #    return True
-    if op == 'query' and args.syntaxhelp:
-        return True
-    if op == 'reload':
-        if not args.all and not args.currentlyup and not args.CLASS:
-            print '\'-a\' or \'-c\' or \'-allow\' option is required'
-            return False
-    elif (not args.iflist and
-            not args.all and not args.CLASS):
-        print '\'-a\' option or interface list are required'
-        return False
-    if args.iflist and args.all:
-        print '\'-a\' option and interface list are mutually exclusive'
-        return False
-    if op != 'reload' and args.CLASS and (args.all or args.iflist):
-        print ('\'--allow\' option is mutually exclusive ' +
-               'with interface list and \'-a\'')
-        return False
-    return True
-
-def read_config(args):
-    global configmap_g
-
-    config = open(configfile, 'r').read()
-    configStr = '[ifupdown2]\n' + config
-    configFP =  StringIO.StringIO(configStr)
-    parser = ConfigParser.RawConfigParser()
-    parser.readfp(configFP)
-    configmap_g = dict(parser.items('ifupdown2'))
-
-    # Preprocess config map
-    configval = configmap_g.get('multiple_vlan_aware_bridge_support', '0')
-    if configval == '0':
-        # if multiple bridges not allowed, set the bridge-vlan-aware
-        # attribute in the 'no_repeats' config, so that the ifupdownmain
-        # module can catch it appropriately
-        configmap_g['no_repeats'] = {'bridge-vlan-aware' : 'yes'}
-
-
-    configval = configmap_g.get('link_master_slave', '0')
-    if configval == '1':
-        # link_master_slave is only valid when all is set
-        if hasattr(args, 'all') and not args.all:
-            configmap_g['link_master_slave'] = '0'
-
-    configval = configmap_g.get('delay_admin_state_change', '0')
-    if configval == '1':
-        # reset link_master_slave if delay_admin_state_change is on
-        configmap_g['link_master_slave'] = '0'
-
-def main(argv):
-    """ main function """
-    args = None
-    try:
-        op = None
-        if argv[0].endswith('ifup'):
-            op = 'up'
-        elif argv[0].endswith('ifdown'):
-            op = 'down'
-        elif argv[0].endswith('ifquery'):
-            op = 'query'
-        elif argv[0].endswith('ifreload'):
-            op = 'reload'
-        else:
-            print ('Unexpected executable.' +
-                   ' Should be \'ifup\' or \'ifdown\' or \'ifquery\'')
-            exit(1)
-        # Command line arg parser
-        args = parse_args(argv[1:], op)
-        if not validate_args(op, args):
-            exit(1)
-
-        if not sys.argv[0].endswith('ifquery') and not os.geteuid() == 0:
-            print 'error: must be root to run this command'
-            exit(1)
-
-        if not sys.argv[0].endswith('ifquery') and not utils.lockFile(lockfile):
-            print 'Another instance of this program is already running.'
-            exit(0)
-
-        read_config(args)
-        init(args)
-        handlers.get(op)(args)
-    except Exception, e:
-        if not str(e):
-            exit(1)
-        if args and args.debug:
-            raise
-        else:
-            if logger:
-                logger.error(str(e))
-            else:
-                print str(e)
-            #if args and not args.debug:
-            #    print '\nrerun the command with \'-d\' for a detailed errormsg'
-        exit(1)
-    finally:
-        deinit()
-
-if __name__ == "__main__":
-
-    # required during boot
-    os.putenv('PATH', ENVPATH)
-    resource.setrlimit(resource.RLIMIT_CORE, (0,0))
-    main(sys.argv)
diff --git a/sbin/ifupdown2 b/sbin/ifupdown2
new file mode 100755 (executable)
index 0000000..b3415b8
--- /dev/null
@@ -0,0 +1,522 @@
+#!/usr/bin/python
+#
+# Copyright 2014 Cumulus Networks, Inc. All rights reserved.
+# Author: Roopa Prabhu, roopa@cumulusnetworks.com
+#
+# ifupdown --
+#    tool to configure network interfaces
+#
+import sys
+import os
+import argcomplete
+import argparse
+import ConfigParser
+import StringIO
+import logging
+import logging.handlers
+import resource
+from ifupdown.ifupdownmain import *
+from ifupdown.utils import *
+
+lockfile="/run/network/.lock"
+configfile="/etc/network/ifupdown2/ifupdown2.conf"
+configmap_g=None
+logger = None
+interfacesfileiobuf=None
+interfacesfilename=None
+ENVPATH = "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
+
+def run_up(args):
+    logger.debug('args = %s' %str(args))
+
+    try:
+        iflist = args.iflist
+        if len(args.iflist) == 0:
+            iflist = None
+        logger.debug('creating ifupdown object ..')
+        cachearg=(False if (iflist or args.nocache or
+                            args.perfmode or args.noact)
+                            else True)
+        ifupdown_handle = ifupdownMain(config=configmap_g,
+                                       force=args.force,
+                                       withdepends=args.withdepends,
+                                       perfmode=args.perfmode,
+                                       dryrun=args.noact,
+                                       cache=cachearg,
+                                       addons_enable=not args.noaddons,
+                                       statemanager_enable=not args.noaddons,
+                                       interfacesfile=interfacesfilename,
+                                       interfacesfileiobuf=interfacesfileiobuf,
+                                       interfacesfileformat=args.interfacesfileformat)
+        if args.noaddons:
+            ifupdown_handle.up(['up'], args.all, args.CLASS, iflist,
+                               excludepats=args.excludepats,
+                               printdependency=args.printdependency,
+                               syntaxcheck=args.syntaxcheck, type=args.type,
+                               skipupperifaces=args.skipupperifaces)
+        else:
+            ifupdown_handle.up(['pre-up', 'up', 'post-up'],
+                               args.all, args.CLASS, iflist,
+                               excludepats=args.excludepats,
+                               printdependency=args.printdependency,
+                               syntaxcheck=args.syntaxcheck, type=args.type,
+                               skipupperifaces=args.skipupperifaces)
+    except:
+        raise
+
+def run_down(args):
+    logger.debug('args = %s' %str(args))
+
+    try:
+        iflist = args.iflist
+        logger.debug('creating ifupdown object ..')
+        ifupdown_handle = ifupdownMain(config=configmap_g, force=args.force,
+                                       withdepends=args.withdepends,
+                                       perfmode=args.perfmode,
+                                       dryrun=args.noact,
+                                       addons_enable=not args.noaddons,
+                                       statemanager_enable=not args.noaddons,
+                                       interfacesfile=interfacesfilename,
+                                       interfacesfileiobuf=interfacesfileiobuf,
+                                       interfacesfileformat=args.interfacesfileformat)
+
+        ifupdown_handle.down(['pre-down', 'down', 'post-down'],
+                             args.all, args.CLASS, iflist,
+                             excludepats=args.excludepats,
+                             printdependency=args.printdependency,
+                             usecurrentconfig=args.usecurrentconfig,
+                             type=args.type)
+    except:
+        raise
+
+def run_query(args):
+    logger.debug('args = %s' %str(args))
+
+    try:
+        iflist = args.iflist
+        if args.checkcurr:
+            qop='query-checkcurr'
+        elif args.running:
+            qop='query-running'
+        elif args.raw:
+            qop='query-raw'
+        elif args.syntaxhelp:
+            qop = 'query-syntax'
+        elif args.printdependency:
+            qop = 'query-dependency'
+        elif args.printsavedstate:
+            qop = 'query-savedstate'
+        else:
+            qop='query'
+        cachearg=(False if (iflist or args.nocache or
+                            args.perfmode or args.syntaxhelp or
+                            (qop != 'query-checkcurr' and
+                            qop != 'query-running')) else True)
+        if not iflist and qop == 'query-running':
+            iflist = [i for i in os.listdir('/sys/class/net/')
+                        if os.path.isdir('/sys/class/net/%s' %i)]
+        logger.debug('creating ifupdown object ..')
+        ifupdown_handle = ifupdownMain(config=configmap_g,
+                                       withdepends=args.withdepends,
+                                       perfmode=args.perfmode,
+                                       cache=cachearg,
+                                       interfacesfile=interfacesfilename,
+                                       interfacesfileiobuf=interfacesfileiobuf,
+                                       interfacesfileformat=args.interfacesfileformat)
+
+        ifupdown_handle.query([qop], args.all, args.CLASS, iflist,
+                              excludepats=args.excludepats,
+                              printdependency=args.printdependency,
+                              format=args.format, type=args.type)
+    except:
+        raise
+
+def run_reload(args):
+    logger.debug('args = %s' %str(args))
+
+    try:
+        logger.debug('creating ifupdown object ..')
+        ifupdown_handle = ifupdownMain(config=configmap_g,
+                                       interfacesfile=interfacesfilename,
+                                       withdepends=args.withdepends,
+                                       perfmode=args.perfmode)
+        ifupdown_handle.reload(['pre-up', 'up', 'post-up'],
+                               ['pre-down', 'down', 'post-down'],
+                               auto=args.all, allow=args.CLASS, ifacenames=None,
+                               excludepats=args.excludepats,
+                               usecurrentconfig=args.usecurrentconfig,
+                               syntaxcheck=args.syntaxcheck,
+                               currentlyup=args.currentlyup)
+    except:
+        raise
+
+def init(args):
+    global logger
+    global interfacesfileiobuf
+    global interfacesfilename
+
+    log_level = logging.WARNING
+    if args.verbose:
+        log_level = logging.INFO
+    if args.debug:
+        log_level = logging.DEBUG
+
+    try:
+        if hasattr(args, 'syslog') and args.syslog:
+            root_logger = logging.getLogger()
+            syslog_handler = logging.handlers.SysLogHandler(address='/dev/log',
+                             facility=logging.handlers.SysLogHandler.LOG_DAEMON)
+            logging.addLevelName(logging.ERROR, 'error')
+            logging.addLevelName(logging.WARNING, 'warning')
+            logging.addLevelName(logging.DEBUG, 'debug')
+            logging.addLevelName(logging.INFO, 'info')
+            root_logger.setLevel(log_level)
+            syslog_handler.setFormatter(logging.Formatter(
+                '%(name)s: %(levelname)s: %(message)s'))
+            root_logger.addHandler(syslog_handler)
+            logger = logging.getLogger('ifupdown')
+        else:
+            logging.basicConfig(level=log_level,
+                format='%(levelname)s: %(message)s')
+            logging.addLevelName(logging.ERROR, 'error')
+            logging.addLevelName(logging.WARNING, 'warning')
+            logging.addLevelName(logging.DEBUG, 'debug')
+            logging.addLevelName(logging.INFO, 'info')
+            logger = logging.getLogger('ifupdown')
+    except:
+        raise
+
+    if hasattr(args, 'interfacesfile') and args.interfacesfile != None:
+        # Check to see if -i option is allowed by config file
+        # But for ifquery, we will not check this
+        if (not sys.argv[0].endswith('ifquery') and
+                configmap_g.get('disable_cli_interfacesfile','0') == '1'):
+            logger.error('disable_cli_interfacesfile is set so users '
+                         'not allowed to specify interfaces file on cli.')
+            exit(1)
+        if args.interfacesfile == '-':
+            # If interfaces file is stdin, read
+            interfacesfileiobuf = sys.stdin.read()
+        else:
+            interfacesfilename = args.interfacesfile
+    else:
+        # if the ifupdown2 config file does not have it, default to standard
+        interfacesfilename = configmap_g.get('default_interfaces_configfile',
+                                             '/etc/network/interfaces')
+
+
+
+
+def deinit():
+    {}
+
+def update_argparser(argparser):
+    """ base parser, common to all commands """
+
+    argparser.add_argument('-a', '--all', action='store_true', required=False,
+                help='process all interfaces marked \"auto\"')
+    argparser.add_argument('iflist', metavar='IFACE',
+                nargs='*', help='interface list separated by spaces. ' +
+                'IFACE list is mutually exclusive with -a option.')
+    argparser.add_argument('-v', '--verbose', dest='verbose',
+                action='store_true', help='verbose')
+    argparser.add_argument('-d', '--debug', dest='debug',
+                action='store_true',
+                help='output debug info')
+    argparser.add_argument('-q', '--quiet', dest='quiet',
+                action='store_true',
+                help=argparse.SUPPRESS)
+    argparser.add_argument('--allow', dest='CLASS', 
+                help='ignore non-\"allow-CLASS\" interfaces')
+    argparser.add_argument('-w', '--with-depends', dest='withdepends',
+                action='store_true', help='run with all dependent interfaces.'+
+                ' This option is redundant when \'-a\' is specified. With ' +
+                '\'-a\' interfaces are always executed in dependency order')
+    argparser.add_argument('--perfmode', dest='perfmode',
+                action='store_true', help=argparse.SUPPRESS)
+    #argparser.add_argument('-j', '--jobs', dest='jobs', type=int,
+    #            default=-1, choices=range(1,12), help=argparse.SUPPRESS)
+    argparser.add_argument('--nocache', dest='nocache', action='store_true',
+                help=argparse.SUPPRESS)
+    argparser.add_argument('-X', '--exclude', dest='excludepats',
+                action='append',
+                help='Exclude interfaces from the list of interfaces' +
+                ' to operate on. Can be specified multiple times.')
+    argparser.add_argument('-i', '--interfaces', dest='interfacesfile',
+                default=None,
+                help='Specify interfaces file instead of file defined ' +
+                'in ifupdown2.conf file')
+    argparser.add_argument('-t', '--interfaces-format',
+                dest='interfacesfileformat',
+                default='native',
+                choices=['native', 'json'],
+                help='interfaces file format')
+    argparser.add_argument('-T', '--type',
+                dest='type',
+                default=None,
+                choices=['iface', 'vlan'],
+                help='type of interface entry (iface or vlan).' +
+                     'This option can be used in case of ambiguity between ' +
+                     'a vlan interface and an iface interface of the same name')
+
+def update_ifupdown_argparser(argparser):
+    """ common arg parser for ifup and ifdown """
+    argparser.add_argument('-f', '--force', dest='force',
+                action='store_true',
+                help='force run all operations')
+    argparser.add_argument('-l', '--syslog', dest='syslog',
+                action='store_true',
+                help=argparse.SUPPRESS)
+    group = argparser.add_mutually_exclusive_group(required=False)
+    group.add_argument('-n', '--no-act', dest='noact',
+                action='store_true', help='print out what would happen,' +
+                'but don\'t do it')
+    group.add_argument('-p', '--print-dependency',
+                dest='printdependency', choices=['list', 'dot'],
+                help='print iface dependency')
+    group.add_argument('--no-scripts', '--admin-state',
+                dest='noaddons',  action='store_true',
+                help='dont run any addon modules/scripts. Only bring the ' +
+                    'interface administratively up/down')
+
+def update_ifup_argparser(argparser):
+    argparser.add_argument('-s', '--syntax-check', dest='syntaxcheck',
+                action='store_true',
+                help='Only run the interfaces file parser')
+    argparser.add_argument('-k', '--skip-upperifaces', dest='skipupperifaces',
+                action='store_true',
+                help='ifup by default tries to add newly created interfaces' +
+                ' into its upper/parent interfaces. Eg. if a bridge port is' +
+                ' created as a result of ifup on the port, ifup automatically' +
+                ' adds the port to the bridge. This option can be used to ' +
+                'disable this default behaviour')
+    update_ifupdown_argparser(argparser)
+
+def update_ifdown_argparser(argparser):
+    update_ifupdown_argparser(argparser)
+    argparser.add_argument('-u', '--use-current-config',
+                dest='usecurrentconfig',  action='store_true',
+                help='By default ifdown looks at the saved state for ' +
+                'interfaces to bring down. This option allows ifdown to ' +
+                'look at the current interfaces file. Useful when your ' +
+                'state file is corrupted or you want down to use the latest '
+                'from the interfaces file')
+
+def update_ifquery_argparser(argparser):
+    """ arg parser for ifquery options """
+
+    # -l is same as '-a', only here for backward compatibility
+    argparser.add_argument('-l', '--list', action='store_true', dest='all',
+                help=argparse.SUPPRESS)
+    group = argparser.add_mutually_exclusive_group(required=False)
+    group.add_argument('-r', '--running', dest='running',
+                       action='store_true',
+                       help='query running state of an interface')
+    group.add_argument('-c', '--check', dest='checkcurr',
+                       action='store_true',
+                       help='check interface file contents against ' +
+                       'running state of an interface')
+    group.add_argument('-x', '--raw', action='store_true', dest='raw',
+                       help='print raw config file entries')
+    group.add_argument('--print-savedstate', action='store_true',
+                       dest='printsavedstate',
+                       help=argparse.SUPPRESS)
+    argparser.add_argument('-o', '--format', dest='format', default='native',
+                           choices=['native', 'json'],
+                           help='interface display format')
+    argparser.add_argument('-p', '--print-dependency',
+                           dest='printdependency', choices=['list', 'dot'],
+                           help='print interface dependency')
+    argparser.add_argument('-s', '--syntax-help', action='store_true',
+                           dest='syntaxhelp',
+                           help='print supported interface config syntax')
+
+def update_ifreload_argparser(argparser):
+    """ parser for ifreload """
+    group = argparser.add_mutually_exclusive_group(required=True)
+    group.add_argument('-a', '--all', action='store_true',
+                help='process all interfaces marked \"auto\"')
+    group.add_argument('-c', '--currently-up', dest='currentlyup',
+                action='store_true',
+                help='only reload auto and other interfaces that are ' +
+                'currently up')
+    group.add_argument('--allow', dest='CLASS',
+                help='ignore non-\"allow-CLASS\" interfaces')
+    argparser.add_argument('iflist', metavar='IFACE',
+                nargs='*', help=argparse.SUPPRESS)
+    argparser.add_argument('-n', '--no-act', dest='noact',
+                action='store_true', help=argparse.SUPPRESS)
+    argparser.add_argument('-v', '--verbose', dest='verbose',
+                action='store_true', help='verbose')
+    argparser.add_argument('-d', '--debug', dest='debug',
+                action='store_true',
+                help='output debug info')
+    argparser.add_argument('-w', '--with-depends', dest='withdepends',
+                action='store_true', help=argparse.SUPPRESS)
+    argparser.add_argument('--perfmode', dest='perfmode',
+                action='store_true', help=argparse.SUPPRESS)
+    argparser.add_argument('--nocache', dest='nocache', action='store_true',
+                help=argparse.SUPPRESS)
+    argparser.add_argument('-X', '--exclude', dest='excludepats',
+                action='append',
+                help=argparse.SUPPRESS)
+    #argparser.add_argument('-j', '--jobs', dest='jobs', type=int,
+    #            default=-1, choices=range(1,12), help=argparse.SUPPRESS)
+    #argparser.add_argument('-i', '--interfaces', dest='interfacesfile',
+    #            default='/etc/network/interfaces',
+    #            help='use interfaces file instead of default ' +
+    #            '/etc/network/interfaces')
+    argparser.add_argument('-u', '--use-current-config',
+                dest='usecurrentconfig',  action='store_true',
+                help='By default ifreload looks at saved state for ' +
+                'interfaces to bring down. With this option ifreload will'
+                ' only look at the current interfaces file. Useful when your ' +
+                'state file is corrupted or you want down to use the latest '
+                'from the interfaces file')
+    argparser.add_argument('-l', '--syslog', dest='syslog',
+                action='store_true',
+                help=argparse.SUPPRESS)
+    argparser.add_argument('-f', '--force', dest='force',
+                action='store_true',
+                help='force run all operations')
+    argparser.add_argument('-s', '--syntax-check', dest='syntaxcheck',
+                action='store_true',
+                help='Only run the interfaces file parser')
+
+def parse_args(argsv, op):
+    if op == 'query':
+        descr = 'query interfaces (all or interface list)'
+    elif op == 'reload':
+        descr = 'reload interface configuration.'
+    else:
+        descr = 'interface management'
+    argparser = argparse.ArgumentParser(description=descr)
+    if op == 'reload':
+        update_ifreload_argparser(argparser)
+    else:
+        update_argparser(argparser)
+        if op == 'up':
+            update_ifup_argparser(argparser)
+        elif op == 'down':
+            update_ifdown_argparser(argparser)
+        elif op == 'query':
+            update_ifquery_argparser(argparser)
+        elif op == 'reload':
+            update_ifreload_argparser(argparser)
+    argcomplete.autocomplete(argparser)
+    return argparser.parse_args(argsv)
+
+handlers = {'up' : run_up,
+            'down' : run_down,
+            'query' : run_query,
+            'reload' : run_reload }
+
+def validate_args(op, args):
+    #if op == 'up' and args.syntaxcheck:
+    #    if args.iflist or args.all:
+    #        print 'ignoring interface options ..'
+    #    return True
+    if op == 'query' and args.syntaxhelp:
+        return True
+    if op == 'reload':
+        if not args.all and not args.currentlyup and not args.CLASS:
+            print '\'-a\' or \'-c\' or \'-allow\' option is required'
+            return False
+    elif (not args.iflist and
+            not args.all and not args.CLASS):
+        print '\'-a\' option or interface list are required'
+        return False
+    if args.iflist and args.all:
+        print '\'-a\' option and interface list are mutually exclusive'
+        return False
+    if op != 'reload' and args.CLASS and (args.all or args.iflist):
+        print ('\'--allow\' option is mutually exclusive ' +
+               'with interface list and \'-a\'')
+        return False
+    return True
+
+def read_config(args):
+    global configmap_g
+
+    config = open(configfile, 'r').read()
+    configStr = '[ifupdown2]\n' + config
+    configFP =  StringIO.StringIO(configStr)
+    parser = ConfigParser.RawConfigParser()
+    parser.readfp(configFP)
+    configmap_g = dict(parser.items('ifupdown2'))
+
+    # Preprocess config map
+    configval = configmap_g.get('multiple_vlan_aware_bridge_support', '0')
+    if configval == '0':
+        # if multiple bridges not allowed, set the bridge-vlan-aware
+        # attribute in the 'no_repeats' config, so that the ifupdownmain
+        # module can catch it appropriately
+        configmap_g['no_repeats'] = {'bridge-vlan-aware' : 'yes'}
+
+
+    configval = configmap_g.get('link_master_slave', '0')
+    if configval == '1':
+        # link_master_slave is only valid when all is set
+        if hasattr(args, 'all') and not args.all:
+            configmap_g['link_master_slave'] = '0'
+
+    configval = configmap_g.get('delay_admin_state_change', '0')
+    if configval == '1':
+        # reset link_master_slave if delay_admin_state_change is on
+        configmap_g['link_master_slave'] = '0'
+
+def main(argv):
+    """ main function """
+    args = None
+    try:
+        op = None
+        if argv[0].endswith('ifup'):
+            op = 'up'
+        elif argv[0].endswith('ifdown'):
+            op = 'down'
+        elif argv[0].endswith('ifquery'):
+            op = 'query'
+        elif argv[0].endswith('ifreload'):
+            op = 'reload'
+        else:
+            print ('Unexpected executable.' +
+                   ' Should be \'ifup\' or \'ifdown\' or \'ifquery\'')
+            exit(1)
+        # Command line arg parser
+        args = parse_args(argv[1:], op)
+        if not validate_args(op, args):
+            exit(1)
+
+        if not sys.argv[0].endswith('ifquery') and not os.geteuid() == 0:
+            print 'error: must be root to run this command'
+            exit(1)
+
+        if not sys.argv[0].endswith('ifquery') and not utils.lockFile(lockfile):
+            print 'Another instance of this program is already running.'
+            exit(0)
+
+        read_config(args)
+        init(args)
+        handlers.get(op)(args)
+    except Exception, e:
+        if not str(e):
+            exit(1)
+        if args and args.debug:
+            raise
+        else:
+            if logger:
+                logger.error(str(e))
+            else:
+                print str(e)
+            #if args and not args.debug:
+            #    print '\nrerun the command with \'-d\' for a detailed errormsg'
+        exit(1)
+    finally:
+        deinit()
+
+if __name__ == "__main__":
+
+    # required during boot
+    os.putenv('PATH', ENVPATH)
+    resource.setrlimit(resource.RLIMIT_CORE, (0,0))
+    main(sys.argv)
index d98910e93d9cdc4983856b4512b36132cc4040d9..3629a9a34a8453fcc97ce11e12ded665491d5de8 100755 (executable)
--- a/setup.py
+++ b/setup.py
@@ -1,39 +1,16 @@
 from distutils.core import setup
 
 setup(name='ifupdown2',
-      version='0.1',
+      version='1.1',
       description = "ifupdown 2",
       author='Roopa Prabhu',
       author_email='roopa@cumulusnetworks.com',
       url='cumulusnetworks.com',
       packages=['ifupdown', 'ifupdownaddons'],
-      scripts = ['sbin/ifupdown'],
-      install_requires = ['python-gvgen', 'python-argcomplete', 'python-ipaddr'],
-      data_files=[('share/man/man8/',
-                      ['man/ifup.8', 'man/ifquery.8', 'man/ifreload.8']),
-                  ('share/man/man5/',
-                      ['man/interfaces.5', 'man/ifupdown-addons-interfaces.5']),
-                  ('/etc/init.d/',
-                      ['init.d/networking']),
-                  ('/sbin/', ['sbin/ifupdown']),
-                  ('/etc/network/ifupdown2/',
+      data_files=[ ('/etc/network/ifupdown2/',
                       ['config/ifupdown2.conf']),
-                  ('/etc/default/',
-                      ['config/networking']),
-                  ('/usr/share/python-ifupdown2/',
-                      ['docs/examples/generate_interfaces.py']),
-                  ('/usr/share/doc/python-ifupdown2/examples/',
-                      ['docs/examples/interfaces',
-                       'docs/examples/interfaces_bridge_template_func',
-                       'docs/examples/interfaces_with_template',
-                       'docs/examples/interfaces_bridge_igmp_mstp']),
-                  ('/usr/share/doc/python-ifupdown2/examples/vlan_aware_bridges',
-                      ['docs/examples/vlan_aware_bridges/interfaces.basic',
-                       'docs/examples/vlan_aware_bridges/interfaces.vlan_prune_and_access_ports',
-                       'docs/examples/vlan_aware_bridges/interfaces.with_bonds',
-                       'docs/examples/vlan_aware_bridges/interfaces.with_clag']),
                   ('/etc/bash_completion.d/', ['completion/ifup']),
-                  ('/usr/share/ifupdownaddons/', ['addons/bridge.py',
+                  ('/usr/share/ifupdown2/addons/', ['addons/bridge.py',
                       'addons/bond.py', 'addons/vlan.py',
                       'addons/mstpctl.py', 'addons/address.py',
                       'addons/dhcp.py', 'addons/usercmds.py',
@@ -41,8 +18,8 @@ setup(name='ifupdown2',
                       'addons/addressvirtual.py', 'addons/vxlan.py',
                       'addons/link.py',
                       'addons/bridgevlan.py']),
-                  ('/var/lib/ifupdownaddons/', ['config/addons.conf']),
-                  ('/var/lib/ifupdownaddons/policy.d/', []),
+                  ('/etc/network/ifupdown2/', ['config/addons.conf']),
+                  ('/var/lib/ifupdown2/policy.d/', []),
                   ('/etc/network/ifupdown2/policy.d/', [])
                   ]
       )