func generateSSHKey(privateKeyfile, publicKeyfile string) error { private, public, err := ssh.GenerateKey(2048) if err != nil { return err } // If private keyfile already exists, we must have only made it halfway // through last time, so delete it. exists, err := util.FileExists(privateKeyfile) if err != nil { glog.Errorf("Error detecting if private key exists: %v", err) } else if exists { glog.Infof("Private key exists, but public key does not") if err := os.Remove(privateKeyfile); err != nil { glog.Errorf("Failed to remove stale private key: %v", err) } } if err := ioutil.WriteFile(privateKeyfile, ssh.EncodePrivateKey(private), 0600); err != nil { return err } publicKeyBytes, err := ssh.EncodePublicKey(public) if err != nil { return err } if err := ioutil.WriteFile(publicKeyfile+".tmp", publicKeyBytes, 0600); err != nil { return err } return os.Rename(publicKeyfile+".tmp", publicKeyfile) }
// checks if the required cgroups subsystems are mounted. // As of now, only 'cpu' and 'memory' are required. // cpu quota is a soft requirement. func validateSystemRequirements(mountUtil mount.Interface) (features, error) { const ( cgroupMountType = "cgroup" localErr = "system validation failed" ) var ( cpuMountPoint string f features ) mountPoints, err := mountUtil.List() if err != nil { return f, fmt.Errorf("%s - %v", localErr, err) } expectedCgroups := sets.NewString("cpu", "cpuacct", "cpuset", "memory") for _, mountPoint := range mountPoints { if mountPoint.Type == cgroupMountType { for _, opt := range mountPoint.Opts { if expectedCgroups.Has(opt) { expectedCgroups.Delete(opt) } if opt == "cpu" { cpuMountPoint = mountPoint.Path } } } } if expectedCgroups.Len() > 0 { return f, fmt.Errorf("%s - Following Cgroup subsystem not mounted: %v", localErr, expectedCgroups.List()) } // Check if cpu quota is available. // CPU cgroup is required and so it expected to be mounted at this point. periodExists, err := util.FileExists(path.Join(cpuMountPoint, "cpu.cfs_period_us")) if err != nil { glog.Errorf("failed to detect if CPU cgroup cpu.cfs_period_us is available - %v", err) } quotaExists, err := util.FileExists(path.Join(cpuMountPoint, "cpu.cfs_quota_us")) if err != nil { glog.Errorf("failed to detect if CPU cgroup cpu.cfs_quota_us is available - %v", err) } if quotaExists && periodExists { f.cpuHardcapping = true } return f, nil }
// Run establishes tunnel loops and returns func (c *SSHTunneler) Run(getAddresses AddressFunc) { if c.stopChan != nil { return } c.stopChan = make(chan struct{}) // Save the address getter if getAddresses != nil { c.getAddresses = getAddresses } // Usernames are capped @ 32 if len(c.SSHUser) > 32 { glog.Warning("SSH User is too long, truncating to 32 chars") c.SSHUser = c.SSHUser[0:32] } glog.Infof("Setting up proxy: %s %s", c.SSHUser, c.SSHKeyfile) // public keyfile is written last, so check for that. publicKeyFile := c.SSHKeyfile + ".pub" exists, err := util.FileExists(publicKeyFile) if err != nil { glog.Errorf("Error detecting if key exists: %v", err) } else if !exists { glog.Infof("Key doesn't exist, attempting to create") if err := generateSSHKey(c.SSHKeyfile, publicKeyFile); err != nil { glog.Errorf("Failed to create key pair: %v", err) } } c.tunnels = ssh.NewSSHTunnelList(c.SSHUser, c.SSHKeyfile, c.HealthCheckURL, c.stopChan) // Sync loop to ensure that the SSH key has been installed. c.lastSSHKeySync = c.clock.Now().Unix() c.installSSHKeySyncLoop(c.SSHUser, publicKeyFile) // Sync tunnelList w/ nodes. c.lastSync = c.clock.Now().Unix() c.nodesSyncLoop() }