bin/trema in trema-0.4.7 vs bin/trema in trema-0.4.8

- old
+ new

@@ -1,312 +1,238 @@ -#! /usr/bin/env ruby -# -# Trema command-line tool. -# -# Copyright (C) 2008-2013 NEC Corporation -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License, version 2, as -# published by the Free Software Foundation. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License along -# with this program; if not, write to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -# +#!/usr/bin/env ruby +$LOAD_PATH.unshift File.join(File.dirname(__FILE__), '..', 'lib') - -$LOAD_PATH.unshift File.expand_path(File.join File.dirname(__FILE__), '..', 'ruby') - -require 'rubygems' -require 'bundler/setup' - +require 'drb/drb' require 'gli' -require 'trema/command' -require 'trema/util' -require 'trema/version' -require 'trema/default_openflow_channel_port' +require 'phut' +require 'rake' +require 'trema' +ENV['GLI_DEBUG'] = 'true' -class BinTrema - include Trema::Command - include Trema::Util - include GLI::App +# OpenFlow controller framework. +module Trema + # trema command. + module App + extend GLI::App - - def initialize + desc 'Displays the current runtime version' program_desc 'Trema command-line tool' - - desc 'Displays the current runtime version' version Trema::VERSION - desc 'Be verbose' - switch [:v, :verbose], :negatable => false + switch [:v, :verbose], negatable: false - desc 'Runs a trema application' arg_name 'controller' - command :run do | c | + command :run do |c| c.desc 'Runs as a daemon' - c.switch [:d, :daemonize], :negatable => false - - c.desc 'Enables Trema wireshark plugin' - c.switch [:s, :tremashark], :negatable => false - - c.desc "Overrides the default openflow channel port #{Trema::DEFAULT_OPENFLOW_CHANNEL_PORT}" - c.flag [:p, :port] - + c.switch [:d, :daemonize], negatable: false c.desc 'Specifies emulated network configuration' c.flag [:c, :conf] + c.desc 'Use OpenFlow1.3' + c.switch :openflow13, default_value: false - c.desc 'Disables initial flow cleanup for a connected switch' - c.switch [:r, :no_flow_cleanup], :negatable => false + c.desc 'Overrides the default openflow channel port' + c.flag [:p, :port] - c.action do | global_options, options, args | - trema_run options + c.desc 'Location to put pid files' + c.flag [:P, :pid_dir], default_value: Trema::DEFAULT_PID_DIR + c.desc 'Location to put log files' + c.flag [:L, :log_dir], default_value: Trema::DEFAULT_LOG_DIR + c.desc 'Location to put socket files' + c.flag [:S, :socket_dir], default_value: Trema::DEFAULT_SOCKET_DIR + + c.action do |global_options, options, args| + Phut.pid_dir = options[:pid_dir] + Phut.log_dir = options[:log_dir] + Phut.socket_dir = options[:socket_dir] + require 'pio/open_flow13' if options[:openflow13] + require 'trema/switch' + Trema::Command.new.run(args, global_options.merge(options)) end end + desc 'Print all flow entries' + arg_name 'switches...' + command :dump_flows do |c| + c.desc 'Location to put socket files' + c.flag [:S, :socket_dir], default_value: Phut.socket_dir - desc 'Terminates a trema process' - arg_name 'name' - command :kill do | c | - c.action do | global_options, options, args | - help_now!('name is required') if args.empty? - args.each do | each | - trema_kill each + c.action do |_global_options, options, args| + args.each do |each| + puts Trema.fetch(each, options.fetch(:socket_dir)).dump_flows end end end - - desc 'Starts a killed trema process again' - arg_name 'name' - command :up do | c | - c.action do | global_options, options, args | - trema_up args[ 0] - end - end - - - desc 'Terminates all trema processes' - command :killall do | c | - c.action do - trema_killall - end - end - - desc 'Sends UDP packets to destination host' - command :send_packets do | c | + command :send_packets do |c| c.desc 'host that sends packets' c.flag [:s, :source] - c.desc 'host that receives packets' c.flag [:d, :dest] + c.desc 'number of packets to send' + c.flag [:n, :npackets], default_value: 1 - c.desc 'number of times to increment the IP source address' - c.default_value nil - c.flag [:inc_ip_src] + c.desc 'Location to put socket files' + c.flag [:S, :socket_dir], default_value: Trema::DEFAULT_SOCKET_DIR - c.desc 'number of times to increment the IP destination address' - c.default_value nil - c.flag [:inc_ip_dst] + c.action do |_global_options, options, _args| + fail '--source option is mandatory' if options[:source].nil? + fail '--dest option is mandatory' if options[:dest].nil? + dest = Trema.fetch(options.fetch(:dest), options.fetch(:socket_dir)) + Phut::VhostDaemon. + process(options.fetch(:source), options.fetch(:socket_dir)). + send_packets(dest, options.fetch(:npackets).to_i) + end + end - c.desc 'set the initial UDP source port' - c.flag [:tp_src] + desc 'Shows stats of packets' + arg_name 'host' + command :show_stats do |c| + c.desc 'Location to find socket files' + c.flag [:S, :socket_dir], default_value: Trema::DEFAULT_SOCKET_DIR - c.desc 'number of times to increment the UDP source port' - c.default_value nil - c.flag [:inc_tp_src] + c.action do |_global_options, options, args| + help_now!('host is required') if args.empty? - c.desc 'set the initial UDP destination port' - c.flag [:tp_dst] + stats = Phut::VhostDaemon.process(args[0], options[:socket_dir]).stats - c.desc 'number of times to increment the UDP destination port' - c.default_value nil - c.flag [:inc_tp_dst] + dests = stats[:tx].map { |each| each.ip_destination_address.to_s }.uniq + txstats = dests.map do |each| + all = stats[:tx].select { |pkt| pkt.ip_destination_address == each } + "#{all.first.ip_source_address} -> #{each} = " \ + "#{all.size} packet#{all.size > 1 ? 's' : ''}" + end + unless txstats.empty? + puts 'Packets sent:' + txstats.each { |each| puts " #{each}" } + end - c.desc 'send packet rate - packets per second' - c.flag [:pps] - - c.desc 'number of packets to send' - c.flag [:n_pkts] - - c.desc 'time duration to send packets' - c.flag [:duration] - - c.desc 'length of UDP payload' - c.flag [:length] - - c.desc 'increment UDP payload' - c.default_value nil - c.flag [:inc_payload] - - c.action do | global_options, options, args | - fail '--source option is mandatory' if options[ :source].nil? - fail '--dest option is mandatory' if options[ :dest].nil? - - trema_send_packets options[ :source], options[ :dest], options + sources = stats[:rx].map { |each| each.ip_source_address.to_s }.uniq + rxstats = sources.map do |each| + all = stats[:rx].select { |pkt| pkt.ip_source_address == each } + "#{each} -> #{all.first.ip_destination_address} = " \ + "#{all.size} packet#{all.size > 1 ? 's' : ''}" + end + unless rxstats.empty? + puts 'Packets received:' + rxstats.each { |each| puts " #{each}" } + end end end - desc "Brings a switch's specified port up" - command :port_up do | c | + command :port_up do |c| c.desc 'switch name' c.flag [:s, :switch] - c.desc 'port' c.flag [:p, :port] + c.desc 'Location to put socket files' + c.flag [:S, :socket_dir], default_value: Trema::DEFAULT_SOCKET_DIR - c.action do | global_options, options, args | - fail '--switch option is mandatory' if options[ :switch].nil? - fail '--port option is mandatory' if options[ :port].nil? - - trema_port_up options[ :switch], options[ :port] + c.action do |_global_options, options, _args| + fail '--switch option is mandatory' if options[:switch].nil? + fail '--port option is mandatory' if options[:port].nil? + Trema.trema_processes(options[:socket_dir]).each do |trema| + begin + trema.port_up(options[:switch], options[:port].to_i) + rescue + next + end + end end end - desc "Brings a switch's specified port down" - command :port_down do | c | + command :port_down do |c| c.desc 'switch name' c.flag [:s, :switch] - c.desc 'port' c.flag [:p, :port] + c.desc 'Location to put socket files' + c.flag [:S, :socket_dir], default_value: Trema::DEFAULT_SOCKET_DIR - c.action do | global_options, options, args | - fail '--switch option is mandatory' if options[ :switch].nil? - fail '--port option is mandatory' if options[ :port].nil? - - trema_port_down options[ :switch], options[ :port] + c.action do |_global_options, options, _args| + fail '--switch option is mandatory' if options[:switch].nil? + fail '--port option is mandatory' if options[:port].nil? + Trema.trema_processes(options[:socket_dir]).each do |trema| + begin + trema.port_down(options[:switch], options[:port].to_i) + rescue + next + end + end end end + desc 'Stops a vswitch or a vhost' + arg_name 'name' + command :stop do |c| + c.desc 'Location to find socket files' + c.flag [:S, :socket_dir], default_value: Trema::DEFAULT_SOCKET_DIR - desc 'Shows stats of packets' - arg_name 'host' - command :show_stats do | c | - c.desc 'Show stats of packets sent' - c.switch [:t, :tx], :negatable => false - c.desc 'Show stats of packets received' - c.switch [:r, :rx], :negatable => false - - c.action do | global_options, options, args | - help_now!('host is required') if args.empty? - trema_show_stats args[ 0], options[ :tx], options[ :rx] + c.action do |_global_options, options, args| + help_now! if args.size != 1 + Trema.fetch(args[0], options[:socket_dir]).stop end end + desc 'Deletes a virtual link' + arg_name 'endpoint1 endpoint2' + command :delete_link do |c| + c.desc 'Location to find socket files' + c.flag [:S, :socket_dir], default_value: Trema::DEFAULT_SOCKET_DIR - desc 'Resets stats of packets' - arg_name 'hosts...' - command :reset_stats do | c | - c.action do | global_options, options, args | - hosts = args - if hosts.empty? - hosts = Trema::DSL::Context.load_current.hosts.keys - end - hosts.each do | each | - trema_reset_stats each - end + c.action do |_global_options, options, args| + help_now! if args.size != 2 + Trema.fetch(args, options[:socket_dir]).stop end end - - desc 'Print all flow entries' - arg_name 'switches...' - command :dump_flows do | c | - c.action do | global_options, options, args | - help_now!('switches is required') if args.empty? - trema_dump_flows args - end - end - - - desc 'Opens a new shell in the specified network namespace' + desc 'Starts the stopped vswitch or vhost again' arg_name 'name' - command :netns do | c | - c.action do | global_options, options, args | - trema_netns args[ 0] - end - end + command :start do |c| + c.desc 'Location to find socket files' + c.flag [:S, :socket_dir], default_value: Trema::DEFAULT_SOCKET_DIR - - desc "Opens in your browser Trema's Ruby API documentation" - command :ruby do | c | - c.action do - trema_ruby + c.action do |_global_options, options, args| + help_now! if args.size != 1 + Trema.fetch(args[0], options[:socket_dir]).run end end + desc 'Terminates all trema processes' + arg_name 'controller_name' + command :killall do |c| + c.desc 'Kill all known trema processes' + c.switch :all, default_value: false, negatable: false + c.desc 'Location to find socket files' + c.flag [:S, :socket_dir], default_value: Trema::DEFAULT_SOCKET_DIR - desc 'Displays the current runtime version' - command :version do | c | - c.action do - trema_version + c.action do |_global_options, options, args| + if options[:all] + Trema.trema_processes(options[:socket_dir]).each do |each| + begin + each.killall + rescue DRb::DRbConnError + true # OK (trema process exitted). + end + end + else + help_now! if args.size != 1 + begin + Trema.trema_process(args[0], options[:socket_dir]).killall + rescue DRb::DRbConnError + true # OK (trema process exitted). + end + end end end + default_command :help - GLI::Commands::Help.skips_pre = false - - - pre do | global, command, options, args | - $verbose = global[ :verbose] - - if global[ :version] - trema_version - exit_now! nil, 0 - end - - assert_trema_is_built - - if FileTest.exist?(Trema.tmp) && !FileTest.writable?(Trema.tmp) - # Trema is system widely installed with gem command - sh "sudo chmod a+w -R #{ Trema.tmp }" - end - - FileUtils.mkdir_p Trema.log - FileUtils.mkdir_p Trema.pid - FileUtils.mkdir_p Trema.sock - - true - end - - - on_error do | exception | - # Error logic here - # return false to skip default error handling - true - end + exit run(ARGV) end - - - def start(argv) - run argv - rescue - puts $! - $!.backtrace.each do | each | - puts each - end - exit - end end - - -exit BinTrema.new.start(ARGV) - - -### Local variables: -### mode: Ruby -### coding: utf-8 -### indent-tabs-mode: nil -### End: