示例#1
0
// Remove the app.
func (a *App) Remove(removeBackups bool) error {
	// Lock the task mutex.
	// The app should not be started during a remove process.
	a.taskMutex.Lock()
	defer a.taskMutex.Unlock()

	// Abort if any app task is running.
	if a.IsTaskRunning() {
		return fmt.Errorf("the app is running!")
	}

	if !removeBackups {
		// Create a backup first.
		// Call the private method, because we locked the taskMutex already.
		err := a.backup()
		if err != nil {
			return err
		}
	}

	// Remove the app subvolume if it exists.
	e, err := utils.Exists(a.path)
	if err != nil {
		return err
	} else if e {
		if err = btrfs.DeleteSubvolume(a.path); err != nil {
			return err
		}
	}

	func() {
		// Lock the apps mutex.
		appsMutex.Lock()
		defer appsMutex.Unlock()

		// Remove the app from the apps map.
		delete(apps, a.name)
	}()

	// Remove all backups if requested.
	if removeBackups {
		if err = a.RemoveAllBackups(); err != nil {
			return err
		}
	}

	return nil
}
示例#2
0
// RemoveBackup removes the given backup.
func (a *App) RemoveBackup(timestamp string) error {
	// Create the backup directory path.
	path := a.BackupDirectoryPath() + "/" + timestamp

	// Check if the backup exists.
	if !btrfs.IsSubvolume(path) {
		return fmt.Errorf("no backup '%s' found!", timestamp)
	}

	log.Infof("Removing backup '%s' of app '%s'.", timestamp, a.name)

	// Remove the backup subvolume.
	err := btrfs.DeleteSubvolume(path)
	if err != nil {
		return fmt.Errorf("failed to delete backup subvolume '%s': %v", timestamp, err)
	}

	return nil
}
示例#3
0
// Add and register a new turtle App.
// A turtle App name should not not contain any whitespaces.
func Add(name, sourceURL, branch string) (err error) {
	var a *App

	// Cleanup on any error.
	defer func() {
		if err == nil || a == nil {
			return
		}

		// Remove the app subvolume if it exists.
		e, errC := utils.Exists(a.path)
		if errC != nil {
			log.Errorf("failed to cleanup failed add app action: %v", errC)
		} else if e {
			if errC = btrfs.DeleteSubvolume(a.path); errC != nil {
				log.Errorf("failed to cleanup failed add app action: %v", errC)
			}
		}
	}()

	// Lock the mutex.
	appsMutex.Lock()
	defer appsMutex.Unlock()

	// Check if an app with the same name already exists.
	_, ok := apps[name]
	if ok {
		return fmt.Errorf("an App with the name '%s' already exists!", name)
	}

	// Create a new app value.
	a, err = newApp(name)
	if err != nil {
		return fmt.Errorf("failed to create add: %v", err)
	}

	// Set the app's settings.
	a.settings.SourceURL = sourceURL
	a.settings.Branch = branch

	// Create the app's subvolume.
	if err = btrfs.CreateSubvolume(a.path); err != nil {
		return fmt.Errorf("failed to prepare app's environment: %v", err)
	}

	// Save the app's settings to the app settings file.
	if err = a.saveSettings(); err != nil {
		return fmt.Errorf("failed to prepare app's environment: %v", err)
	}

	// Create the source directory.
	err = utils.MkDirIfNotExists(a.SourceDirectoryPath())
	if err != nil {
		return fmt.Errorf("failed to prepare app's environment: %v", err)
	}

	// Clone the source in a new task.
	if err = a.cloneSource(); err != nil {
		return err
	}

	// Finally add the app to the map.
	apps[name] = a

	return nil
}