+++ /dev/null
-#!/usr/bin/python
-###############################################################################
-# #
-# IPFire.org - A linux based firewall #
-# Copyright (C) 2008 Michael Tremer & Christian Schmidt #
-# #
-# This program is free software: you can redistribute it and/or modify #
-# it under the terms of the GNU General Public License as published by #
-# the Free Software Foundation, either version 3 of the License, or #
-# (at your option) any later version. #
-# #
-# 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, see <http://www.gnu.org/licenses/>. #
-# #
-###############################################################################
-
-import os
-import sys
-import time
-import socket
-import base64
-import shutil
-from pysqlite2 import dbapi2 as sqlite
-
-sys.path.append(".")
-
-from constants import config
-
-class Database:
- def __init__(self, path):
- self.db = sqlite.connect(os.path.join(path, config["db_name"]))
- c = self.cursor()
- c.executescript("""
- create table if not exists config(key, value, date);
- create table if not exists durations(duration);
- """)
- c.close()
-
- def __call__(self):
- return self.cursor()
-
- def __del__(self):
- self.commit()
- self.db.close()
-
- def cursor(self):
- return self.db.cursor()
-
- def commit(self):
- self.db.commit()
-
-class DatabaseConfig:
- def __init__(self, db, key, base64=0):
- self.db = db
- self.key = key
- self.data = None
- self.date = None
- self.base64 = base64
-
- def get(self):
- if not self.data:
- c = self.db.cursor()
- c.execute("SELECT value FROM %(table)s WHERE key = '%(key)s'" \
- % { "table" : "config",
- "key" : self.key, })
- try:
- self.data = c.fetchone()[0]
- except TypeError:
- self.data = None
- c.close()
- return self.data
-
- __call__ = get
-
- def time(self):
- if not self.date:
- c = self.db.cursor()
- c.execute("SELECT date FROM %(table)s WHERE key = '%(key)s'" \
- % { "table" : "config",
- "key" : self.key, })
- try:
- self.date = float("%s" % c.fetchone()[0])
- except TypeError:
- self.date = None
- c.close()
- return self.date or float(0)
-
- def set(self, value):
- if self.base64:
- value = base64.b64decode(value)
- #value = (value,)
- c = self.db.cursor()
- if not self.get():
- sql = "INSERT INTO %(table)s(key, value, date) VALUES('%(key)s', '%(value)s', '%(date)s')" \
- % { "table" : "config",
- "key" : self.key,
- "value" : value,
- "date" : time.time(), }
-
- else:
- sql = "UPDATE %(table)s SET value='%(value)s', date='%(date)s' WHERE key='%(key)s'" \
- % { "table" : "config",
- "key" : self.key,
- "value" : value,
- "date" : time.time(), }
- c.execute(sql)
- c.close()
- self.data = value
- self.db.commit()
- return """Set "%s" to "%s".""" % (self.key, self.data,)
-
-class DurationsConfig:
- def __init__(self, db):
- self.db = db
-
- def get(self, sort=0):
- c = self.db.cursor()
- c.execute("SELECT duration FROM durations")
- ret = []
- for value in c.fetchall():
- value = int("%s" % value)
- if value < 900: # 15min
- continue
- ret.append(value)
- c.close()
- if sort: ret.sort()
- return ret
-
- def set(self, value):
- #value = (value,)
- c = self.db.cursor()
- c.execute("INSERT INTO %(table)s(duration) VALUES('%(value)s')" \
- % { "table" : "durations",
- "value" : value, })
- c.close()
- self.db.commit()
- return """Accepted build duration of %s seconds.""" % (value,)
-
- def get_avg(self):
- sum = 0
- durations = self.get()
- if not len(durations):
- return None
- for value in durations:
- sum += value
- avg = sum / len(durations)
- return avg
-
- def get_eta(self, timestamp):
- avg = self.get_avg()
- if not avg:
- return "N/A"
- eta = int(timestamp) + avg
- return time.ctime(eta)
-
-class DistccConfig(DatabaseConfig):
- def __init__(self, db, key, hostname, jobs):
- DatabaseConfig.__init__(self, db, key)
- self.hostname = hostname
- self.jobs = jobs
-
- def __str__(self):
- if not self.ping() or self.get() == "0":
- return ""
- return "%s:%s/%s,lzo" % \
- (self.hostname, self.get(), self.jobs or "4",)
-
- def ping(self):
- if not self.hostname:
- return False
- return not os.system("ping -c1 -w1 %s &>/dev/null" % self.hostname)
-
- def version(self):
- return os.popen("distcc --version").readlines()
-
-class FileConfig:
- def __init__(self, path, filetype):
- self.filename = os.path.join(path, config["path"][filetype])
-
- # Create the file if not existant
- if not os.access(self.filename, os.R_OK):
- f = open(self.filename, "w")
- f.close()
-
- def get(self):
- ret = []
- try:
- f = open(self.filename)
- ret = f.readlines()
- f.close()
- except:
- pass
- return ret or ["Log is empty."]
-
- __call__ = get
-
- def set(self, lines):
- f = open(self.filename, "w")
- for line in base64.b64decode(lines).split("\n"):
- f.write("%s\n" % line.rstrip("\n"))
- f.close()
- return """Saved file content to %s.""" % (self.filename,)
-
-class Builder:
- def __init__(self, config, uuid):
- self.uuid = uuid
- self.config = config
- self.path = os.path.join(self.config['path']['db'], self.uuid)
-
- if not os.access(self.path, os.R_OK):
- try:
- os.mkdir(self.path)
- except:
- pass
-
- self.db = Database(self.path)
-
- self.hostname = DatabaseConfig(self.db, "hostname")
- self.state = DatabaseConfig(self.db, "state")
- self.package = DatabaseConfig(self.db, "package")
- self.target = DatabaseConfig(self.db, "target")
- self.toolchain= DatabaseConfig(self.db, "toolchain")
-
- self.duration = DurationsConfig(self.db)
- self.jobs = DatabaseConfig(self.db, "jobs")
- self.distcc = DistccConfig(self.db, "distcc", self.hostname(), self.jobs())
- self.cpu = DatabaseConfig(self.db, "cpu", base64=1)
- self.machine = DatabaseConfig(self.db, "machine")
- self.system = DatabaseConfig(self.db, "system", base64=1)
-
- self.log = FileConfig(self.path, "log")
-
- # If host was longer than 3 days in state compiling we set it as idle.
- if self.state() == "compiling" and \
- (time.time() - self.state.time()) > 3*24*60*60:
- self.state.set("idle")
-
- # If host is idle and distcc is not disabled we set it as distcc host.
- if self.state() == "idle" and self.distcc() != "0":
- self.state.set("distcc")
-
- # If host is longer than 24h in error state we set it as distcc host.
- if self.state() == "error" and \
- (time.time() - self.state.time()) > 24*60*60:
- self.state.set("distcc")
-
- # If host was longer than two weeks in distcc state we set it as unknown.
- if self.state() == "error" and \
- (time.time() - self.state.time()) > 2*7*24*60*60:
- self.state.set("unknown")
-
- # If host was longer than four weels in distcc state we delete it.
- if self.state() in ("distcc", "unknown",) and \
- (time.time() - self.state.time()) > 4*7*24*60*60:
- del self.db
- shutil.rmtree(self.path)
-
- def set(self, key, value):
- return eval("self.%s.set(\"%s\")" % (key, value,))
-
- def get(self, key):
- return eval("self.%s.get()" % (key,))
-
-def getAllBuilders(age=0):
- builders = []
- for uuid in os.listdir(config["path"]["db"]):
- if uuid == "empty.txt": continue
- builder = Builder(config, uuid)
- # If there was no activity since "age" days -> continue...
- if age and (time.time() - builder.state.time()) > age*24*60*60:
- continue
- builders.append(builder)
- return builders
+++ /dev/null
-#!/usr/bin/python
-###############################################################################
-# #
-# IPFire.org - A linux based firewall #
-# Copyright (C) 2008 Michael Tremer & Christian Schmidt #
-# #
-# This program is free software: you can redistribute it and/or modify #
-# it under the terms of the GNU General Public License as published by #
-# the Free Software Foundation, either version 3 of the License, or #
-# (at your option) any later version. #
-# #
-# 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, see <http://www.gnu.org/licenses/>. #
-# #
-###############################################################################
-
-import os
-import time
-
-POINTS_UNKNOWN = 0
-POINTS_IDLE = 1
-POINTS_DISTCC = 2
-POINTS_ERROR = 4
-POINTS_COMPILING = 8
-
-config = {
- "title" : "IPFire - Builder",
- "nightly_url" : ("http://ftp.ipfire.org/pub/nightly-builds/", "http://www.rowie.at/upload/ipfire/builds/",),
- "path" : { "db" : "db", "log" : "error.log", },
- "script" : os.environ['SCRIPT_NAME'],
- "db_name" : "builder.db",
-}
-
-statedesc = {
- None : "",
- "unknown" : "Dunno what the host is doing at the moment...",
- "compiling" : "The host is really hard working at the moment...",
- "error" : "Oops! The host had an error...",
- "idle" : "The host is idle at the moment...",
- "distcc" : "This host is waiting for distcc requests...",
-}
-
-ping2class = {
- True : "online",
- False : "offline",
-}
-
-state2style = {
- None : "",
- "compiling" : "background: #8C8; border: 1px solid #0e0;",
- "distcc" : "background: #58c; border: 1px solid #8ac;",
- "error" : "background: #c33; border: 1px solid #e00;",
- "idle" : "background: #ddd; border: 1px solid #eee;",
-}
+++ /dev/null
-#!/usr/bin/python
-###############################################################################
-# #
-# IPFire.org - A linux based firewall #
-# Copyright (C) 2008 Michael Tremer & Christian Schmidt #
-# #
-# This program is free software: you can redistribute it and/or modify #
-# it under the terms of the GNU General Public License as published by #
-# the Free Software Foundation, either version 3 of the License, or #
-# (at your option) any later version. #
-# #
-# 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, see <http://www.gnu.org/licenses/>. #
-# #
-###############################################################################
-
-import os
-import sys
-import time
-
-sys.path.append(".")
-
-from builder import Builder, getAllBuilders
-from constants import *
-
-def format_time(seconds, use_hours=1):
- if seconds is None or seconds < 0:
- if use_hours: return '--:--:--'
- else: return '--:--'
- else:
- seconds = int(seconds)
- minutes = seconds / 60
- seconds = seconds % 60
- if use_hours:
- hours = minutes / 60
- minutes = minutes % 60
- return '%02i:%02i:%02i' % (hours, minutes, seconds)
- else:
- return '%02i:%02i' % (minutes, seconds)
-
-class Site:
- def __init__(self, config):
- self.builders = None
- self.config = config
- print "Content-type: text/html"
- print
-
- def __call__(self, builders=None):
- self.builders = builders
- print """<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
- <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
- <head>
- <title>%(title)s</title>
- <style type="text/css">
- * {
- margin: auto;
- padding: 0;
- text-decoration: none;
- outline: none;
- }
- body {
- font-family: Verdana;
- font-size: 90%%;
- background-color:#f9f9f9;
- }
- h1 {
- text-decoration: underline;
- }
- #header {
- width: 800px;
- text-align: center;
- background: #E0E0E0;
- border: 1px solid #999;
- padding-top: 10px;
- padding-bottom: 5px;
- }
- #content {
- padding-top: 10px;
- width: 800px;
- }
- div.box {
- padding: 5px;
- margin: 10px 0 10px 0;
- /* height: 80px; */
- border: 1px solid;
- }
- div.infobox {
- float: right;
- width: 240px;
- }
- div.log {
- background: #e55;
- border: 1px dotted;
- margin-top: 12px;
- /* visibility: hidden; */
- height: 150px;
- overflow: auto;
- }
- div.log p {
- font-family: Courier New;
- }
- div.footer {
- }
- div.footer p {
- text-align: center;
- font-size: 5px;
- }
- p {
- margin: 2px;
- }
- p.boxheader {
- font-weight: bold;
- }
- p.online {
- color: green;
- }
- p.offline {
- color: red;
- }
- p.package {
- font: bold;
- font-size: 150%%;
- }
- img.right {
- float: right;
- }
- p.desc {
- text-decoration: bold;
- }
- a:link {
- color: black; text-decoration: none;
- }
- a:visited {
- color: black; text-decoration: none;
- }
- </style>
- <meta http-equiv="refresh" content="90; URL=%(script)s" />
- </head>
- <body>
- <div id="header">
- <h1>IPFire Builder</h1>""" % self.config
- for i in self.config["nightly_url"]:
- print """\
- <p><a href="%s" target="_blank">%s</a></p>""" % (i, i,)
- print """\
- </div>"""
-
- self.content()
-
- print "\t\t</body>\n</html>"
-
- def content(self):
- if self.builders:
- print """\
- <div id="content">"""
- for builder in self.builders:
- builder()
- print """\
- </div>"""
-
-class Box:
- def __init__(self, builder):
- self.builder = builder
- self.points = POINTS_UNKNOWN
-
- def __cmp__(self, other):
- if self.points > other.points:
- return -1
- elif self.points == other.points:
- return 0
- elif self.points < other.points:
- return 1
-
- def __str__(self):
- return """<a href="#%(hostname)s">%(hostname)s</a>""" % { "hostname" : self.builder.hostname(), }
-
- def open_bigbox(self):
- print """<a name="%s"></a><div class="box" style="%s">""" \
- % (self.builder.hostname(), state2style[self.builder.state()],)
-
- def open_infobox(self):
- print """<div class="infobox">"""
-
- def close_bigbox(self):
- print """</div>"""
-
- close_infobox = close_bigbox
-
- def header(self):
- print """<p class="boxheader">%(hostname)s <span>[%(uuid)s]</span></p>""" \
- % { "hostname" : self.builder.hostname(),
- "state" : self.builder.state(),
- "uuid" : self.builder.uuid, }
-
- def package(self):
- if self.builder.state() in [ "compiling", "error", ]:
- print """\
- <p class="package">%s</p>"""\
- % self.builder.package()
-
- def time(self):
- print """<p>%s</p>""" \
- % time.ctime(float(self.builder.state.time()))
-
- def stateinfo(self):
- print """<p class="desc">%s</p>""" \
- % statedesc[self.builder.state()]
-
- def durations(self):
- print """<p>Average Build Duration: %s</p>""" \
- % format_time(self.builder.duration.get_avg())
- if self.builder.state() == "compiling":
- print """<p>ETA: %s</p>""" \
- % self.builder.duration.get_eta(self.builder.state.time())
-
- def distccinfo(self):
- state = self.builder.distcc.ping()
- port = self.builder.distcc()
- if port == "0":
- state = False
- port = "disabled"
- print """<p class="%s">Distcc: %s</p>""" \
- % (ping2class[state], port,)
-
- def log(self):
- log = self.builder.log()
- if log:
- print """<div class="log"><p>"""
- print "<br />".join(log)
- print """</p></div>"""
-
- def footer(self):
- print """<div class="footer"><p>system: %s - cpu: %s <br /> machine: %s - target: %s - jobs: %s - toolchain: %s</p></div>""" \
- % (self.builder.system(), self.builder.cpu(), self.builder.machine(), self.builder.target(), self.builder.jobs(), self.builder.toolchain(),)
-
-class BoxCompiling(Box):
- def __init__(self, builder):
- Box.__init__(self, builder)
- self.points = POINTS_COMPILING
-
- def __call__(self):
- self.open_bigbox()
- self.open_infobox()
- self.distccinfo()
- self.package()
- self.time()
- self.close_infobox()
- self.header()
- self.stateinfo()
- self.durations()
- self.footer()
- self.close_bigbox()
-
-class BoxError(Box):
- def __init__(self, builder):
- Box.__init__(self, builder)
- self.points = POINTS_ERROR
-
- def __call__(self):
- self.open_bigbox()
- self.open_infobox()
- self.distccinfo()
- self.package()
- self.time()
- self.close_infobox()
- self.header()
- self.stateinfo()
- self.durations()
- self.log()
- self.footer()
- self.close_bigbox()
-
-class BoxDistcc(Box):
- def __init__(self, builder):
- Box.__init__(self, builder)
- self.points = POINTS_DISTCC
-
- def __call__(self):
- self.open_bigbox()
- self.open_infobox()
- self.distccinfo()
- self.time()
- self.close_infobox()
- self.header()
- self.stateinfo()
- self.durations()
- self.footer()
- self.close_bigbox()
-
-class BoxIdle(Box):
- def __init__(self, builder):
- Box.__init__(self, builder)
- self.points = POINTS_IDLE
-
- def __call__(self):
- self.open_bigbox()
- self.open_infobox()
- self.distccinfo()
- self.time()
- self.close_infobox()
- self.header()
- self.stateinfo()
- self.durations()
- self.footer()
- self.close_bigbox()
-
-site = Site(config)
-
-boxes = []
-for builder in getAllBuilders():
- box = None
- if builder.state() == "compiling":
- box = BoxCompiling(builder)
- elif builder.state() == "error":
- box = BoxError(builder)
- elif builder.state() == "idle":
- box = BoxIdle(builder)
- elif builder.state() == "distcc":
- if builder.distcc() == "0":
- continue
- box = BoxDistcc(builder)
- if box:
- boxes.append(box)
-
-boxes.sort()
-site(boxes)
+++ /dev/null
-#!/usr/bin/python
-###############################################################################
-# #
-# IPFire.org - A linux based firewall #
-# Copyright (C) 2008,2009 Michael Tremer & Christian Schmidt #
-# #
-# This program is free software: you can redistribute it and/or modify #
-# it under the terms of the GNU General Public License as published by #
-# the Free Software Foundation, either version 3 of the License, or #
-# (at your option) any later version. #
-# #
-# 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, see <http://www.gnu.org/licenses/>. #
-# #
-###############################################################################
-
-import os
-import sys
-import cgi
-
-sys.path.append(".")
-
-from builder import Builder, getAllBuilders
-from constants import config
-
-ALLOWED_ACTIONS_SET = ( "distcc", "duration", "hostname", "jobs", "log", "state",
- "package", "target", "toolchain", "cpu", "machine", "system",)
-ALLOWED_ACTIONS_GET = ( "distcc",)
-
-def run(uuid, action):
- myself = Builder(config, uuid)
-
- if action == "get":
- for key in ALLOWED_ACTIONS_GET:
- if key == "distcc":
- for value in data.getlist(key):
- if value == "raw":
- builders = getAllBuilders()
- print "--randomize"
- for builder in builders:
- # Print "localhost" for ourself
- if myself.uuid == builder.uuid:
- print "localhost"
- else:
- if ((myself.toolchain() == builder.toolchain()) and \
- (myself.machine() == builder.machine()) and \
- (myself.target() == builder.target())):
- print "%s" % (builder.distcc,)
-
- elif action == "set":
- for key in ALLOWED_ACTIONS_SET:
- for value in data.getlist(key):
- print myself.set(key, value)
-
-data = cgi.FieldStorage()
-
-print "Status: 200 - OK" # We always send okay.
-print
-
-try:
- uuid = data.getfirst("uuid")
- action = data.getfirst("action")
- if uuid and action:
- run(uuid, action)
-except SystemExit:
- pass
"hostname" : "mirror1.ipfire.org",
"path" : "",
"serves" : {
- "isos" : false,
+ "isos" : true,
"pakfire2" : true,
"pakfire3" : true
}
{
"name" : "Jan Paul Tücking",
"location" : {
- "city" : "Karlsruhe",
+ "city" : "Falkenstein/Vogtland",
"country" : "Germany",
"country_code" : "de"
},
"path" : "",
"serves" : {
"isos" : true,
- "pakfire2" : false,
+ "pakfire2" : true,
"pakfire3" : false
}
},
}
},
- {
- "name" : "Peter Schälchli",
- "location" : {
- "city" : "Paris",
- "country" : "France",
- "country_code" : "fr"
- },
- "hostname" : "mirror3.ipfire.org",
- "path" : "",
- "serves" : {
- "isos" : true,
- "pakfire2" : true,
- "pakfire3" : false
- }
- },
-
- {
- "name" : "Peter Schälchli",
- "location" : {
- "city" : "Cologne",
- "country" : "Germany",
- "country_code" : "de"
- },
- "hostname" : "mirror5.ipfire.org",
- "path" : "",
- "serves" : {
- "isos" : true,
- "pakfire2" : true,
- "pakfire3" : false
- }
- },
-
{
"name" : "Kim Barthel",
"location" : {
"country" : "Germany",
"country_code" : "de"
},
- "hostname" : "ipfire.kbarthel.de",
+ "hostname" : "ipfire.b56.eu",
"path" : "",
"serves" : {
"isos" : true,
},
{
- "name" : "Kim Barthel",
+ "name" : "Robert Möker",
"location" : {
- "city" : "Stuttgart",
+ "city" : "Frankfurt am Main",
"country" : "Germany",
"country_code" : "de"
},
- "hostname" : "ipfire.1l0v3u.com",
- "path" : "",
+ "hostname" : "datenklatscher.net",
+ "path" : "/ipfire",
"serves" : {
"isos" : true,
"pakfire2" : false,
},
{
- "name" : "Sebastian Winter",
+ "name" : "SWITCH",
"location" : {
- "city" : "Minden",
- "country" : "Germany",
- "country_code" : "de"
+ "city" : "Zurich",
+ "country" : "Switzerland",
+ "country_code" : "ch"
},
- "hostname" : "ipfiremirror.wintertech.de",
- "path" : "",
+ "hostname" : "mirror.switch.ch",
+ "path" : "/ftp/mirror/ipfire/pakfire2",
"serves" : {
"isos" : true,
"pakfire2" : false,
},
{
- "name" : "Robert Möker",
- "location" : {
- "city" : "Frankfurt am Main",
- "country" : "Germany",
- "country_code" : "de"
- },
- "hostname" : "datenklatscher.net",
- "path" : "/ipfire",
- "serves" : {
- "isos" : true,
- "pakfire2" : false,
- "pakfire3" : false
- }
- }
+ "name" : "Peter Schälchli",
+ "location" : {
+ "city" : "Paris",
+ "country" : "France",
+ "country_code" : "fr"
+ },
+ "hostname" : "mirror6.ipfire.org",
+ "path" : "",
+ "serves" : {
+ "isos" : true,
+ "pakfire2" : true,
+ "pakfire3" : false
+ }
+ }
]
The webif marks this as \"can be blank\" but this will change with strongswan!
</p>",
-
"de" : "<p>Heute werden wir <strong>Core 37</strong> veröffentlichen.
Es bringt die folgenden Änderungen mit sich:</p>
<ul>
von openswan auf strongswan zu wechseln. Um auf diesen Wechsel vorbereitet zu sein
sollten Sie Ihre IPSEC Einstellungen prüfen und die Felder \"Local ID\" und \"Remote ID\"
ausfüllen. Im Moment sind diese Felder optional aber mit strongswan sind diese erforderlich.
- </p>"}}
+ </p>"}},
+
+ "31" : {"author" : "Jan Paul Tuecking",
+ "mail" : "earl@ipfire.org",
+ "subject" : { "en" : "IPFire on LWN.net", "de" : "IPFire auf LWN.net" },
+ "date" : "2010-05-15",
+ "link" : "",
+ "content" :
+ { "en" : "<p>Linux Weekly News, one of the most important information portals of free software and linux,
+ has released a detailed article about IPFire that we want to share with our users:
+ <br />
+ <a href=\"http://lwn.net/Articles/384419/\" target=\"_blank\">IPFire 2.5: Firewalls and more</a>
+ </p>",
+
+
+ "de" : "<p>Linux Weekly News, einer der wichtigsten Informationsportale über Freie Software und Linux,
+ hat einen ausführlichen Artikel über IPFire herausgebracht den wir unseren Benutzern nicht
+ vorenthalten wollen:
+ <br />
+ <a href=\"http://lwn.net/Articles/384419/\" target=\"_blank\">IPFire 2.5: Firewalls and more</a>
+ </p>"}},
+
+ "32" : {"author" : "Jan Paul Tuecking",
+ "mail" : "earl@ipfire.org",
+ "subject" : { "en" : "IPFire 2.7 release candidate 1", "de" : "IPFire 2.7 release candidate 1" },
+ "date" : "2010-06-10",
+ "link" : "",
+ "content" :
+ { "en" : "<p>After the approval by the release manager we are going to release <strong>IPFire 2.7 RC1</strong> today.
+ This version is only suitable for testing and should not be used in productive environments.
+ <br />
+ Download: <a href=\"http://people.ipfire.org/~arne_f/testing/\" target=\"_blank\">Mirror 1</a> |
+ <a href=\"http://testing.ipfire.at/\" target=\"_blank\">Mirror 2</a>
+ <br />
+ Please help us to test the new version of IPFire. If you have experienced any bugs please report
+ them to the <a href=\"http://bugtracker.ipfire.org/\"
+ target=\"_blank\">bugtracker</a>. Thank you!
+ <br />
+ More information is available on the
+ <a href=\"http://forum.ipfire.org/index.php?topic=2436.0\" target=\"_blank\">IPFire forum</a>.
+ </p>",
+
+ "de" : "<p>Nach der Freigabe durch den Releasemanager werden wir heute <strong>IPFire 2.7 RC1</strong> veröffentlichen.
+ Diese Version ist ausschließlich zu Testzwecken geeignet und sollte nicht in Produktivumgebungen benutzt werden.
+ <br />
+ Download: <a href=\"http://people.ipfire.org/~arne_f/testing/\" target=\"_blank\">Mirror 1</a> |
+ <a href=\"http://testing.ipfire.at/\" target=\"_blank\">Mirror 2</a>
+ <br />
+ Helft uns und testet die neue IPFire-Version. Gefundene Fehler bitte im <a href=\"http://bugtracker.ipfire.org/\"
+ target=\"_blank\">Bugtracker</a> melden. Vielen Dank!
+ <br />
+ Mehr Informationen gibt es hier im
+ <a href=\"http://forum.ipfire.org/index.php?topic=2436.0\" target=\"_blank\">IPFire Forum</a>.
+ </p>"}},
+
+ "33" : {"author" : "Jan Paul Tuecking",
+ "mail" : "earl@ipfire.org",
+ "subject" : { "en" : "IPFire 2.7 release candidate 2", "de" : "IPFire 2.7 release candidate 2" },
+ "date" : "2010-06-16",
+ "link" : "",
+ "content" :
+ { "en" : "<p>Today <strong>IPFire 2.7 RC2</strong> is available.
+ <br />
+ Again this version is only suitable for testing and should not be used in productive environments.
+ <br />
+ Download: <a href=\"http://people.ipfire.org/~arne_f/testing/\" target=\"_blank\">Mirror 1</a> |
+ <a href=\"http://testing.ipfire.at/\" target=\"_blank\">Mirror 2</a>
+ </p>",
+
+ "de" : "<p>Heute steht <strong>IPFire 2.7 RC2</strong> zur Verfügung.
+ <br />Diese Version ist wieder ausschließlich zu Testzwecken geeignet und sollte nicht in Produktivumgebungen benutzt werden.
+ <br />
+ Download: <a href=\"http://people.ipfire.org/~arne_f/testing/\" target=\"_blank\">Mirror 1</a> |
+ <a href=\"http://testing.ipfire.at/\" target=\"_blank\">Mirror 2</a>
+ </p>"}},
+
+
+ "35" : {"author" : "Jan Paul Tuecking",
+ "mail" : "earl@ipfire.org",
+ "subject" : { "en" : "IPFire 2.7 release candidate 3", "de" : "IPFire 2.7 release candidate 3" },
+ "date" : "2010-06-18",
+ "link" : "",
+ "content" :
+ { "en" : "<p>Today we are gonig to release <strong>IPFire 2.7 RC3</strong>.
+ <br />
+ This version is only suitable for testing and should not be used in productive environments.
+ <br />
+ Download: <a href=\"http://people.ipfire.org/~arne_f/testing/\" target=\"_blank\">Mirror 1</a> |
+ <a href=\"http://testing.ipfire.at/\" target=\"_blank\">Mirror 2</a>
+ <br />
+ If you have experienced any bugs please report them to the <a href=\"http://bugtracker.ipfire.org/\"
+ target=\"_blank\">bugtracker</a>. Thank you!
+ <br />
+ Changes are available on the
+ <a href=\"http://forum.ipfire.org/index.php?topic=2436.0\" target=\"_blank\">IPFire forum</a>.
+ </p>",
+
+ "de" : "<p>Heute werden wir <strong>IPFire 2.7 RC3</strong> veröffentlichen.
+ <br />Diese Version ist ausschließlich zu Testzwecken geeignet und sollte nicht in Produktivumgebungen benutzt werden.
+ <br />
+ Download: <a href=\"http://people.ipfire.org/~arne_f/testing/\" target=\"_blank\">Mirror 1</a> |
+ <a href=\"http://testing.ipfire.at/\" target=\"_blank\">Mirror 2</a>
+ <br />
+ Gefundene Fehler bitte im <a href=\"http://bugtracker.ipfire.org/\" target=\"_blank\">Bugtracker</a> melden. Vielen Dank!
+ <br />
+ Änderungen gibt es hier im
+ <a href=\"http://forum.ipfire.org/index.php?topic=2436.0\" target=\"_blank\">IPFire Forum</a>.
+ </p>"}},
+
+ "36" : {"author" : "Jan Paul Tuecking",
+ "mail" : "earl@ipfire.org",
+ "subject" : { "en" : "IPFire 2.7 release candidate 4", "de" : "IPFire 2.7 release candidate 4" },
+ "date" : "2010-06-22",
+ "link" : "",
+ "content" :
+ { "en" : "<p>News for all our tester <strong>IPFire 2.7 RC4</strong> is released.
+ <br />
+ This version is only suitable for testing and should not be used in productive environments.
+ <br />
+ Download: <a href=\"http://people.ipfire.org/~arne_f/testing/\" target=\"_blank\">Mirror 1</a> |
+ <a href=\"http://testing.ipfire.at/\" target=\"_blank\">Mirror 2</a>
+ <br />
+ If you have experienced any bugs please report them to the <a href=\"http://bugtracker.ipfire.org/\"
+ target=\"_blank\">bugtracker</a>. Thank you!
+ <br />
+ All changes are available on the
+ <a href=\"http://forum.ipfire.org/index.php?topic=2436.0\" target=\"_blank\">IPFire forum</a>.
+ </p>",
+
+ "de" : "<p>Neuigkeiten für alle unsere Tester <strong>IPFire 2.7 RC4</strong> ist da.
+ <br />Diese Version ist ausschließlich zu Testzwecken geeignet und sollte nicht in Produktivumgebungen benutzt werden.
+ <br />
+ Download: <a href=\"http://people.ipfire.org/~arne_f/testing/\" target=\"_blank\">Mirror 1</a> |
+ <a href=\"http://testing.ipfire.at/\" target=\"_blank\">Mirror 2</a>
+ <br />
+ Gefundene Fehler bitte im <a href=\"http://bugtracker.ipfire.org/\" target=\"_blank\">Bugtracker</a> melden. Vielen Dank!
+ <br />
+ Alle Änderungen gibt es hier im
+ <a href=\"http://forum.ipfire.org/index.php?topic=2436.0\" target=\"_blank\">IPFire Forum</a>.
+ </p>"}},
+
+ "37" : {"author" : "Jan Paul Tuecking",
+ "mail" : "earl@ipfire.org",
+ "subject" : { "en" : "IPFire 2.7 release candidate 5", "de" : "IPFire 2.7 release candidate 5" },
+ "date" : "2010-06-27",
+ "link" : "",
+ "content" :
+ { "en" : "<p>Probably this will be the last release candidate, <strong>IPFire 2.7 RC5</strong> is avaiable.
+ <br />
+ This version is only suitable for testing and should not be used in productive environments.
+ <br />
+ Download: <a href=\"http://people.ipfire.org/~arne_f/testing/\" target=\"_blank\">Mirror 1</a> |
+ <a href=\"http://testing.ipfire.at/\" target=\"_blank\">Mirror 2</a>
+ <br />
+ If you have experienced any bugs please report them to the <a href=\"http://bugtracker.ipfire.org/\"
+ target=\"_blank\">bugtracker</a>. Thank you!
+ <br />
+ Changes you will find at the
+ <a href=\"http://forum.ipfire.org/index.php?topic=2436.0\" target=\"_blank\">IPFire forum</a>.
+ </p>",
+
+ "de" : "<p>Wahrscheinlich wird dies der letzte Release Candidate, <strong>IPFire 2.7 RC5</strong>
+ steht absofort bereit.
+ <br />Diese Version ist ausschließlich zu Testzwecken geeignet und sollte nicht in Produktivumgebungen benutzt werden.
+ <br />
+ Download: <a href=\"http://people.ipfire.org/~arne_f/testing/\" target=\"_blank\">Mirror 1</a> |
+ <a href=\"http://testing.ipfire.at/\" target=\"_blank\">Mirror 2</a>
+ <br />
+ Gefundene Fehler bitte im <a href=\"http://bugtracker.ipfire.org/\" target=\"_blank\">Bugtracker</a> melden. Vielen Dank!
+ <br />
+ Änderungen findet man im
+ <a href=\"http://forum.ipfire.org/index.php?topic=2436.0\" target=\"_blank\">IPFire Forum</a>.
+ </p>"}},
+
+ "38" : {"author" : "Jan Paul Tuecking",
+ "mail" : "earl@ipfire.org",
+ "subject" : { "en" : "IPFire 2.7 final", "de" : "IPFire 2.7 final" },
+ "date" : "2010-07-02",
+ "link" : "",
+ "content" :
+ { "en" : "<p>It is time - today we are going to release <strong>IPFire 2.7</strong>.
+ At first we will <strong>only</strong> release the ISO files, the update is not <strong>yet</strong> available via pakfire.<br />
+ The reason for this is the change of the IPSec software from OpenSwan to StrongSwan and the mandatory changes in the configuration of net2net connections. The update on pakfire will be released next friday 2010-07-09,
+ so there is enough time to change the IPSec tunnels, more information about this is avaiable at the
+ <a href=\"http://wiki.ipfire.org/en/configuration/services/ipsec_update\" target=\"_blank\">Wiki</a>.
+ <br />There are about 400 changes in the new IPFire Version. All commits can be found at the
+ <a href=\"http://git.ipfire.org/?p=ipfire-2.x.git;a=log;h=refs/heads/core38\" target=\"_blank\">GIT (changelog)</a>.
+ <br />
+ Changes among others are:
+ <ul>
+ <li>Updates</li>
+ <ul>
+ <li>Updated <strong>Kernel</strong> to stable lts (2.6.32.15)</li>
+ <li>Updated openssl to version 0.9.8o</li>
+ <li>Updated Net-SSLeay to version 1.36</li>
+ <li>Updated smartmontools to version 5.39.1</li>
+ <li>Updated usb-modeswitch to version 1.1.2</li>
+ <li>Updated alsa to version 1.0.23</li>
+ <li>Updated memtest to version 4.10</li>
+ <li>Updated v4l-dvb (2010-05-20)</li>
+ <li>Updated kvm-kmod to version 2.6.33.1</li>
+ <li>Updated compat-wireless to version 2.6.34</li>
+ <li>Updated hardware and GeoIP database</li>
+ <li>Updated squid to current stable version</li>
+ <li>Updated mISDN, mISDNuser (25.5.2010) and lcr to version 1.7</li>
+ </ul>
+ <li>VPN</li>
+ <ul>
+ <li>Switched IPSec from OpenSwan to StrongSwan version 4.4.0</li>
+ <li>Fixed vpn-watch hang at connection restart</li>
+ <li>Many other IPSec fixes</li>
+ <li>Updated OpenVPN to current stable version</li>
+ <li>New advanced settings for OpenVPN avaiable [bug #490]</li>
+ <li>Removed not working tap device</li>
+ <li>Load cryptodev modules by default</li>
+ </ul>
+ <li>Snort</li>
+ <ul>
+ <li>Updated snort to stable 2.8.6</li>
+ <li>Removed snort md5 check, added free space check</li>
+ <li>Fixed Snort init script, added sleep before chmod</li>
+ <li>Many snort config and script changes</li>
+ <li>Fixed detection of snort descriptions</li>
+ <li>Replaced snort gpl community rules by emergingthreats</li>
+ <li>Many Guardian fixes like ignore file handling and linefead detection</li>
+ </ul>
+ <li>Hardware</li>
+ <ul>
+ <li>Added support for alix2 leds</li>
+ <li>Added Vodafone K3765 and K4505 usbids to option driver</li>
+ </ul>
+ <li>Webinterface</li>
+ <ul>
+ <li>Cosmetic change for the swap and load graphs</li>
+ <li>Fixed some naming and length problems in the outgoing firewall</li>
+ <li>Fixed naming of firewall groups for webinterface</li>
+ <li>Added clearer description for P2P block</li>
+ <li>Added links for services on services.cgi [bug #617]</li>
+ <li>Added clearer button for stopping services</li>
+ <li>Added new iptables GUI</li>
+ <li>Fixed white page at first start of ids.cgi</li>
+ <li>Fixed update acclerator file download</li>
+ </ul>
+ <li>Firewall</li>
+ <ul>
+ <li>Added grouping option to the outgoing firewall - multiport and network group rules</li>
+ <li>Added space to logging entries by outgoing firewall</li>
+ </ul>
+ <li>Language</li>
+ <ul>
+ <li>Added spanish translation of installer and setup</li>
+ <li>Added spanish webif translation</li>
+ </ul>
+ <li>Others</li>
+ <ul>
+ <li>Added an config setting to remove netfilter sip modules</li>
+ <li>Syslog async logging feature</li>
+ <li>Resized /var/log/rrd in fstab</li>
+ <li>Changed size of the swapfile</li>
+ <li>Done a whole rework on the collectd config</li>
+ <li>misc-progs: Cleanup chain creation of wirelessctrl</li>
+ <li>Modified modules initscript to softly fail module loads</li>
+ <li>Added new led triggers: netdev</li>
+ <li>Added e2fsck.conf, this should fix manual superblock checls</li>
+ <li>Enabled force setting system time on boot</li>
+ <li>Fixed url filter repository for local redirects</li>
+ <li>Fixed squidclamav logging [bug #639]</li>
+ <li>Increase length of the password dialog to 50 chars</li>
+ <li>Added bootoption to skip an initskript</li>
+ <li>Blacklistet all framebuffer modules</li>
+ <li>Fixed rebuildhost [bug #509]</li>
+ <li>Allow also ip/netmask for blue access</li>
+ <li>Fixed grub installation on virtio hdd</li>
+ <li>Changed the flash serialcon image</li>
+ </ul>
+ </ul>
+ </p>",
+
+ "de" : "<p>Es ist so weit - heute werden wir <strong>IPFire 2.7</strong> freigeben.<br />
+ Zuerst veröffentlichen wir <strong>nur</strong> die Installations-ISOs. Über Pakfire ist das Update auf 2.7 <strong>noch</strong> nicht
+ verfügbar.<br />
+ Der Grund hierfür liegt an der Umstellung für IPSec von OpenSwan auf StrongSwan und die damit verbunden zwingenden Änderungen
+ bei laufenden Net2Net-Verbindungen. Das Update über Pakfire wird am Freitag, 09.07.2010 freigegeben. So bleibt genügend Zeit
+ die IPSec Tunnel auf Strongwan anzupassen. Mehr Informationen hierüber findet man im
+ <a href=\"http://wiki.ipfire.org/de/configuration/services/ipsec_update\" target=\"_blank\">Wiki</a>.
+ <br />Insgesammt sind an die 400 Änderungen in die neue IPFire Version eingeflossen, alle Commits hierzu findet man im
+ <a href=\"http://git.ipfire.org/?p=ipfire-2.x.git;a=log;h=refs/heads/core38\" target=\"_blank\">GIT (Changelog)</a>.
+ <br />
+ Änderungen sind unter anderem:
+ <ul>
+ <li>Updates</li>
+ <ul>
+ <li>Update vom <strong>Kernel</strong> auf stabile Version mit LTS (2.6.32.15)</li>
+ <li>Update von openssl auf Version 0.9.8o</li>
+ <li>Update von Net-SSLeay auf Version 1.36</li>
+ <li>Update von smartmontools auf Version 5.39.1</li>
+ <li>Update von usb-modeswitch auf Version 1.1.2</li>
+ <li>Update von alsa auf Version 1.0.23</li>
+ <li>Update von memtest auf Version 4.10</li>
+ <li>Update von v4l-dvb (2010-05-20)</li>
+ <li>Update von kvm-kmod auf Version 2.6.33.1</li>
+ <li>Update von compat-wireless auf Version 2.6.34</li>
+ <li>Update von Hardware und GeoIP Datenbank</li>
+ <li>Update von squid auf die letzte stabile Version</li>
+ <li>Update von mISDN, mISDNuser (25.5.2010) und lcr auf Version 1.7</li>
+ </ul>
+ <li>VPN</li>
+ <ul>
+ <li>Änderung der IPSec Software von OpenSwan nach StrongSwan Version 4.4.0</li>
+ <li>'vpn-watch hing nach einem Verbindungsneustart' behoben</li>
+ <li>Viele kleine IPSec-Fehler behoben</li>
+ <li>Update von OpenVPN auf die letzte stabile Version</li>
+ <li>Neue Möglichkeiten unter 'Erweiterte Einstellungen' für OpenVPN [Bug #490]</li>
+ <li>Das nicht funktionierende tap-Device wurde entfernt</li>
+ <li>cryptodev-Module werden nun geladen</li>
+ </ul>
+ <li>Snort</li>
+ <ul>
+ <li>Update von Snort auf die stabile Version 2.8.6</li>
+ <li>MD5-Check wurde entfernt - Überprüfung von freien Speicher wurde hinzugefügt</li>
+ <li>Fehler in init-Skript wurden behoben</li>
+ <li>Es wurden mehrere Snort Konfigurations- und Skriptanpassungen gemacht</li>
+ <li>Fehler in der Erkennung von Snort Beschreibungen wurde behoben</li>
+ <li>Austausch der Snort GPL-Community-Rule gegen Regeln von Emergingthreats</li>
+ <li>Mehere Guardian-Fehler wurden behoben</li>
+ </ul>
+ <li>Hardware</li>
+ <ul>
+ <li>Support für Alix2-LEDs wurde hinzugefügt</li>
+ <li>Treiber für Vodafone K3765 and K4505 wurden hinzugefügt</li>
+ </ul>
+ <li>Webinterface</li>
+ <ul>
+ <li>Kosmetische Änderungen am Swap- und Load-Graph</li>
+ <li>Fehler bei der Bennenung und Längenproblem in der ausgehenden Firewall behoben</li>
+ <li>Fehler bei der Bennenung von Firewall-Gruppen behoben</li>
+ <li>Eine bessere Beschreibung der P2P-Optionen wurde hinzugefügt</li>
+ <li>Auf der services.cgi werden die Diensten nun mit entsprechenden Links dargestellt [Bug #617]</li>
+ <li>Verbesserter Button für das Stoppen von Diensten</li>
+ <li>Neue iptables-GUI</li>
+ <li>Der Fehler, dass die ids.cgi-Seite beim ersten laden leer blieb, wurde behoben</li>
+ <li>Update-Acclerator: Dateidownload Fehler wurde behoben</li>
+ </ul>
+ <li>Firewall</li>
+ <ul>
+ <li>Neue Gruppenoption wurde der ausgehenden Firewall hinzugefügt, für Multiport- und Netzwerk-Gruppen-Regeln</li>
+ <li>Ein Leerzeichen zur verbesserten Lesbarkeit der ausgehenden Firewall-Logs wurde hinzugefügt</li>
+ </ul>
+ <li>Sprachen</li>
+ <ul>
+ <li>Spanische Übersetzung für Installer und Setupmenü wurde hinzugefügt</li>
+ <li>Spanische Übersetzung des Webinterfaces hinzugefügt</li>
+ </ul>
+ <li>Sonstiges</li>
+ <ul>
+ <li>Eine Konfigurationoption wurde hinzugefügt um die Netfilter-SIP-Module zu deaktivieren</li>
+ <li>Syslog-async-Loggingfunktion hinzugefügt</li>
+ <li>Größe von /var/log/rrd in fstab geändert</li>
+ <li>Größe der Swapdatei geändert</li>
+ <li>Komplette Ãœberarbeitung der collectd-Konfiguration</li>
+ <li>Die Erstellung der Chains in der wirelessctrl wurde bereinigt</li>
+ <li>Neue LED-Trigger hinzugefügt: netdev</li>
+ <li>Eine e2fsck.conf wurde hinzugefügt um den Fehler der Superblock-Checks zu beheben</li>
+ <li>Fehler im squidclamav-Logging wurde behoben [Bug #639]</li>
+ <li>Erhöhung der Passwortlänge im Installer auf 50 Zeichen</li>
+ <li>Es wurde eine Bootoption hinzugefügt, welche bestimmte Init-Skripte überspringen kann</li>
+ <li>Es wurden alle Frambuffer-Module der Blacklist hinzugefügt</li>
+ <li>Fehler im rebuildhost behoben [Bug #509]</li>
+ <li>Fehler in GRUB bei der Installation auf Virtio-Blockdevices wurde behoben</li>
+ </ul>
+ </ul>
+ </p>"}},
+
+ "39" : {"author" : "Jan Paul Tuecking",
+ "mail" : "earl@ipfire.org",
+ "subject" : { "en" : "IPFire 2.7 final via pakfire", "de" : "IPFire 2.7 final via pakfire" },
+ "date" : "2010-07-09",
+ "link" : "",
+ "content" :
+ { "en" : "<p>From today it will be possible to update old IPFire systems via the package manager
+ to the brand new version <strong>IPFire 2.7</strong>.
+ <br />We want to point out again that the update to StrongSwan comes with
+ <a href=\"http://wiki.ipfire.org/en/configuration/services/ipsec_update\" target=\"_blank\">mandatory changes</a>
+ for existing IPSec tunnels with PSK.
+ <br />
+ <br />Because of to the kernel update, a reboot will be needed.<br />
+ </p>",
+
+ "de" : "<p>Ab heute wird es nun auch möglich sein, über den Paketmanager alte IPFire-Systeme
+ auf die Version <strong>IPFire 2.7</strong> zu aktuallsieren.
+ <br />Wir wollen erneut darauf hinweisen, dass durch das Update auf StrongSwan
+ <a href=\"http://wiki.ipfire.org/de/configuration/services/ipsec_update\" target=\"_blank\">zwingend eine Änderung</a> an den
+ bestehenden IPSec-Tunneln mit PSK vorgenommen werden muss.
+ <br />
+ <br />Durch das Update des Kernels ist ein Neustart von IPFire nötig.<br/>
+ </p>"}},
+
+ "40" : {"author" : "Jan Paul Tuecking",
+ "mail" : "earl@ipfire.org",
+ "subject" : { "en" : "Core Update 39", "de" : "Core Update 39" },
+ "date" : "2010-08-01",
+ "link" : "",
+ "content" :
+ { "en" : "<p>Today we are going to release <strong>Core 39</strong>.<br />
+ The most significant changes are the fixed download of snort rules and the update of the ppp daemon to version 2.4.5.<br />
+ Despite of that it comes with the following changes:<br />
+ <ul>
+ <li>Updated libpng to version 1.2.44 (critical vulnerability)</li>
+ <li>Fixed the creating of the backupiso</li>
+ <li>Fixed dhcp client helper script to handle multiple dns servers</li>
+ <li>Fixed blacklist update and cache cleanup of the Update-Accelerator/URL filter</li>
+ <li>Added missing terminfo file for screen</li>
+ <li>Enabled support for Cisco VPN clients</li>
+ </ul>
+ </p>",
+
+ "de" : "<p>Heute werden wir <strong>Core 39</strong> veröffentlichen.<br />
+ Die wichtigsten Änderungen sind insbesondere die Aktualisierung des Snort-Regeldownloads
+ und des ppp-Daemon auf die Version 2.4.5.<br />
+ Desweiteren bringt es folgende Änderungen mit sich:<br />
+ <ul>
+ <li>Update der libpng auf Version 1.2.44 (kritische Lücke)</li>
+ <li>Fehler beim Erstellen der Backup-ISO behoben</li>
+ <li>Fehler im DHCP Client-Helper-Script behoben (Multiple DNS-Server wurden falsch verarbeitet)</li>
+ <li>Fehler im Blacklistenupdate und Cachecleanup vom Update-Accelerator/URL-Filter behoben</li>
+ <li>Die fehlende terminfo für Screen wurde hinzugefügt</li>
+ <li>Support für Cisco VPN-Clients hinzugefügt</li>
+ </ul>
+ </p>"}}
}
[
- { "name" : "IPFire 2.5 - Core 37",
+ { "name" : "IPFire 2.7 - Core 39",
"status" : "stable",
"online" : 1,
+ "files" : [
+ {
+ "type" : "alix",
+ "name" : "ipfire-2.7.1gb-ext2-scon.i586-full-core39.img.gz",
+ "sha1" : "a567fc27f4d85ac7c18fa52fbfcf8539eb34bc85"
+ },
+ {
+ "type" : "flash",
+ "name" : "ipfire-2.7.1gb-ext2.i586-full-core39.img.gz",
+ "sha1" : "14c746d895f2400ea7ffaff54a01630b55f62ba9"
+ },
+ {
+ "type" : "iso",
+ "name" : "ipfire-2.7.i586-full-core39.iso",
+ "sha1" : "fff98747a60981f7f9db642ffd8984fa459ffd44"
+ },
+ {
+ "type" : "torrent",
+ "name" : "ipfire-2.7.i586-full-core39.iso.torrent",
+ "hash" : "915E1F25919C8CD9D651CB250CEC00362B41C580"
+ },
+ {
+ "type" : "usbfdd",
+ "name" : "ipfire-2.7-install-usb-fdd.i586-full-core39.img.gz",
+ "sha1" : "dbba94f216632105b3591f04feada0f4fa74edc8"
+ },
+ {
+ "type" : "usbhdd",
+ "name" : "ipfire-2.7-install-usb-hdd.i586-full-core39.img.gz",
+ "sha1" : "6c806d017336e4349938c3a0aa765142cb3fb184"
+ },
+ {
+ "type" : "xen",
+ "name" : "ipfire-2.7.xen.i586-full-core39.tar.bz2",
+ "sha1" : "7eb2f700659be180f1f7195fd7abb1f5b61ede96"
+ }
+ ]
+ },
+
+ { "name" : "IPFire 2.7 - Core 38",
+ "status" : "stable",
+ "online" : 1,
+ "files" : [
+ {
+ "type" : "alix",
+ "name" : "ipfire-2.7.1gb-ext2-scon.i586-full-core38.img.gz",
+ "sha1" : "1b2a5795da9f7c7e8e276f5f9a3e77843ea612cb"
+ },
+ {
+ "type" : "flash",
+ "name" : "ipfire-2.7.1gb-ext2.i586-full-core38.img.gz",
+ "sha1" : "db546eced1c9b07df9ce196c9642874371cb19df"
+ },
+ {
+ "type" : "iso",
+ "name" : "ipfire-2.7.i586-full-core38.iso",
+ "sha1" : "9ad97d399824772b01aef20d2f9ca0bb39972f19"
+ },
+ {
+ "type" : "torrent",
+ "name" : "ipfire-2.7.i586-full-core38.iso.torrent",
+ "hash" : "9A1BEEEDB8ADC094683B5E268C201FDA43702379"
+ },
+ {
+ "type" : "usbfdd",
+ "name" : "ipfire-2.7-install-usb-fdd.i586-full-core38.img.gz",
+ "sha1" : "56a8685614eefce7c5cce1302cc99687f00afebc"
+ },
+ {
+ "type" : "usbhdd",
+ "name" : "ipfire-2.7-install-usb-hdd.i586-full-core38.img.gz",
+ "sha1" : "6f3dfa23e7fe7176fccf78907ccd3dd3a4a74a0b"
+ },
+ {
+ "type" : "xen",
+ "name" : "ipfire-2.7.xen.i586-full-core38.tar.bz2",
+ "sha1" : "bdefe67bf1d06d59a8d61e6212836cccb8fecca6"
+ }
+ ]
+ },
+
+ { "name" : "IPFire 2.5 - Core 37",
+ "status" : "stable",
+ "online" : 0,
"files" : [
{
"type" : "alix",
}
]
},
+
{ "name" : "IPFire 2.5 - Core 36",
"status" : "stable",
- "online" : 1,
+ "online" : 0,
"files" : [
{
"type" : "alix",
{ "name" : "IPFire 2.5 - Core 35",
"status" : "stable",
- "online" : 1,
+ "online" : 0,
"files" : [
{
"type" : "alix",
{ "name" : "IPFire 2.5 - Core 34",
"status" : "stable",
- "online" : 1,
+ "online" : 0,
"files" : [
{
"type" : "alix",
{ "name" : "IPFire 2.5 - Core 33",
"status" : "stable",
- "online" : 1,
+ "online" : 0,
"files" : [
{
"type" : "alix",
{ "name" : "IPFire 1.4.9 - FINAL",
"status" : "stable",
- "online" : 1,
+ "online" : 0,
"files" : [
{
"type" : "iso",
#main_inner .post ul
{
-padding-left: 1.0em;
+padding-left: 1.5em;
}
#main_inner .post ul a
+++ /dev/null
-nodes = new Array();
-id = 0;
-busy = false;
-
-update = function() {
- $.getJSON("/api/cluster_info", { id : id++ },
- function(data) {
- // If we are already busy then exit
- if (busy == true) return;
-
- var count = 0;
-
- if (data.error != "null") return;
-
- busy = true;
-
- $.each(data.result.nodes, function(i, node) {
- var nodeid = node.hostname.replace(/\./g, "");
- count++;
-
- nodes[nodeid] = true;
-
- if ($("#" + nodeid).length) {
- $("#" + nodeid + "_speed").html(node.speed);
- } else {
- row = "<tr id=\"" + nodeid + "\" class=\"node\">";
- row += " <td id=\"" + nodeid + "_hostname\"></td>";
- row += " <td id=\"" + nodeid + "_arch\">" + node.arch + "</td>";
- row += " <td><span id=\"" + nodeid + "_loadbar\"></span></td>";
- row += " <td><span id=\"" + nodeid + "_jobs\"></span></td>";
- row += " <td id=\"" + nodeid + "_speed\">" + node.speed + "</td>";
- row += "</tr>";
- $("#nodes").append(row);
- }
- $("#" + nodeid + "_loadbar").progressBar(node.load, {showText: false});
- $("#" + nodeid + "_jobs").progressBar(node.jobcount.split("/")[0], { max: node.jobcount.split("/")[1], textFormat: 'fraction'});
- if (node.installing == true) {
- $("#" + nodeid + "_hostname").html(node.hostname + " *");
- } else {
- $("#" + nodeid + "_hostname").html(node.hostname);
- }
- });
-
- $("#loadbar").progressBar(data.result.cluster.load);
- $("#jobbar").progressBar(data.result.cluster.jobcount.split("/")[0], { max: data.result.cluster.jobcount.split("/")[1], textFormat: 'fraction'});
- for (var nodeid in nodes) {
- if (nodes[nodeid] == false) {
- $("#" + nodeid).remove();
- nodes.pop(nodeid);
- } else {
- nodes[nodeid] = false;
- }
- }
- $("#count").html(count);
- busy = false;
- });
-}
-
-$(document).ready(function(){
- // Init loadbar
- $("#loadbar").progressBar();
-
- update();
- setInterval("update()", 2000);
-})
+++ /dev/null
-
-(function($){$.extend({progressBar:new function(){this.defaults={steps:20,step_duration:20,max:100,showText:true,textFormat:'percentage',width:120,height:12,callback:null,boxImage:'/static/images/progressbar.gif',barImage:{0:'/static/images/progressbg_green.gif',30:'/static/images/progressbg_orange.gif',70:'/static/images/progressbg_red.gif'},running_value:0,value:0,image:null};this.construct=function(arg1,arg2){var argvalue=null;var argconfig=null;if(arg1!=null){if(!isNaN(arg1)){argvalue=arg1;if(arg2!=null){argconfig=arg2;}}else{argconfig=arg1;}}
-return this.each(function(child){var pb=this;var config=this.config;if(argvalue!=null&&this.bar!=null&&this.config!=null){this.config.value=argvalue
-if(argconfig!=null)
-pb.config=$.extend(this.config,argconfig);config=pb.config;}else{var $this=$(this);var config=$.extend({},$.progressBar.defaults,argconfig);config.id=$this.attr('id')?$this.attr('id'):Math.ceil(Math.random()*100000);if(argvalue==null)
-argvalue=$this.html().replace("%","")
-config.value=argvalue;config.running_value=0;config.image=getBarImage(config);$this.html("");var bar=document.createElement('img');var text=document.createElement('span');var $bar=$(bar);var $text=$(text);pb.bar=$bar;$bar.attr('id',config.id+"_pbImage");$text.attr('id',config.id+"_pbText");$text.html(getText(config));$bar.attr('title',getText(config));$bar.attr('alt',getText(config));$bar.attr('src',config.boxImage);$bar.attr('width',config.width);$bar.css("width",config.width+"px");$bar.css("height",config.height+"px");$bar.css("background-image","url("+config.image+")");$bar.css("background-position",((config.width*-1))+'px 50%');$bar.css("padding","0");$bar.css("margin","0");$this.append($bar);$this.append($text);}
-function getPercentage(config){return parseInt(config.running_value*100/config.max);}
-function getBarImage(config){var image=config.barImage;if(typeof(config.barImage)=='object'){for(var i in config.barImage){if(config.running_value>=parseInt(i)){image=config.barImage[i];}else{break;}}}
-return image;}
-function getText(config){if(config.showText){if(config.textFormat=='percentage'){return" "+Math.round(config.running_value)+"%";}else if(config.textFormat=='fraction'){return" "+config.running_value+'/'+config.max;}}}
-config.increment=Math.round((config.value-config.running_value)/config.steps);if(config.increment<0)
-config.increment*=-1;if(config.increment<1)
-config.increment=1;var t=setInterval(function(){var pixels=config.width/100;var stop=false;if(config.running_value>config.value){if(config.running_value-config.increment<config.value){config.running_value=parseInt(config.value);}else{config.running_value-=config.increment;}}
-else if(config.running_value<config.value){if(config.running_value+config.increment>config.value){config.running_value=parseInt(config.value);}else{config.running_value+=config.increment;}}
-if(config.running_value==config.value)
-clearInterval(t);var $bar=$("#"+config.id+"_pbImage");var $text=$("#"+config.id+"_pbText");var image=getBarImage(config);if(image!=config.image){$bar.css("background-image","url("+image+")");config.image=image;}
-$bar.css("background-position",(((config.width*-1))+(getPercentage(config)*pixels))+'px 50%');$text.html(getText(config));if(config.callback!=null&&typeof(config.callback)=='function')
-config.callback(config);pb.config=config;},config.step_duration);});};}});$.fn.extend({progressBar:$.progressBar.construct});})(jQuery);
\ No newline at end of file
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" />
- <title>{% block title %}{{ title }}{% end block %}</title>
+ <title>{{ hostname }} - {% block title %}{{ title }}{% end block %}</title>
<meta name="keywords" content="Linux, Firewall, IPFire, Security" />
<meta name="description" content="" />
<meta name="verify-v1" content="2LEf3W8naILGWVy2dhedSVEHPXTpp2xFNVsHXZMH1JI=" />
<img src="{{ static_url("images/Network-1.png") }}") }}" alt="IPFire Network" />
<div class="button">
<div class="button_text">
- <a href="download">Download IPFire 2.5</a>
+ <a href="download">Download IPFire 2.7</a>
</div>
</div>
</div>
<img src="{{ static_url("images/artwork/flyer_tn.png") }}" align="bottom" border= "0"/></a>
</div>
</p>
+
+ <p>
+ Designed by <a href="http://www.elricco.com" target="_blank" border="0">elricco media services</a>.
+ </p>
</div>
{% end block %}
{{ modules.SidebarBanner(banner) }}
{% block sidebar %}
- <h4>Public <span>relations</span></h4>
+ <h4><span>Artwork</span> list</h4>
<ul class="links">
<li class="first"><a href="#{{ _("online") }}">{{ _("Online media") }}</a></li>
<li><a href="#{{ _("print") }}">{{ _("Print media") }}</a></li>
- <li><a href="#{{ _("Licenses") }}">{{ _("Licenses") }}</a></li>
</ul>
{% end block %}
+++ /dev/null
-{% extends "../base.html" %}
-
-{% block title %}{{ _("Cluster") }}{% end block %}
-
-{% block content %}
- <h3>{{ _("Icecream Cluster Monitoring") }}</h3>
-
- <p>{{ _("Cluster's CPU load") }}:
- <span id="loadbar"></span>
- - {{ _("Job load") }}:
- <span id="jobbar"></span>
- </p>
-
- <table id="nodes">
- <thead>
- <tr>
- <th class="hostname">{{ _("Name") }}</th>
- <th class="arch">{{ _("Arch") }}</th>
- <th class="load">{{ _("CPU-Load") }}</th>
- <th class="jobs">{{ _("Jobs") }}</th>
- <th class="speed">{{ _("Speed") }}</th>
- </tr>
- </thead>
- <tbody>
- </tbody>
- </table>
-
- <p class="right"> <br />{{ _("Number of nodes") }}: <span id="count">-</span></p>
-
-{% end block %}
-
-{% block javascript %}
- <script type="text/javascript" src="{{ static_url("js/jquery.progressbar.js") }}"></script>
- <script type="text/javascript" src="{{ static_url("js/cluster.js") }}"></script>
-{% end block %}
{% block content %}
- <div class=post>
+ <div class="post">
<h3>{{ _("Development") }}</h3>
<img src="{{ static_url("images/page_icons/development.png") }}" class="floatTR" border="0" alt="{{ _("Development") }}" />
<p>
</div>
<br class="clear" />
- <div class=post>
+ <div class="post">
<a name="{{ _("git") }}"></a><h3>{{ _("git") }}</h3>
<img src=" http://git.ipfire.org/git-logo.png" class="floatTL" alt="{{ _("git") }}" />
<p>
<br class="clear" />
- <div class=post>
+ <div class="post">
<a name="{{ _("source-code") }}"></a><h3>{{ _("source-code") }}</h3>
<p>
{% if lang == "de" %}
</div>
- <div class=post>
+ <div class="post">
<a name="{{ _("bugtracker") }}"></a><h3>{{ _("bugtracker") }}</h3>
<img src="http://bugtracker.ipfire.org/images/mantis_logo.gif" class="floatTL" width="80" alt="{{ _("bugtracker") }}" />
<p>
<br class="clear" />
- <div class=post>
+ <div class="post">
<a name="{{ _("HowTos") }}"></a><h3>{{ _("HowTos") }}</h3>
<p>
{% if lang == "de" %}
</div>
- <div class=post>
+ <div class="post">
<a name="{{ _("IPFire 3.x") }}"></a><h3>{{ _("IPFire 3.x") }}</h3>
<p>
{% if lang == "de" %}
{% end %}
</div>
- <div class=post>
+ <div class="post">
<a name="{{ _("Artwork") }}"></a><h3>{{ _("Artwork") }}</h3>
<p>
{% if lang == "de" %}
<div class="post">
<h3>{{ _("Features") }}</h3>
- <img src="{{ static_url("images/features.png") }}" class="floatTR" alt="{{ _("Features") }}" />
+ <img src="{{ static_url("images/page_icons/features.png") }}" class="floatTR" alt="{{ _("Features") }}" />
<p>
{% if lang == "de" %}
Hier findet Ihr einen Überblick über alle derzeitig verfügbaren Funktionen
<br class="clear" />
<div class="post">
- <h3>{{ _("firewall functions") }}</h3>
+ <a name="{{ _("firewall functions") }}"></a><h3>{{ _("firewall functions") }}</h3>
<p>
{% if lang == "de" %}
Die Firewallfunktionalität ist die Hauptaufgabe von IPFire. Die Distribution trennt
<li>Eigene Netzwerksegmente für Server (DMZ) und Wireless-LAN mit angepassten Policies</li>
<li>DoS-Attacken-Schutz</li>
<li>Application-Proxies für HTTP und FTP (mit Zugangskontrolle und Content-Filter)</li>
- <li>Eingehende sowie ausgehende Paketfilterung</li>
+ <li>Eingehende sowie ausgehende Paketfilterung mit einfacher Gruppenverwaltung</li>
<li>Quality-of-Service und Trafficshaping</li>
</ul>
{% else %}
<li>separate network segments for server (DMZ) and wireless with custom policies</li>
<li>DoS attack protection</li>
<li>application proxies for HTTP and FTP (with access control and content filtering) and DNS</li>
- <li>incoming and outgoing packet filtering</li>
+ <li>incoming and outgoing packet filtering with user grouping</li>
<li>Quality of Service and traffic shaping</li>
</ul>
{% end %}
<br class="clear" />
<div class="post">
- <h3>{{ _("essential networking services") }}</h3>
+ <a name="{{ _("essential networking services") }}"></a><h3>{{ _("essential networking services") }}</h3>
<p>
{% if lang == "de" %}
IPFire stellt auch unabdingbare Funktionen jedem Netzwerk bereit.
</div>
<div class="post">
- <h3>{{ _("http proxy") }}</h3>
+ <a name="{{ _("http proxy") }}"></a><h3>{{ _("http proxy") }}</h3>
<p>
{% if lang == "de" %}
Ein Webproxy ermöglicht dem Administrator Kontrolle über Nutzeraktivitäten
</div>
<div class="post">
- <h3>{{ _("virtual private networking") }}</h3>
+ <a name="{{ _("virtual private networking") }}"></a><h3>{{ _("virtual private networking") }}</h3>
<p>
{% if lang == "de" %}
Virtuelle private Netzwerke (VPNs) sind nötig um mit einem entfernten
Interoperabilität bringt IPFire mehrere Lösung mit.
<ul>
- <li>IPSec/OpenSwan 2
+ <li>IPSec/Strongswan
<ul>
<li>Netz-zu-Netz- oder Netz-zu-Host-Verbindungen (Roadwarrior)</li>
<li>IKE - PreSharedKey oder</li>
with multiple implementations.
<ul>
- <li>IPSec/OpenSwan 2
+ <li>IPSec/Strongswan
<ul>
<li>network-to-network or network-to-host (roadwarrior)</li>
<li>IKE - PreSharedKey or</li>
</div>
<div class="post">
- <h3>{{ _("supported connection types") }}</h3>
+ <a name="{{ _("supported connection types") }}"></a><h3>{{ _("supported connection types") }}</h3>
<p>
{% if lang == "de" %}
IPFire ist über eine Vielzahl von Verbindungsmöglichkeiten an
</div>
<div class="post">
- <h3>{{ _("configuration") }}</h3>
+ <a name="{{ _("configuration") }}"></a><h3>{{ _("configuration") }}</h3>
<p>
{% if lang == "de" %}
Alle Funktionen sind in einem Web-Interface bequem erreichbar.
</div>
<div class="post">
- <h3>{{ _("monitoring") }}</h3>
+ <a name="{{ _("monitoring") }}"></a><h3>{{ _("monitoring") }}</h3>
<p>
{% if lang == "de" %}
Um dem Administrator die Auswerung der Geschehnisse möglichst zu vereinfachen
</p>
</div>
{% end block %}
+
+
+{% block sidebar %}
+ <h4><span>Features</span> list</h4>
+ <ul class="links">
+ <li class="first"><a href="#{{ _("firewall functions") }}">{{ _("firewall functions") }}</a></li>
+ <li><a href="#{{ _("essential networking services") }}">{{ _("essential networking services") }}</a></li>
+ <li><a href="#{{ _("http proxy") }}">{{ _("http proxy") }}</a></li>
+ <li><a href="#{{ _("virtual private networking") }}">{{ _("virtual private networking") }}</a></li>
+ <li><a href="#{{ _("supported connection types") }}">{{ _("supported connection types") }}</a></li>
+ <li><a href="#{{ _("configuration") }}">{{ _("configuration") }}</a></li>
+ <li><a href="#{{ _("monitoring") }}">{{ _("monitoring") }}</a></li>
+ </ul>
+
+
+
+
+{% end block %}
+++ /dev/null
-{% extends "base.html" %}
-
-{% block title %}{{ _("Translations") }}{% end block %}
-
-{% block content %}
- <h3>IPFire {{ _("Translation Status") }}</h3>
-
- <div id="tabs">
- <ul>
- {% for project in projects %}
- <li>
- <a href="#{{ project.id }}">{{ project.name }}</a>
- </li>
- {% end %}
- </ul>
- </div>
-
- {% for project in projects %}
- <div id="{{ project.id }}">
- <p><strong>{{ _("Description") }}:</strong> {{ project.desc }}</p>
- <br />
- <table class="translate">
- <tr>
- <th>{{ _("Language") }}</th>
- <th>{{ _("Translated") }}</th>
- <th>{{ _("Untranslated") }}</th>
- <th>{{ _("Fuzzy") }}</th>
- <th>{{ _("Status") }}</th>
- </tr>
-
- {% for translation in project.translations %}
- <tr>
- <td class="lang"><img src="{{ static_url("images/flags/%s.png" % translation.code) }}"
- alt="{{ translation.code }}" />{{ translation.lang }}</td>
- <td>{{ translation.translated }}</td>
- <td>{{ translation.untranslated }}</td>
- <td>{{ translation.fuzzy }}</td>
- <td>{{ translation.percent }}</td>
- </tr>
- {% end %}
- </table>
- {% end %}
-
- <p class="right">
- <strong>{{ _("Template") }}</strong> - {{ project.total_strings }} strings
- </p>
-{% end block %}
-
-{% block javascript %}
- <script type="text/javascript">
- $(function() {
- $("#tabs").tabs();
- });
- </script>
-{% end block %}
case "$1" in
start)
- cd ${HOMEDIR} && ./webapp.py >>${LOGFILE} 2>&1 &
+ if ps ax | grep -v grep | grep webapp.py > /dev/null
+ then
+ echo "webapp is allready running..."
+ else
+ echo "Starting webapp..."
+ cd ${HOMEDIR} && ./webapp.py >>${LOGFILE} 2>&1 &
+ fi
;;
stop)
- killall webapp.py
+ if ps ax | grep -v grep | grep webapp.py > /dev/null
+ then
+ echo "Stopping webapp..."
+ killall webapp.py &> /dev/null
+ else
+ echo "webapp is not running..."
+ fi
;;
restart)
;;
check)
- if (ps aux | grep -q webapp.py); then
- : # Process is running...
+ if ps ax | grep -v grep | grep webapp.py > /dev/null
+ then
+ :
+# echo "webapp is running..."
else
- $0 restart
+ echo "webapp is not running!"
+ $0 start
fi
;;
+
+ *)
+ echo "usage: webapp [ start | stop | restart | check ]"
+ ;;
+
esac
(r"/[A-Za-z]{2}/index", IndexHandler),
(r"/[A-Za-z]{2}/news", NewsHandler),
(r"/[A-Za-z]{2}/builds", BuildHandler),
- (r"/[A-Za-z]{2}/translations?", TranslationHandler),
# Download sites
(r"/[A-Za-z]{2}/downloads?", DownloadHandler),
(r"/[A-Za-z]{2}/downloads?/all", DownloadAllHandler),
# RSS feed
(r"/([A-Za-z]{2})/news.rss", RSSHandler),
(r"/data/feeds/main-([A-Za-z]{2}).rss", RSSHandler),
- # API
- (r"/api/cluster_info", ApiClusterInfoHandler),
# Always the last rule
(r"/[A-Za-z]{2}/(.*)", StaticHandler),
] + static_handlers)
(r"/", MainHandler),
(r"/[A-Za-z]{2}/?", MainHandler),
(r"/[A-Za-z]{2}/index", DownloadTorrentHandler),
+ (r"/a.*", TrackerAnnounceHandler),
+ (r"/scrape", TrackerScrapeHandler),
] + static_handlers)
# admin.ipfire.org
+++ /dev/null
-#!/usr/bin/python
-
-import os
-import telnetlib
-
-class Node(object):
- def __init__(self, hostname, address, arch, speed, jobcount, load, installing):
- self.hostname = hostname
- self.address = address
- self.arch = arch
- self.speed = speed
- self.installing = installing
-
- (jobs_cur, jobs_max) = jobcount.split("/")
- if jobs_cur > jobs_max:
- jobs_cur = jobs_max
- self.jobcount = "%s/%s" % (jobs_cur, jobs_max)
-
- self.load = int(load) / 10 # in percent
-
- self.jobs = []
-
- def __str__(self):
- return self.hostname
-
- def __repr__(self):
- return "<Node %s>" % self.hostname
-
- def __cmp__(self, other):
- return cmp(self.hostname, other.hostname)
-
- def print_node(self):
- print "Hostname : %s" % self.hostname
- print " Address: %s" % self.address
- print " Arch : %s" % self.arch
- print " Speed : %s" % self.speed
- print " Jobs : %s" % self.jobcount
- print " Load : %s" % self.load
-
-class Job(object):
- def __init__(self, id, status, submitter, compiler, file):
- self.id = id
- self.status = status
- self.submitter = submitter
- self.compiler = compiler
- self.file = file
-
-
-class Cluster(object):
- def __init__(self, scheduler, port=8766):
- self.scheduler = scheduler
- self.port = port
-
- self._nodes = None
-
- def command(self, command):
- connection = telnetlib.Telnet(self.scheduler, self.port)
- connection.read_until("quit.\n")
- connection.write("%s\nquit\n" % command)
- return connection.read_until("200 done").split("\n")
-
- @property
- def load(self):
- if not self.nodes:
- return 0
- load = 0
- for node in self.nodes:
- load += node.load
- load /= len(self.nodes)
- return load
-
- @property
- def jobcount(self):
- jobs_cur = jobs_max = 0
- for node in self.nodes:
- jobs_cur += int(node.jobcount.split("/")[0])
- jobs_max += int(node.jobcount.split("/")[1])
- return "%s/%s" % (jobs_cur, jobs_max)
-
- @property
- def nodes(self):
- if self._nodes:
- return self._nodes
- ret = []
- data = self.command("listcs")
- node = None
- for line in data:
- if not line.startswith(" "):
- continue # does not belong to the data
-
- if line.startswith(" ") and node: # Job
- (a, b, c, id, status, submitter, compiler, file) = line.split(" ")
- submitter = submitter[4:]
- compiler = compiler[3:]
- file = os.path.basename(file)
- job = Job(id, status, submitter, compiler, file)
- node.jobs.append(job)
-
- elif line.startswith(" "): # Node
- installing = False
- a = line.split(" ")
- if len(a) > 7:
- installing = True
- line = " ".join(a[0:7])
-
- (a, hostname, address, arch, speed, jobcount, load) = line.split(" ")
- address = address.strip("()")
- arch = arch.strip("[]")
- speed = speed[6:]
- jobcount = jobcount[5:]
- load = load[5:]
- node = Node(hostname, address, arch, speed, jobcount, load, installing)
- ret.append(node)
-
- self._nodes = sorted(ret)
- return ret
-
- @property
- def json(self, *args):
- nodes = []
- ret = {}
- for node in self.nodes:
- tmp = { "hostname" : node.hostname,
- "address" : node.address,
- "arch" : node.arch,
- "jobcount" : node.jobcount,
- "load" : node.load,
- "speed" : node.speed,
- "installing" : node.installing,}
- jobs = []
- for job in node.jobs:
- jobs.append({ "id" : job.id,
- "status" : job.status,
- "submitter" : job.submitter,
- "compiler" : job.compiler,
- "file" : job.file, })
- tmp["jobs"] = jobs
- nodes.append(tmp)
- ret["nodes"] = nodes
- ret["cluster"] = { "load" : self.load,
- "jobcount" : self.jobcount, }
- return ret
-
-
-if __name__ == "__main__":
- cluster = Cluster("minerva.ipfire.org")
- print cluster.command("listcs")
- for node in cluster.nodes:
- node.print_node()
from mirrors import mirrors
from news import news
from releases import releases
+from torrent import tracker, bencode, bdecode, decode_hex
import builds
+import menu
import cluster
import markdown
-import translations
#import uriel
class BaseHandler(tornado.web.RequestHandler):
def render(self, *args, **kwargs):
nargs = self.render_args
nargs.update(kwargs)
- nargs["title"] = "%s - %s" % (self.request.host, nargs["title"])
+ nargs["hostname"] = self.request.host
tornado.web.RequestHandler.render(self, *args, **nargs)
def link(self, s):
pass
-class ApiClusterInfoHandler(BaseHandler):
- def get(self):
- id = self.get_argument("id", "null")
-
- c = cluster.Cluster(info["cluster"]["hostname"])
-
- self.write(simplejson.dumps({
- "version": "1.1",
- "id": id,
- "result" : c.json,
- "error" : "null", }))
- self.finish()
-
-
-class TranslationHandler(BaseHandler):
- def get(self):
- self.render("translations.html", projects=translations.projects)
-
-
class SourceHandler(BaseHandler):
def get(self):
source_path = "/srv/sources"
self.render("rss.xml", items=items, lang=lang)
+<<<<<<< HEAD
+class TrackerBaseHandler(tornado.web.RequestHandler):
+ def get_hexencoded_argument(self, name, all=False):
+ try:
+ arguments = self.request.arguments[name]
+ except KeyError:
+ return None
+
+ arguments_new = []
+ for argument in arguments:
+ arguments_new.append(decode_hex(argument))
+
+ arguments = arguments_new
+
+ if all:
+ return arguments
+
+ return arguments[0]
+
+ def send_tracker_error(self, error_message):
+ self.write(bencode({"failure reason" : error_message }))
+ self.finish()
+
+class TrackerAnnounceHandler(TrackerBaseHandler):
+ def get(self):
+ self.set_header("Content-Type", "text/plain")
+
+ info_hash = self.get_hexencoded_argument("info_hash")
+ if not info_hash:
+ self.send_tracker_error("Your client forgot to send your torrent's info_hash.")
+ return
+
+ peer = {
+ "id" : self.get_hexencoded_argument("peer_id"),
+ "ip" : self.get_argument("ip", None),
+ "port" : self.get_argument("port", None),
+ "downloaded" : self.get_argument("downloaded", 0),
+ "uploaded" : self.get_argument("uploaded", 0),
+ "left" : self.get_argument("left", 0),
+ }
+
+ event = self.get_argument("event", "")
+ if not event in ("started", "stopped", "completed", ""):
+ self.send_tracker_error("Got unknown event")
+ return
+
+ if peer["ip"]:
+ if peer["ip"].startswith("10.") or \
+ peer["ip"].startswith("172.") or \
+ peer["ip"].startswith("192.168."):
+ peer["ip"] = self.request.remote_ip
+
+ if peer["port"]:
+ peer["port"] = int(peer["port"])
+
+ if peer["port"] < 0 or peer["port"] > 65535:
+ self.send_tracker_error("Port number is not in valid range")
+ return
+
+ eventhandlers = {
+ "started" : tracker.event_started,
+ "stopped" : tracker.event_stopped,
+ "completed" : tracker.event_completed,
+ }
+
+ if event:
+ eventhandlers[event](info_hash, peer["id"])
+
+ tracker.update(hash=info_hash, **peer)
+
+ no_peer_id = self.get_argument("no_peer_id", False)
+ numwant = self.get_argument("numwant", tracker.numwant)
+
+ self.write(bencode({
+ "tracker id" : tracker.id,
+ "interval" : tracker.interval,
+ "min interval" : tracker.min_interval,
+ "peers" : tracker.get_peers(info_hash, limit=numwant,
+ random=True, no_peer_id=no_peer_id),
+ "complete" : tracker.complete(info_hash),
+ "incomplete" : tracker.incomplete(info_hash),
+ }))
+ self.finish()
+
+
+class TrackerScrapeHandler(TrackerBaseHandler):
+ def get(self):
+ info_hashes = self.get_hexencoded_argument("info_hash", all=True)
+
+ self.write(bencode(tracker.scrape(hashes=info_hashes)))
+ self.finish()
+=======
class PlanetBaseHandler(BaseHandler):
@property
def db(self):
entry.author = user
self.render("planet-posting.html", entry=entry, user=user)
+>>>>>>> planet
--- /dev/null
+#!/usr/bin/python
+
+import time
+
+import tornado.database
+
+
+def decode_hex(s):
+ ret = []
+ for c in s:
+ for i in range(256):
+ if not c == chr(i):
+ continue
+
+ ret.append("%0x" % i)
+
+ return "".join(ret)
+
+class Tracker(object):
+ id = "The IPFire Torrent Tracker"
+
+ # Intervals
+ interval = 60*60
+ min_interval = 30*60
+
+ numwant = 50
+
+ def __init__(self):
+ self.db = tornado.database.Connection(
+ host="172.28.1.150",
+ database="tracker",
+ user="tracker",
+ )
+
+ def _fetch(self, hash, limit=None, random=False, completed=False, no_peer_id=False):
+ query = "SELECT * FROM peers WHERE last_update >= %d" % self.since
+
+ if hash:
+ query += " AND hash = '%s'" % hash
+
+ if completed:
+ query += " AND left_data = 0"
+
+ if random:
+ query += " ORDER BY RAND()"
+
+ if limit:
+ query += " LIMIT %s" % limit
+
+ peers = []
+ for peer in self.db.query(query):
+ if not peer.ip or not peer.port:
+ continue
+
+ peer_dict = {
+ "ip" : str(peer.ip),
+ "port" : int(peer.port),
+ }
+
+ if not no_peer_id:
+ peer_dict["peer id"] = str(peer.id),
+
+ peers.append(peer_dict)
+
+ return peers
+
+ def get_peers(self, hash, **kwargs):
+ return self._fetch(hash, **kwargs)
+
+ def get_seeds(self, hash, **kwargs):
+ kwargs.update({"completed" : True})
+ return self._fetch(hash, **kwargs)
+
+ def complete(self, hash):
+ return len(self.get_seeds(hash))
+
+ def incomplete(self, hash):
+ return len(self.get_peers(hash))
+
+ def event_started(self, hash, peer_id):
+ # Damn, mysql does not support INSERT IF NOT EXISTS...
+ if not self.db.query("SELECT id FROM peers WHERE hash = '%s' AND peer_id = '%s'" % (hash, peer_id)):
+ self.db.execute("INSERT INTO peers(hash, peer_id) VALUES('%s', '%s')" % (hash, peer_id))
+
+ if not hash in [h["hash"] for h in self.hashes]:
+ self.db.execute("INSERT INTO hashes(hash) VALUES('%s')" % hash)
+
+ def event_stopped(self, hash, peer_id):
+ self.db.execute("DELETE FROM peers WHERE hash = '%s' AND peer_id = '%s'" % (hash, peer_id))
+
+ def event_completed(self, hash, peer_id):
+ self.db.execute("UPDATE hashes SET completed=completed+1 WHERE hash = '%s'" % hash)
+
+ def scrape(self, hashes=[]):
+ ret = {}
+ for hash in self.db.query("SELECT hash, completed FROM hashes"):
+ hash, completed = hash.hash, hash.completed
+
+ if hashes and hash not in hashes:
+ continue
+
+ ret[hash] = {
+ "complete" : self.complete(hash),
+ "downloaded" : completed or 0,
+ "incomplete" : self.incomplete(hash),
+ }
+
+ return ret
+
+ def update(self, hash, id, ip=None, port=None, downloaded=None, uploaded=None, left=None):
+ args = [ "last_update = '%s'" % self.now ]
+
+ if ip:
+ args.append("ip='%s'" % ip)
+
+ if port:
+ args.append("port='%s'" % port)
+
+ if downloaded:
+ args.append("downloaded='%s'" % downloaded)
+
+ if uploaded:
+ args.append("uploaded='%s'" % uploaded)
+
+ if left:
+ args.append("left_data='%s'" % left)
+
+ if not args:
+ return
+
+ query = "UPDATE peers SET " + ", ".join(args) + \
+ " WHERE hash = '%s' AND peer_id = '%s'" % (hash, id)
+
+ self.db.execute(query)
+
+ @property
+ def hashes(self):
+ return self.db.query("SELECT * FROM hashes");
+
+ @property
+ def now(self):
+ return int(time.time())
+
+ @property
+ def since(self):
+ return int(time.time() - self.interval)
+
+
+tracker = Tracker()
+
+
+##### This is borrowed from the bittorrent client libary #####
+
+def decode_int(x, f):
+ f += 1
+ newf = x.index('e', f)
+ n = int(x[f:newf])
+ if x[f] == '-':
+ if x[f + 1] == '0':
+ raise ValueError
+ elif x[f] == '0' and newf != f+1:
+ raise ValueError
+ return (n, newf+1)
+
+def decode_string(x, f):
+ colon = x.index(':', f)
+ n = int(x[f:colon])
+ if x[f] == '0' and colon != f+1:
+ raise ValueError
+ colon += 1
+ return (x[colon:colon+n], colon+n)
+
+def decode_list(x, f):
+ r, f = [], f+1
+ while x[f] != 'e':
+ v, f = decode_func[x[f]](x, f)
+ r.append(v)
+ return (r, f + 1)
+
+def decode_dict(x, f):
+ r, f = {}, f+1
+ while x[f] != 'e':
+ k, f = decode_string(x, f)
+ r[k], f = decode_func[x[f]](x, f)
+ return (r, f + 1)
+
+decode_func = {}
+decode_func['l'] = decode_list
+decode_func['d'] = decode_dict
+decode_func['i'] = decode_int
+decode_func['0'] = decode_string
+decode_func['1'] = decode_string
+decode_func['2'] = decode_string
+decode_func['3'] = decode_string
+decode_func['4'] = decode_string
+decode_func['5'] = decode_string
+decode_func['6'] = decode_string
+decode_func['7'] = decode_string
+decode_func['8'] = decode_string
+decode_func['9'] = decode_string
+
+def bdecode(x):
+ try:
+ r, l = decode_func[x[0]](x, 0)
+ except (IndexError, KeyError, ValueError):
+ raise Exception("not a valid bencoded string")
+ if l != len(x):
+ raise Exception("invalid bencoded value (data after valid prefix)")
+ return r
+
+from types import StringType, IntType, LongType, DictType, ListType, TupleType
+
+
+class Bencached(object):
+
+ __slots__ = ['bencoded']
+
+ def __init__(self, s):
+ self.bencoded = s
+
+def encode_bencached(x,r):
+ r.append(x.bencoded)
+
+def encode_int(x, r):
+ r.extend(('i', str(x), 'e'))
+
+def encode_bool(x, r):
+ if x:
+ encode_int(1, r)
+ else:
+ encode_int(0, r)
+
+def encode_string(x, r):
+ r.extend((str(len(x)), ':', x))
+
+def encode_list(x, r):
+ r.append('l')
+ for i in x:
+ encode_func[type(i)](i, r)
+ r.append('e')
+
+def encode_dict(x,r):
+ r.append('d')
+ ilist = x.items()
+ ilist.sort()
+ for k, v in ilist:
+ r.extend((str(len(k)), ':', k))
+ encode_func[type(v)](v, r)
+ r.append('e')
+
+encode_func = {}
+encode_func[Bencached] = encode_bencached
+encode_func[IntType] = encode_int
+encode_func[LongType] = encode_int
+encode_func[StringType] = encode_string
+encode_func[ListType] = encode_list
+encode_func[TupleType] = encode_list
+encode_func[DictType] = encode_dict
+
+try:
+ from types import BooleanType
+ encode_func[BooleanType] = encode_bool
+except ImportError:
+ pass
+
+def bencode(x):
+ r = []
+ encode_func[type(x)](x, r)
+ return ''.join(r)
+++ /dev/null
-#!/usr/bin/python
-
-import os
-
-import tornado.locale
-
-class Po(object):
- def __init__(self, path, project):
- self.path = path
- self.project = project
-
- p = os.popen("msgfmt -v --statistics %s 2>&1" % self.path)
- self.line = p.readlines()[0]
-
- def __cmp__(self, other):
- return cmp(self.lang, other.lang)
-
- @property
- def code2lang(self):
- ret = {}
- for lang in tornado.locale.LOCALE_NAMES.keys():
- ret[lang[:2]] = "%(name)s (%(name_en)s)" % tornado.locale.LOCALE_NAMES[lang]
- return ret
-
- @property
- def code(self):
- return os.path.basename(self.path)[:-3]
-
- @property
- def lang(self):
- return self.code2lang.get(self.code, "Unknown (%s)" % self.code)
-
- @property
- def translated(self):
- return int(self.line.split()[0])
-
- @property
- def untranslated(self):
- l = self.line.split()
- if len(l) == 6:
- return int(l[3])
- elif len(l) == 9:
- return int(l[6])
- return 0
-
- @property
- def fuzzy(self):
- l = self.line.split()
- if len(l) == 9:
- return l[3]
- return 0
-
- @property
- def percent(self):
- if not self.project.total_strings:
- return "---.-- %"
-
- return "%3.1f%%" % (self.translated * 100 / self.project.total_strings)
-
-
-class Project(object):
- def __init__(self, id, path, **kwargs):
- self.id = id
- self.path = path
- self._name = kwargs.pop("name")
- self.desc = kwargs.pop("desc")
-
- self._translations = []
- self.pot = None
- self.find_pot()
-
- @property
- def name(self):
- if self._name:
- return self._name
- return self.id
-
- @property
- def translations(self):
- if not self._translations:
- for path in os.listdir(self.path):
- if path.endswith(".po"):
- self._translations.append(Po(os.path.join(self.path, path), self))
- self._translations.sort()
- return self._translations
-
- def find_pot(self):
- for path in os.listdir(self.path):
- if path.endswith(".pot"):
- self.pot = Po(os.path.join(self.path, path), self)
- break
-
- @property
- def total_strings(self):
- if not self.pot:
- return 0
- return self.pot.untranslated
-
-projects = [
- Project("pomona", "/srv/checkout/ipfire-3.x/src/pomona/po",
- name="Pomona", desc="The pomona installer for ipfire."),
-]