Example #1
0
func Deque(deck *deque.Deque, data ...interface{}) string {
	deck.CheckInvariant()
	if deck.Count() != len(data) {
		return fmt.Sprintf("Count() is %v but should be %v", deck.Count(), len(data))
	}
	if deck.IsEmpty() != (len(data) == 0) {
		return fmt.Sprintf("IsEmpty() should be %v", (len(data) == 0))
	}
	if deck.IsFull() != (len(data) == deck.Capacity()) {
		return fmt.Sprintf("IsFull() should be %v", (len(data) == deck.Capacity()))
	}
	for i := range data {
		if deck.At(i) != data[i] {
			return fmt.Sprintf("At(%v) is %v but should be %v", i, deck.At(i), data[i])
		}
		if deck.Peek(i) != data[len(data)-1-i] {
			return fmt.Sprintf("Peek(%v) is %v but should be %v", i, deck.Peek(i), data[len(data)-1-i])
		}

		p := deck.Put(i, "x")
		if p != data[i] {
			return fmt.Sprintf("Put(%v,x) is %v but should be %v", i, p, data[i])
		}
		if deck.Put(i, p).(string) != "x" {
			return fmt.Sprintf("Put is broken")
		}
		p = deck.Poke(i, "x")
		if p != data[len(data)-1-i] {
			return fmt.Sprintf("Poke(%v,x) is %v but should be %v", i, p, data[len(data)-1-i])
		}
		if deck.Poke(i, p).(string) != "x" {
			return fmt.Sprintf("Poke is broken")
		}

		if deck.At(i) != data[i] {
			return fmt.Sprintf("After Put/Poke At(%v) is %v but should be %v", i, deck.At(i), data[i])
		}
		if deck.Peek(i) != data[len(data)-1-i] {
			return fmt.Sprintf("After Put/Poke Peek(%v) is %v but should be %v", i, deck.Peek(i), data[len(data)-1-i])
		}
	}
	var zero interface{}
	if deck.Peek(-1) != zero {
		return fmt.Sprintf("Peek(-1) returns %v", deck.Peek(-1))
	}
	if deck.Peek(-1) != nil {
		return fmt.Sprintf("Peek(-1) returns %v", deck.Peek(-1))
	}
	if deck.Poke(-1, "foo") != zero {
		return fmt.Sprintf("Poke(-1,foo) returns not nil")
	}
	if deck.Poke(-1, "foo") != nil {
		return fmt.Sprintf("Poke(-1,foo) returns not nil")
	}

	if deck.At(-1) != zero {
		return fmt.Sprintf("At(-1) returns %v", deck.At(-1))
	}
	if deck.At(-1) != nil {
		return fmt.Sprintf("At(-1) returns %v", deck.At(-1))
	}
	if deck.Put(-1, "foo") != zero {
		return fmt.Sprintf("Put(-1,foo) returns not nil")
	}
	if deck.Put(-1, "foo") != nil {
		return fmt.Sprintf("Put(-1,foo) returns not nil")
	}

	if deck.Peek(len(data)) != zero {
		return fmt.Sprintf("Peek(len(data)) returns %v", deck.Peek(len(data)))
	}
	if deck.Peek(len(data)) != nil {
		return fmt.Sprintf("Peek(len(data)) returns %v", deck.Peek(len(data)))
	}
	if deck.Poke(len(data), "foo") != zero {
		return fmt.Sprintf("Poke(len(data),foo) returns not nil")
	}
	if deck.Poke(len(data), "foo") != nil {
		return fmt.Sprintf("Poke(len(data),foo) returns not nil")
	}

	if deck.At(len(data)) != zero {
		return fmt.Sprintf("At(len(data)) returns %v", deck.At(len(data)))
	}
	if deck.At(len(data)) != nil {
		return fmt.Sprintf("At(len(data)) returns %v", deck.At(len(data)))
	}
	if deck.Put(len(data), "foo") != zero {
		return fmt.Sprintf("Put(len(data),foo) returns not nil")
	}
	if deck.Put(len(data), "foo") != nil {
		return fmt.Sprintf("Put(len(data),foo) returns not nil")
	}

	if deck.String() != "Deque"+fmt.Sprintf("%v", data) {
		return fmt.Sprintf("String() returns \"%v\" instead of \"%v\"", deck.String(), "Deque"+fmt.Sprintf("%v", data))
	}

	return ""
}
Example #2
0
// Parses the relevant configuration files and sets
// the config variables accordingly.
func ReadConfig() {
	conf := map[string]map[string]string{"": map[string]string{}}

	var tftp_mappings deque.Deque

	// [general]/pxelinux-cfg-hook is deprecated and only supported for
	// backwards compatibility. It will be converted to patterns later.
	// That's why this is a local variable and not a global one.
	pxeLinuxCfgHookPath := "/usr/lib/go-susi/generate_pxelinux_cfg"

	for _, configfile := range []string{ClientConfigPath, ServerConfigPath} {
		if configfile == "" {
			continue
		}
		file, err := os.Open(configfile)
		if err != nil {
			if os.IsNotExist(err) {
				/* File does not exist is not an error that needs to be reported */
			} else {
				util.Log(0, "ERROR! ReadConfig: %v", err)
			}
			continue
		}
		defer file.Close()
		input := bufio.NewReader(file)

		current_section := ""
		for {
			var line string
			line, err = input.ReadString('\n')
			if err != nil {
				break
			}

			if comment := strings.Index(line, "#"); comment >= 0 {
				line = line[0:comment]
			}

			line = strings.TrimSpace(line)
			if len(line) > 2 && line[0] == '[' && line[len(line)-1] == ']' {
				current_section = line
				if _, ok := conf[current_section]; !ok {
					conf[current_section] = map[string]string{}
				}
			}

			i := strings.Index(line, "=")
			if i >= 0 {
				key := strings.TrimSpace(line[0:i])
				value := strings.TrimSpace(line[i+1:])
				if key != "" {
					if current_section == "[tftp]" && key[0] == '/' && len(key) >= 2 {
						tftp_mappings.Push(key[1:])
						tftp_mappings.Push(value)
					} else {
						conf[current_section][key] = value
					}
				}
			}
		}

		if err != io.EOF {
			util.Log(0, "ERROR! ReadConfig: %v", err)
			// Do not return. Try working with whatever we got out of the file.
		}
	}

	for sectionname, section := range conf {
		if sectkey, ok := section["key"]; ok {
			ModuleKeys = append(ModuleKeys, sectkey)
			ModuleKey[sectionname] = sectkey
		}
	}

	TLSRequired = len(ModuleKey) == 0

	if general, ok := conf["[general]"]; ok {
		if logfile, ok := general["log-file"]; ok {
			LogFilePath = logfile
		}
		if failogdir, ok := general["fai-log-dir"]; ok {
			FAILogPath = failogdir
		}
		if kernel_list_hook, ok := general["kernel-list-hook"]; ok {
			KernelListHookPath = kernel_list_hook
		}
		if package_list_hook, ok := general["package-list-hook"]; ok {
			PackageListHookPath = package_list_hook
		}
		if user_msg_hook, ok := general["user-msg-hook"]; ok {
			UserMessageHookPath = user_msg_hook
		}
		if pxelinux_cfg_hook, ok := general["pxelinux-cfg-hook"]; ok {
			pxeLinuxCfgHookPath = pxelinux_cfg_hook
		}
		if new_config_hook, ok := general["new-config-hook"]; ok {
			NewConfigHookPath = new_config_hook
		}
		if trigger_action_hook, ok := general["trigger-action-hook"]; ok {
			TriggerActionHookPath = trigger_action_hook
		}
		if registered_hook, ok := general["registered-hook"]; ok {
			RegisteredHookPath = registered_hook
		}
		if activated_hook, ok := general["activated-hook"]; ok {
			ActivatedHookPath = activated_hook
		}
		if detect_hardware_hook, ok := general["detect-hardware-hook"]; ok {
			DetectHardwareHookPath = detect_hardware_hook
		}
		if fai_progress, ok := general["fai-progress-hook"]; ok {
			FAIProgressHookPath = fai_progress
		}
		if fai_savelog, ok := general["fai-savelog-hook"]; ok {
			FAISavelogHookPath = fai_savelog
		}
	}

	if server, ok := conf["[server]"]; ok {

		if dnslookup, ok := server["dns-lookup"]; ok {
			dnslookup = strings.TrimSpace(dnslookup)
			if dnslookup != "false" && dnslookup != "true" {
				util.Log(0, "ERROR! ReadConfig: [server]/dns-lookup must be \"true\" or \"false\", not \"%v\"", dnslookup)
			}
			DNSLookup = (dnslookup == "true")
		}

		if port, ok := server["port"]; ok {
			port = strings.TrimSpace(port)
			i := strings.Index(ServerSourceAddress, ":")
			ServerSourceAddress = ServerSourceAddress[:i+1] + port
			i = strings.Index(ServerListenAddress, ":")
			ServerListenAddress = ServerListenAddress[:i+1] + port
		}

		if ip, ok := server["ip"]; ok {
			PreferredServer = ip
		}
		if uri, ok := server["ldap-uri"]; ok {
			LDAPURI = uri
		}
		if base, ok := server["ldap-base"]; ok {
			LDAPBase = base
		}
		if newsysbase, ok := server["new-systems-base"]; ok {
			IncomingOU = newsysbase
		}
		if IncomingOU[len(IncomingOU)-1] == ',' {
			IncomingOU += LDAPBase
		}
		if admin, ok := server["ldap-admin-dn"]; ok {
			LDAPAdmin = admin
		}
		if pw, ok := server["ldap-admin-password"]; ok {
			err := ioutil.WriteFile(LDAPAdminPasswordFile, []byte(pw), 0600)
			if err != nil {
				util.Log(0, "ERROR! Could not write admin password to file: %v", err)
			}
		}
		if user, ok := server["ldap-user-dn"]; ok {
			LDAPUser = user
		}
		if pw, ok := server["ldap-user-password"]; ok {
			err := ioutil.WriteFile(LDAPUserPasswordFile, []byte(pw), 0600)
			if err != nil {
				util.Log(0, "ERROR! Could not write user password to file: %v", err)
			}
		}
	}

	if client, ok := conf["[client]"]; ok {
		if port, ok := client["port"]; ok {
			ClientPorts = strings.Fields(strings.Replace(port, ",", " ", -1))
		}
	}

	if faimon, ok := conf["[faimon]"]; ok {
		if port, ok := faimon["port"]; ok {
			FAIMonPort = port
		}
	}

	if tftp, ok := conf["[tftp]"]; ok {
		if port, ok := tftp["port"]; ok {
			TFTPPort = port
		}
	}

	if tlsconf, ok := conf["[tls]"]; ok {
		if cacert, ok := tlsconf["ca-certificate"]; ok {
			CACertPath = []string{cacert}
		}
		if cert, ok := tlsconf["certificate"]; ok {
			CertPath = cert
		}
		if certkey, ok := tlsconf["keyfile"]; ok {
			CertKeyPath = certkey
		}
	}

	// Backwards compatibility: Convert [general]/pxelinux-cfg-hook to patterns
	// as described in manual.
	if pxeLinuxCfgHookPath != "" {
		tftp_mappings.Insert("|" + pxeLinuxCfgHookPath)
		tftp_mappings.Insert("^pxelinux.cfg/01-(?P<macaddress>[0-9a-f]{2}(-[0-9a-f]{2}){5})$")
		tftp_mappings.Insert("")
		tftp_mappings.Insert("/^pxelinux.cfg/[0-9a-f]{8}(-[0-9a-f]{4}){3}-[0-9a-f]{12}$")
	}

	for !tftp_mappings.IsEmpty() {
		file := tftp_mappings.Pop().(string)
		pattern := tftp_mappings.Pop().(string)
		if pattern[0] != '^' {
			pattern = "^" + regexp.QuoteMeta(pattern) + "$"
			file = strings.Replace(file, "$", "$$", -1)
		}
		re, err := regexp.Compile(pattern)
		if err != nil {
			util.Log(0, "ERROR! ReadConfig: In section [tftp]: Error compiling regex \"%v\": %v", pattern, err)
		} else {
			TFTPRegexes = append(TFTPRegexes, re)
			TFTPReplies = append(TFTPReplies, file)
		}
	}

	// The [ServerPackages] section must be evaluated AFTER the [server]
	// section, because the manual says that [ServerPackages]/dns-lookup takes
	// precedence over [server]/dns-lookup.
	if serverpackages, ok := conf["[ServerPackages]"]; ok {
		if addresses, ok := serverpackages["address"]; ok && addresses != "" {
			PeerServers = append(PeerServers, strings.Fields(strings.Replace(addresses, ",", " ", -1))...)
		}
		if dnslookup, ok := serverpackages["dns-lookup"]; ok {
			dnslookup = strings.TrimSpace(dnslookup)
			if dnslookup != "false" && dnslookup != "true" {
				util.Log(0, "ERROR! ReadConfig: [ServerPackages]/dns-lookup must be \"true\" or \"false\", not \"%v\"", dnslookup)
			}
			DNSLookup = (dnslookup == "true")
		}
		if lookupdomains, ok := serverpackages["domains"]; ok {
			for _, dom := range strings.Fields(strings.Replace(lookupdomains, ",", " ", -1)) {
				if dom[0] != '.' {
					dom = "." + dom
				}
				LookupDomains = append(LookupDomains, dom)
			}
		}
	}

	if LDAPAdmin == "" {
		RunServer = false
	}

	ClientPorts = append(ClientPorts, ServerListenAddress[strings.Index(ServerListenAddress, ":")+1:])

	if PreferredServer != "" && strings.Index(PreferredServer, ":") < 0 {
		PreferredServer += ServerListenAddress[strings.Index(ServerListenAddress, ":"):]
	}

	serversInConfigFile := make([]string, len(PeerServers))
	copy(serversInConfigFile, PeerServers)
	if PreferredServer != "" {
		serversInConfigFile = append(serversInConfigFile, PreferredServer)
	}

	for _, srv := range serversInConfigFile {
		prefhost, _, err := net.SplitHostPort(srv)
		if err == nil {
			prefip := net.ParseIP(prefhost)
			if prefip != nil {
				ServerIPsFromConfigFile = append(ServerIPsFromConfigFile, prefip)
			} else {
				ServerNamesFromConfigFile = append(ServerNamesFromConfigFile, prefhost)
			}
		}
	}

	file, err := os.Open(ServersOUConfigPath)
	if err != nil {
		if os.IsNotExist(err) {
			/* File does not exist is not an error that needs to be reported */
		} else {
			util.Log(0, "ERROR! ReadConfig: %v", err)
		}
	} else {
		defer file.Close()
		input := bufio.NewReader(file)
		for {
			var line string
			line, err = input.ReadString('\n')
			if err != nil {
				break
			}
			line = strings.TrimSpace(line)
			if line != "" {
				LDAPServerOUs = append(LDAPServerOUs, line)
			}
		}
	}
}